@tamagui/static 2.0.0-rc.3 → 2.0.0-rc.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/checkDeps.cjs +164 -31
- package/dist/exports.cjs +3 -0
- package/dist/extractor/bundle.cjs +72 -35
- package/dist/extractor/bundleConfig.cjs +219 -35
- package/dist/extractor/createExtractor.cjs +170 -28
- package/dist/extractor/detectModuleFormat.cjs +49 -0
- package/dist/extractor/esbuildTsconfigPaths.cjs +3 -1
- package/dist/extractor/extractToClassNames.cjs +7 -5
- package/dist/extractor/extractToNative.cjs +7 -8
- package/dist/extractor/loadTamagui.cjs +1 -1
- package/dist/getPragmaOptions.cjs +7 -3
- package/dist/registerRequire.cjs +23 -14
- package/package.json +26 -22
- package/src/checkDeps.ts +305 -68
- package/src/exports.ts +1 -0
- package/src/extractor/bundle.ts +140 -37
- package/src/extractor/bundleConfig.ts +435 -61
- package/src/extractor/createExtractor.ts +261 -41
- package/src/extractor/detectModuleFormat.ts +42 -0
- package/src/extractor/esbuildTsconfigPaths.ts +6 -1
- package/src/extractor/extractToClassNames.ts +15 -9
- package/src/extractor/extractToNative.ts +32 -25
- package/src/extractor/loadTamagui.ts +2 -2
- package/src/getPragmaOptions.ts +6 -1
- package/src/registerRequire.ts +40 -8
- package/types/checkDeps.d.ts.map +1 -1
- package/types/exports.d.ts +1 -0
- package/types/exports.d.ts.map +1 -1
- package/types/extractor/bundle.d.ts +83 -1
- package/types/extractor/bundle.d.ts.map +1 -1
- package/types/extractor/bundleConfig.d.ts +15 -2
- package/types/extractor/bundleConfig.d.ts.map +1 -1
- package/types/extractor/createExtractor.d.ts.map +1 -1
- package/types/extractor/detectModuleFormat.d.ts +5 -0
- package/types/extractor/detectModuleFormat.d.ts.map +1 -0
- package/types/extractor/esbuildTsconfigPaths.d.ts +8 -0
- package/types/extractor/esbuildTsconfigPaths.d.ts.map +1 -1
- package/types/extractor/extractToClassNames.d.ts.map +1 -1
- package/types/extractor/extractToNative.d.ts.map +1 -1
- package/types/getPragmaOptions.d.ts.map +1 -1
- package/types/registerRequire.d.ts.map +1 -1
- package/dist/check-dep-versions.js +0 -389
- package/dist/check-dep-versions.js.map +0 -6
- package/dist/checkDeps.js +0 -60
- package/dist/checkDeps.js.map +0 -6
- package/dist/constants.js +0 -34
- package/dist/constants.js.map +0 -6
- package/dist/exports.js +0 -34
- package/dist/exports.js.map +0 -6
- package/dist/extractor/accessSafe.js +0 -47
- package/dist/extractor/accessSafe.js.map +0 -6
- package/dist/extractor/babelParse.js +0 -59
- package/dist/extractor/babelParse.js.map +0 -6
- package/dist/extractor/buildClassName.js +0 -72
- package/dist/extractor/buildClassName.js.map +0 -6
- package/dist/extractor/bundle.js +0 -135
- package/dist/extractor/bundle.js.map +0 -6
- package/dist/extractor/bundleConfig.js +0 -352
- package/dist/extractor/bundleConfig.js.map +0 -6
- package/dist/extractor/concatClassName.js +0 -69
- package/dist/extractor/concatClassName.js.map +0 -6
- package/dist/extractor/createEvaluator.js +0 -66
- package/dist/extractor/createEvaluator.js.map +0 -6
- package/dist/extractor/createExtractor.js +0 -1215
- package/dist/extractor/createExtractor.js.map +0 -6
- package/dist/extractor/createLogger.js +0 -32
- package/dist/extractor/createLogger.js.map +0 -6
- package/dist/extractor/ensureImportingConcat.js +0 -50
- package/dist/extractor/ensureImportingConcat.js.map +0 -6
- package/dist/extractor/errors.js +0 -22
- package/dist/extractor/errors.js.map +0 -6
- package/dist/extractor/esbuildAliasPlugin.js +0 -36
- package/dist/extractor/esbuildAliasPlugin.js.map +0 -6
- package/dist/extractor/esbuildTsconfigPaths.js +0 -79
- package/dist/extractor/esbuildTsconfigPaths.js.map +0 -6
- package/dist/extractor/evaluateAstNode.js +0 -99
- package/dist/extractor/evaluateAstNode.js.map +0 -6
- package/dist/extractor/extractHelpers.js +0 -108
- package/dist/extractor/extractHelpers.js.map +0 -6
- package/dist/extractor/extractMediaStyle.js +0 -123
- package/dist/extractor/extractMediaStyle.js.map +0 -6
- package/dist/extractor/extractToClassNames.js +0 -351
- package/dist/extractor/extractToClassNames.js.map +0 -6
- package/dist/extractor/extractToNative.js +0 -286
- package/dist/extractor/extractToNative.js.map +0 -6
- package/dist/extractor/findTopmostFunction.js +0 -32
- package/dist/extractor/findTopmostFunction.js.map +0 -6
- package/dist/extractor/generatedUid.js +0 -42
- package/dist/extractor/generatedUid.js.map +0 -6
- package/dist/extractor/getPrefixLogs.js +0 -24
- package/dist/extractor/getPrefixLogs.js.map +0 -6
- package/dist/extractor/getPropValueFromAttributes.js +0 -65
- package/dist/extractor/getPropValueFromAttributes.js.map +0 -6
- package/dist/extractor/getSourceModule.js +0 -62
- package/dist/extractor/getSourceModule.js.map +0 -6
- package/dist/extractor/getStaticBindingsForScope.js +0 -145
- package/dist/extractor/getStaticBindingsForScope.js.map +0 -6
- package/dist/extractor/getTamaguiConfigPathFromOptionsConfig.js +0 -32
- package/dist/extractor/getTamaguiConfigPathFromOptionsConfig.js.map +0 -6
- package/dist/extractor/hoistClassNames.js +0 -63
- package/dist/extractor/hoistClassNames.js.map +0 -6
- package/dist/extractor/literalToAst.js +0 -90
- package/dist/extractor/literalToAst.js.map +0 -6
- package/dist/extractor/loadFile.js +0 -14
- package/dist/extractor/loadFile.js.map +0 -6
- package/dist/extractor/loadTamagui.js +0 -306
- package/dist/extractor/loadTamagui.js.map +0 -6
- package/dist/extractor/logLines.js +0 -30
- package/dist/extractor/logLines.js.map +0 -6
- package/dist/extractor/normalizeTernaries.js +0 -61
- package/dist/extractor/normalizeTernaries.js.map +0 -6
- package/dist/extractor/propsToFontFamilyCache.js +0 -33
- package/dist/extractor/propsToFontFamilyCache.js.map +0 -6
- package/dist/extractor/regenerateConfig.js +0 -123
- package/dist/extractor/regenerateConfig.js.map +0 -6
- package/dist/extractor/removeUnusedHooks.js +0 -72
- package/dist/extractor/removeUnusedHooks.js.map +0 -6
- package/dist/extractor/timer.js +0 -38
- package/dist/extractor/timer.js.map +0 -6
- package/dist/extractor/validHTMLAttributes.js +0 -72
- package/dist/extractor/validHTMLAttributes.js.map +0 -6
- package/dist/extractor/watchTamaguiConfig.js +0 -57
- package/dist/extractor/watchTamaguiConfig.js.map +0 -6
- package/dist/getPragmaOptions.js +0 -46
- package/dist/getPragmaOptions.js.map +0 -6
- package/dist/helpers/memoize.js +0 -33
- package/dist/helpers/memoize.js.map +0 -6
- package/dist/helpers/requireTamaguiCore.js +0 -30
- package/dist/helpers/requireTamaguiCore.js.map +0 -6
- package/dist/index.js +0 -30
- package/dist/index.js.map +0 -6
- package/dist/registerRequire.js +0 -100
- package/dist/registerRequire.js.map +0 -6
- package/dist/server.js +0 -58
- package/dist/server.js.map +0 -6
- package/dist/setup.js +0 -1
- package/dist/setup.js.map +0 -6
- package/dist/types.js +0 -14
- package/dist/types.js.map +0 -6
- package/dist/worker.js +0 -72
- package/dist/worker.js.map +0 -6
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import generate from '@babel/generator'
|
|
2
2
|
import traverse from '@babel/traverse'
|
|
3
3
|
import * as t from '@babel/types'
|
|
4
|
-
import {
|
|
4
|
+
import { createHash } from 'node:crypto'
|
|
5
|
+
import { existsSync, readFileSync, unlinkSync } from 'node:fs'
|
|
5
6
|
import { basename, dirname, extname, join, relative, sep } from 'node:path'
|
|
7
|
+
import { pathToFileURL } from 'node:url'
|
|
6
8
|
// @ts-ignore why
|
|
7
9
|
import { Color, colorLog } from '@tamagui/cli-color'
|
|
8
|
-
import {
|
|
9
|
-
createTamagui,
|
|
10
|
-
type StaticConfig,
|
|
11
|
-
type TamaguiInternalConfig,
|
|
12
|
-
} from '@tamagui/web'
|
|
10
|
+
import { type StaticConfig, type TamaguiInternalConfig } from '@tamagui/web'
|
|
13
11
|
import esbuild from 'esbuild'
|
|
14
12
|
import * as FS from 'fs-extra'
|
|
15
13
|
import { readFile } from 'node:fs/promises'
|
|
@@ -19,6 +17,72 @@ import { babelParse } from './babelParse'
|
|
|
19
17
|
import { esbuildLoaderConfig, esbundleTamaguiConfig } from './bundle'
|
|
20
18
|
import { getTamaguiConfigPathFromOptionsConfig } from './getTamaguiConfigPathFromOptionsConfig'
|
|
21
19
|
import { requireTamaguiCore } from '../helpers/requireTamaguiCore'
|
|
20
|
+
import { detectModuleFormat } from './detectModuleFormat'
|
|
21
|
+
|
|
22
|
+
// track temp files for cleanup on exit
|
|
23
|
+
const activeTempFiles = new Set<string>()
|
|
24
|
+
|
|
25
|
+
function getDynamicEvalOutfile(name: string, format: 'esm' | 'cjs', contents: string) {
|
|
26
|
+
const ext = format === 'esm' ? 'mjs' : 'cjs'
|
|
27
|
+
const hash = createHash('sha1')
|
|
28
|
+
.update(name)
|
|
29
|
+
.update('\0')
|
|
30
|
+
.update(format)
|
|
31
|
+
.update('\0')
|
|
32
|
+
.update(contents)
|
|
33
|
+
.digest('hex')
|
|
34
|
+
.slice(0, 10)
|
|
35
|
+
return join(process.cwd(), '.tamagui', `dynamic-eval-${hash}-${basename(name)}.${ext}`)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getEsbuildStdinLoader(filePath: string): esbuild.Loader {
|
|
39
|
+
if (filePath.endsWith('.tsx')) return 'tsx'
|
|
40
|
+
if (filePath.endsWith('.ts')) return 'ts'
|
|
41
|
+
if (filePath.endsWith('.jsx')) return 'jsx'
|
|
42
|
+
return 'js'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function resolvePackageEntry(packageName: string, format: 'esm' | 'cjs') {
|
|
46
|
+
if (format === 'cjs') {
|
|
47
|
+
return require.resolve(packageName)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const packageJsonPath = require.resolve(`${packageName}/package.json`)
|
|
51
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
|
|
52
|
+
const packageRoot = dirname(packageJsonPath)
|
|
53
|
+
const exportEntry = packageJson.exports?.['.']
|
|
54
|
+
|
|
55
|
+
const esmEntry =
|
|
56
|
+
exportEntry?.import ||
|
|
57
|
+
exportEntry?.module ||
|
|
58
|
+
exportEntry?.browser ||
|
|
59
|
+
packageJson.module
|
|
60
|
+
|
|
61
|
+
if (typeof esmEntry === 'string') {
|
|
62
|
+
return join(packageRoot, esmEntry)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return require.resolve(packageName)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function cleanupTempFiles() {
|
|
69
|
+
for (const f of activeTempFiles) {
|
|
70
|
+
try {
|
|
71
|
+
unlinkSync(f)
|
|
72
|
+
} catch {}
|
|
73
|
+
}
|
|
74
|
+
activeTempFiles.clear()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
process.on('exit', cleanupTempFiles)
|
|
78
|
+
process.on('SIGINT', () => {
|
|
79
|
+
cleanupTempFiles()
|
|
80
|
+
process.exit()
|
|
81
|
+
})
|
|
82
|
+
process.on('SIGTERM', () => {
|
|
83
|
+
cleanupTempFiles()
|
|
84
|
+
process.exit()
|
|
85
|
+
})
|
|
22
86
|
|
|
23
87
|
type NameToPaths = {
|
|
24
88
|
[key: string]: Set<string>
|
|
@@ -55,12 +119,95 @@ const esbuildExtraOptions = {
|
|
|
55
119
|
},
|
|
56
120
|
}
|
|
57
121
|
|
|
58
|
-
|
|
59
|
-
|
|
122
|
+
// plugin to handle ESM-only features when bundling to CJS
|
|
123
|
+
const handleEsmFeaturesPlugin: esbuild.Plugin = {
|
|
124
|
+
name: 'handle-esm-features',
|
|
125
|
+
setup(build) {
|
|
126
|
+
// only apply transforms for CJS output - ESM supports these natively
|
|
127
|
+
const isCjs = build.initialOptions.format === 'cjs' || !build.initialOptions.format
|
|
128
|
+
|
|
129
|
+
build.onLoad({ filter: /\.(ts|tsx|js|jsx|mjs)$/ }, (args) => {
|
|
130
|
+
// skip if ESM output - import.meta and top-level await work natively
|
|
131
|
+
if (!isCjs) {
|
|
132
|
+
return null
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// skip most node_modules
|
|
136
|
+
if (args.path.includes('node_modules') && !args.path.includes('@tamagui')) {
|
|
137
|
+
return null
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let contents = readFileSync(args.path, 'utf8')
|
|
141
|
+
let modified = false
|
|
142
|
+
|
|
143
|
+
// transform import.meta.env -> process.env (Vite-style env vars)
|
|
144
|
+
if (contents.includes('import.meta.env')) {
|
|
145
|
+
contents = contents.replace(/import\.meta\.env/g, 'process.env')
|
|
146
|
+
modified = true
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// transform import.meta.url -> "" (not needed for static extraction)
|
|
150
|
+
if (contents.includes('import.meta.url')) {
|
|
151
|
+
contents = contents.replace(/import\.meta\.url/g, '""')
|
|
152
|
+
modified = true
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// transform import.meta.main -> false
|
|
156
|
+
if (contents.includes('import.meta.main')) {
|
|
157
|
+
contents = contents.replace(/import\.meta\.main/g, 'false')
|
|
158
|
+
modified = true
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// stub files with top-level await - they're typically runtime-only
|
|
162
|
+
if (
|
|
163
|
+
/^\s*(?:const|let|var|export)\s+[^=]*=\s*await\b/m.test(contents) ||
|
|
164
|
+
/^await\s/m.test(contents)
|
|
165
|
+
) {
|
|
166
|
+
if (process.env.DEBUG?.startsWith('tamagui')) {
|
|
167
|
+
console.info(`[tamagui] stubbing file with top-level await: ${args.path}`)
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
contents: `// stubbed - contains top-level await\nmodule.exports = {}`,
|
|
171
|
+
loader: 'js',
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (modified) {
|
|
176
|
+
return {
|
|
177
|
+
contents,
|
|
178
|
+
loader: args.path.endsWith('.tsx')
|
|
179
|
+
? 'tsx'
|
|
180
|
+
: args.path.endsWith('.ts')
|
|
181
|
+
? 'ts'
|
|
182
|
+
: args.path.endsWith('.jsx')
|
|
183
|
+
? 'jsx'
|
|
184
|
+
: 'js',
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return null
|
|
189
|
+
})
|
|
190
|
+
},
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// base options for transformSync (no plugins)
|
|
194
|
+
const esbuildTransformOptions = {
|
|
195
|
+
target: 'es2022',
|
|
60
196
|
format: 'cjs',
|
|
61
197
|
jsx: 'automatic',
|
|
62
198
|
platform: 'node',
|
|
63
199
|
...esbuildExtraOptions,
|
|
200
|
+
} satisfies esbuild.TransformOptions
|
|
201
|
+
|
|
202
|
+
// options for buildSync - NO plugins (buildSync doesn't support plugins)
|
|
203
|
+
export const esbuildOptions = {
|
|
204
|
+
...esbuildTransformOptions,
|
|
205
|
+
} satisfies esbuild.BuildOptions
|
|
206
|
+
|
|
207
|
+
// options for async build (with plugins)
|
|
208
|
+
export const esbuildOptionsWithPlugins = {
|
|
209
|
+
...esbuildTransformOptions,
|
|
210
|
+
plugins: [handleEsmFeaturesPlugin],
|
|
64
211
|
} satisfies esbuild.BuildOptions
|
|
65
212
|
|
|
66
213
|
export type BundledConfig = Exclude<Awaited<ReturnType<typeof bundleConfig>>, undefined>
|
|
@@ -122,17 +269,31 @@ export async function bundleConfig(props: TamaguiOptions) {
|
|
|
122
269
|
? getTamaguiConfigPathFromOptionsConfig(props.config)
|
|
123
270
|
: ''
|
|
124
271
|
const tmpDir = join(process.cwd(), '.tamagui')
|
|
125
|
-
|
|
272
|
+
// detect module format from config entry point
|
|
273
|
+
const configFormat = configEntry ? detectModuleFormat(configEntry) : 'cjs'
|
|
274
|
+
const configExt = configFormat === 'esm' ? '.mjs' : '.cjs'
|
|
275
|
+
const configOutPath = join(tmpDir, `tamagui.config${configExt}`)
|
|
126
276
|
const baseComponents = (props.components || []).filter((x) => x !== '@tamagui/core')
|
|
127
|
-
|
|
128
|
-
|
|
277
|
+
// detect format per component module
|
|
278
|
+
const componentFormats: Array<'esm' | 'cjs'> = baseComponents.map((mod) => {
|
|
279
|
+
try {
|
|
280
|
+
const pkgJson = require.resolve(mod + '/package.json')
|
|
281
|
+
const pkg = JSON.parse(readFileSync(pkgJson, 'utf-8'))
|
|
282
|
+
return pkg.type === 'module' ? 'esm' : 'cjs'
|
|
283
|
+
} catch {
|
|
284
|
+
return 'cjs'
|
|
285
|
+
}
|
|
286
|
+
})
|
|
287
|
+
const componentOutPaths = baseComponents.map((componentModule, i) => {
|
|
288
|
+
const ext = componentFormats[i] === 'esm' ? '.mjs' : '.cjs'
|
|
289
|
+
return join(
|
|
129
290
|
tmpDir,
|
|
130
291
|
`${componentModule
|
|
131
292
|
.split(sep)
|
|
132
293
|
.join('-')
|
|
133
|
-
.replace(/[^a-z0-9]+/gi, '')}-components.config
|
|
294
|
+
.replace(/[^a-z0-9]+/gi, '')}-components.config${ext}`
|
|
134
295
|
)
|
|
135
|
-
)
|
|
296
|
+
})
|
|
136
297
|
|
|
137
298
|
if (
|
|
138
299
|
process.env.NODE_ENV === 'development' &&
|
|
@@ -141,7 +302,29 @@ export async function bundleConfig(props: TamaguiOptions) {
|
|
|
141
302
|
console.info(`Building config entry`, configEntry)
|
|
142
303
|
}
|
|
143
304
|
|
|
144
|
-
if (
|
|
305
|
+
// check if ALL output files (config + components) already exist and are recent
|
|
306
|
+
// (built by another worker) - this prevents duplicate builds across worker threads
|
|
307
|
+
// we must check ALL files, not just the config, to avoid a race where another
|
|
308
|
+
// worker has written the config but not yet finished writing component files
|
|
309
|
+
let shouldBuild = !props.disableInitialBuild
|
|
310
|
+
if (shouldBuild && props.config) {
|
|
311
|
+
const allOutFiles = [configOutPath, ...componentOutPaths]
|
|
312
|
+
try {
|
|
313
|
+
const stats = await Promise.all(
|
|
314
|
+
allOutFiles.map((f) => FS.stat(f).catch(() => null))
|
|
315
|
+
)
|
|
316
|
+
const allExistAndRecent = stats.every(
|
|
317
|
+
(s) => s !== null && Date.now() - s.mtimeMs < 3000
|
|
318
|
+
)
|
|
319
|
+
if (allExistAndRecent) {
|
|
320
|
+
shouldBuild = false
|
|
321
|
+
}
|
|
322
|
+
} catch {
|
|
323
|
+
// something went wrong checking files, just build
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (shouldBuild) {
|
|
145
328
|
// build them to node-compat versions
|
|
146
329
|
try {
|
|
147
330
|
await FS.ensureDir(tmpDir)
|
|
@@ -158,7 +341,8 @@ export async function bundleConfig(props: TamaguiOptions) {
|
|
|
158
341
|
entryPoints: [configEntry],
|
|
159
342
|
external,
|
|
160
343
|
outfile: configOutPath,
|
|
161
|
-
target: '
|
|
344
|
+
target: 'node24',
|
|
345
|
+
format: configFormat,
|
|
162
346
|
...esbuildExtraOptions,
|
|
163
347
|
},
|
|
164
348
|
props.platform || 'web'
|
|
@@ -171,7 +355,8 @@ export async function bundleConfig(props: TamaguiOptions) {
|
|
|
171
355
|
resolvePlatformSpecificEntries: true,
|
|
172
356
|
external,
|
|
173
357
|
outfile: componentOutPaths[i],
|
|
174
|
-
target: '
|
|
358
|
+
target: 'node24',
|
|
359
|
+
format: componentFormats[i],
|
|
175
360
|
...esbuildExtraOptions,
|
|
176
361
|
},
|
|
177
362
|
props.platform || 'web'
|
|
@@ -201,25 +386,32 @@ export async function bundleConfig(props: TamaguiOptions) {
|
|
|
201
386
|
}
|
|
202
387
|
}
|
|
203
388
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
389
|
+
// clear specific output file caches so we pick up the fresh (or newly discovered) build
|
|
390
|
+
// only clear the built output files - not all require.cache entries, since that breaks
|
|
391
|
+
// external requires like @tamagui/config/v3 that are externalized in the bundled CJS
|
|
392
|
+
if (hasBundledOnce) {
|
|
393
|
+
try {
|
|
394
|
+
delete require.cache[require.resolve(configOutPath)]
|
|
395
|
+
} catch {
|
|
396
|
+
// file may not exist yet
|
|
397
|
+
}
|
|
398
|
+
for (const p of componentOutPaths) {
|
|
399
|
+
try {
|
|
400
|
+
delete require.cache[require.resolve(p)]
|
|
401
|
+
} catch {
|
|
402
|
+
// file may not exist yet
|
|
215
403
|
}
|
|
216
|
-
} else {
|
|
217
|
-
hasBundledOnce = true
|
|
218
404
|
}
|
|
405
|
+
} else {
|
|
406
|
+
hasBundledOnce = true
|
|
407
|
+
}
|
|
219
408
|
|
|
409
|
+
let out: any
|
|
410
|
+
if (configFormat === 'esm') {
|
|
411
|
+
// use file:// URL for proper ESM resolution
|
|
412
|
+
out = await import(pathToFileURL(configOutPath).href)
|
|
413
|
+
} else {
|
|
220
414
|
out = require(configOutPath)
|
|
221
|
-
} finally {
|
|
222
|
-
unregister()
|
|
223
415
|
}
|
|
224
416
|
|
|
225
417
|
// try and find .config, even if on .default
|
|
@@ -232,6 +424,13 @@ export async function bundleConfig(props: TamaguiOptions) {
|
|
|
232
424
|
throw new Error(`No config: ${config}`)
|
|
233
425
|
}
|
|
234
426
|
|
|
427
|
+
// check for ProxyWorm - indicates a module loading error
|
|
428
|
+
if (config._isProxyWorm) {
|
|
429
|
+
throw new Error(
|
|
430
|
+
`Got a proxied config - likely a module loading error. Set DEBUG=tamagui for details.`
|
|
431
|
+
)
|
|
432
|
+
}
|
|
433
|
+
|
|
235
434
|
loadedConfig = config
|
|
236
435
|
|
|
237
436
|
if (!config.parsed) {
|
|
@@ -244,7 +443,7 @@ export async function bundleConfig(props: TamaguiOptions) {
|
|
|
244
443
|
await writeTamaguiCSS(props.outputCSS, config)
|
|
245
444
|
}
|
|
246
445
|
|
|
247
|
-
let components = loadComponents({
|
|
446
|
+
let components = await loadComponents({
|
|
248
447
|
...props,
|
|
249
448
|
components: componentOutPaths,
|
|
250
449
|
})
|
|
@@ -322,14 +521,20 @@ export async function writeTamaguiCSS(outputCSS: string, config: TamaguiInternal
|
|
|
322
521
|
}
|
|
323
522
|
}
|
|
324
523
|
|
|
325
|
-
export function loadComponents(props: TamaguiOptions, forceExports = false) {
|
|
326
|
-
const coreComponents =
|
|
327
|
-
const otherComponents = loadComponentsInner(props, forceExports)
|
|
524
|
+
export async function loadComponents(props: TamaguiOptions, forceExports = false) {
|
|
525
|
+
const coreComponents = getCoreComponentsSync(props)
|
|
526
|
+
const otherComponents = await loadComponentsInner(props, forceExports)
|
|
328
527
|
return [...coreComponents, ...(otherComponents || [])]
|
|
329
528
|
}
|
|
330
529
|
|
|
331
|
-
function
|
|
332
|
-
const
|
|
530
|
+
export function loadComponentsSync(props: TamaguiOptions, forceExports = false) {
|
|
531
|
+
const coreComponents = getCoreComponentsSync(props)
|
|
532
|
+
const otherComponents = loadComponentsInnerSync(props, forceExports)
|
|
533
|
+
return [...coreComponents, ...(otherComponents || [])]
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
function getCoreComponentsSync(props: TamaguiOptions) {
|
|
537
|
+
const loaded = loadComponentsInnerSync({
|
|
333
538
|
...props,
|
|
334
539
|
components: ['@tamagui/core'],
|
|
335
540
|
})
|
|
@@ -347,13 +552,172 @@ function getCoreComponents(props: TamaguiOptions) {
|
|
|
347
552
|
]
|
|
348
553
|
}
|
|
349
554
|
|
|
350
|
-
export function loadComponentsInner(
|
|
555
|
+
export async function loadComponentsInner(
|
|
556
|
+
props: TamaguiOptions,
|
|
557
|
+
forceExports = false
|
|
558
|
+
): Promise<null | LoadedComponents[]> {
|
|
559
|
+
const componentsModules = props.components || []
|
|
560
|
+
|
|
561
|
+
const key = componentsModules.join('\0')
|
|
562
|
+
|
|
563
|
+
if (!forceExports && cacheComponents[key]) {
|
|
564
|
+
return cacheComponents[key]
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
const { unregister } = registerRequire(props.platform || 'web', {
|
|
568
|
+
proxyWormImports: forceExports,
|
|
569
|
+
})
|
|
570
|
+
|
|
571
|
+
try {
|
|
572
|
+
const results: LoadedComponents[] = []
|
|
573
|
+
|
|
574
|
+
for (const name of componentsModules) {
|
|
575
|
+
const extension = extname(name)
|
|
576
|
+
const isLocal = Boolean(extension)
|
|
577
|
+
const isDynamic = isLocal && forceExports
|
|
578
|
+
const format = isLocal ? detectModuleFormat(name) : ('cjs' as const)
|
|
579
|
+
|
|
580
|
+
const fileContents = isDynamic ? readFileSync(name, 'utf-8') : ''
|
|
581
|
+
let loadModule = name
|
|
582
|
+
let writtenContents = fileContents
|
|
583
|
+
let didBabel = false
|
|
584
|
+
|
|
585
|
+
const attemptLoad = async ({ forceExports = false } = {}) => {
|
|
586
|
+
if (isDynamic) {
|
|
587
|
+
writtenContents = forceExports
|
|
588
|
+
? transformAddExports(babelParse(esbuildit(fileContents, 'modern'), name))
|
|
589
|
+
: fileContents
|
|
590
|
+
loadModule = getDynamicEvalOutfile(name, format, writtenContents)
|
|
591
|
+
|
|
592
|
+
FS.ensureDirSync(dirname(loadModule))
|
|
593
|
+
activeTempFiles.add(loadModule)
|
|
594
|
+
|
|
595
|
+
await esbuild.build({
|
|
596
|
+
...esbuildOptionsWithPlugins,
|
|
597
|
+
format,
|
|
598
|
+
outfile: loadModule,
|
|
599
|
+
stdin: {
|
|
600
|
+
contents: writtenContents,
|
|
601
|
+
resolveDir: dirname(name),
|
|
602
|
+
sourcefile: name,
|
|
603
|
+
loader: getEsbuildStdinLoader(name),
|
|
604
|
+
},
|
|
605
|
+
alias: {
|
|
606
|
+
'react-native': resolvePackageEntry(
|
|
607
|
+
'@tamagui/react-native-web-lite',
|
|
608
|
+
format
|
|
609
|
+
),
|
|
610
|
+
'@tamagui/react-native-web-lite': resolvePackageEntry(
|
|
611
|
+
'@tamagui/react-native-web-lite',
|
|
612
|
+
format
|
|
613
|
+
),
|
|
614
|
+
'@tamagui/react-native-web-internals': resolvePackageEntry(
|
|
615
|
+
'@tamagui/react-native-web-internals',
|
|
616
|
+
format
|
|
617
|
+
),
|
|
618
|
+
},
|
|
619
|
+
bundle: true,
|
|
620
|
+
packages: 'external',
|
|
621
|
+
allowOverwrite: true,
|
|
622
|
+
sourcemap: false,
|
|
623
|
+
loader: esbuildLoaderConfig,
|
|
624
|
+
})
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (process.env.DEBUG === 'tamagui') {
|
|
628
|
+
console.info(`loadModule`, loadModule, format)
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
let moduleResult: any
|
|
632
|
+
if (format === 'esm') {
|
|
633
|
+
// use file:// URL for proper ESM resolution
|
|
634
|
+
moduleResult = await import(pathToFileURL(loadModule).href)
|
|
635
|
+
} else {
|
|
636
|
+
moduleResult = require(loadModule)
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
if (!forceExports) {
|
|
640
|
+
setRequireResult(name, moduleResult)
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
const nameToInfo = getComponentStaticConfigByName(
|
|
644
|
+
name,
|
|
645
|
+
interopDefaultExport(moduleResult)
|
|
646
|
+
)
|
|
647
|
+
|
|
648
|
+
return {
|
|
649
|
+
moduleName: name,
|
|
650
|
+
nameToInfo,
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
const dispose = () => {
|
|
655
|
+
if (isDynamic) {
|
|
656
|
+
FS.removeSync(loadModule)
|
|
657
|
+
activeTempFiles.delete(loadModule)
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
let loaded: LoadedComponents | LoadedComponents[] | undefined
|
|
662
|
+
|
|
663
|
+
try {
|
|
664
|
+
loaded = await attemptLoad({ forceExports: true })
|
|
665
|
+
didBabel = true
|
|
666
|
+
} catch (err) {
|
|
667
|
+
console.info('babel err', err, writtenContents)
|
|
668
|
+
writtenContents = fileContents
|
|
669
|
+
if (process.env.DEBUG?.startsWith('tamagui')) {
|
|
670
|
+
console.info(`Error parsing babel likely`, err)
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
try {
|
|
674
|
+
loaded = await attemptLoad({ forceExports: false })
|
|
675
|
+
} catch (err2) {
|
|
676
|
+
if (process.env.TAMAGUI_ENABLE_WARN_DYNAMIC_LOAD) {
|
|
677
|
+
console.info(
|
|
678
|
+
`\nTamagui attempted but failed to dynamically optimize components in:\n ${name}\n`
|
|
679
|
+
)
|
|
680
|
+
console.info(err2)
|
|
681
|
+
console.info(
|
|
682
|
+
`At: ${loadModule}`,
|
|
683
|
+
`\ndidBabel: ${didBabel}`,
|
|
684
|
+
`\nIn:`,
|
|
685
|
+
writtenContents,
|
|
686
|
+
`\nisDynamic: `,
|
|
687
|
+
isDynamic
|
|
688
|
+
)
|
|
689
|
+
}
|
|
690
|
+
loaded = []
|
|
691
|
+
}
|
|
692
|
+
} finally {
|
|
693
|
+
dispose()
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
if (Array.isArray(loaded)) {
|
|
697
|
+
results.push(...loaded)
|
|
698
|
+
} else if (loaded) {
|
|
699
|
+
results.push(loaded)
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
cacheComponents[key] = results
|
|
704
|
+
return results
|
|
705
|
+
} catch (err: any) {
|
|
706
|
+
console.info(`Tamagui error bundling components`, err.message, err.stack)
|
|
707
|
+
return null
|
|
708
|
+
} finally {
|
|
709
|
+
unregister()
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// sync version - uses cjs format for buildSync (no plugin support)
|
|
714
|
+
export function loadComponentsInnerSync(
|
|
351
715
|
props: TamaguiOptions,
|
|
352
716
|
forceExports = false
|
|
353
717
|
): null | LoadedComponents[] {
|
|
354
718
|
const componentsModules = props.components || []
|
|
355
719
|
|
|
356
|
-
const key = componentsModules.join('')
|
|
720
|
+
const key = componentsModules.join('\0')
|
|
357
721
|
|
|
358
722
|
if (!forceExports && cacheComponents[key]) {
|
|
359
723
|
return cacheComponents[key]
|
|
@@ -370,32 +734,46 @@ export function loadComponentsInner(
|
|
|
370
734
|
const isDynamic = isLocal && forceExports
|
|
371
735
|
|
|
372
736
|
const fileContents = isDynamic ? readFileSync(name, 'utf-8') : ''
|
|
373
|
-
|
|
374
|
-
? join(dirname(name), `.tamagui-dynamic-eval-${basename(name)}.tsx`)
|
|
375
|
-
: name
|
|
737
|
+
let loadModule = name
|
|
376
738
|
let writtenContents = fileContents
|
|
377
739
|
let didBabel = false
|
|
378
740
|
|
|
379
741
|
function attemptLoad({ forceExports = false } = {}) {
|
|
380
|
-
// need to write to tsx to enable reading it properly (:/ esbuild-register)
|
|
381
742
|
if (isDynamic) {
|
|
382
743
|
writtenContents = forceExports
|
|
383
744
|
? transformAddExports(babelParse(esbuildit(fileContents, 'modern'), name))
|
|
384
745
|
: fileContents
|
|
746
|
+
loadModule = getDynamicEvalOutfile(name, 'cjs', writtenContents)
|
|
385
747
|
|
|
386
|
-
FS.
|
|
748
|
+
FS.ensureDirSync(dirname(loadModule))
|
|
749
|
+
activeTempFiles.add(loadModule)
|
|
387
750
|
|
|
388
751
|
esbuild.buildSync({
|
|
389
752
|
...esbuildOptions,
|
|
390
|
-
entryPoints: [loadModule],
|
|
391
753
|
outfile: loadModule,
|
|
754
|
+
stdin: {
|
|
755
|
+
contents: writtenContents,
|
|
756
|
+
resolveDir: dirname(name),
|
|
757
|
+
sourcefile: name,
|
|
758
|
+
loader: getEsbuildStdinLoader(name),
|
|
759
|
+
},
|
|
392
760
|
alias: {
|
|
393
|
-
'react-native':
|
|
761
|
+
'react-native': resolvePackageEntry(
|
|
762
|
+
'@tamagui/react-native-web-lite',
|
|
763
|
+
'esm'
|
|
764
|
+
),
|
|
765
|
+
'@tamagui/react-native-web-lite': resolvePackageEntry(
|
|
766
|
+
'@tamagui/react-native-web-lite',
|
|
767
|
+
'esm'
|
|
768
|
+
),
|
|
769
|
+
'@tamagui/react-native-web-internals': resolvePackageEntry(
|
|
770
|
+
'@tamagui/react-native-web-internals',
|
|
771
|
+
'esm'
|
|
772
|
+
),
|
|
394
773
|
},
|
|
395
774
|
bundle: true,
|
|
396
775
|
packages: 'external',
|
|
397
776
|
allowOverwrite: true,
|
|
398
|
-
// logLevel: 'silent',
|
|
399
777
|
sourcemap: false,
|
|
400
778
|
loader: esbuildLoaderConfig,
|
|
401
779
|
})
|
|
@@ -423,18 +801,18 @@ export function loadComponentsInner(
|
|
|
423
801
|
}
|
|
424
802
|
|
|
425
803
|
const dispose = () => {
|
|
426
|
-
|
|
804
|
+
if (isDynamic) {
|
|
805
|
+
FS.removeSync(loadModule)
|
|
806
|
+
activeTempFiles.delete(loadModule)
|
|
807
|
+
}
|
|
427
808
|
}
|
|
428
809
|
|
|
429
810
|
try {
|
|
430
|
-
const res = attemptLoad({
|
|
431
|
-
forceExports: true,
|
|
432
|
-
})
|
|
811
|
+
const res = attemptLoad({ forceExports: true })
|
|
433
812
|
didBabel = true
|
|
434
813
|
return res
|
|
435
814
|
} catch (err) {
|
|
436
815
|
console.info('babel err', err, writtenContents)
|
|
437
|
-
// ok
|
|
438
816
|
writtenContents = fileContents
|
|
439
817
|
if (process.env.DEBUG?.startsWith('tamagui')) {
|
|
440
818
|
console.info(`Error parsing babel likely`, err)
|
|
@@ -444,16 +822,12 @@ export function loadComponentsInner(
|
|
|
444
822
|
}
|
|
445
823
|
|
|
446
824
|
try {
|
|
447
|
-
return attemptLoad({
|
|
448
|
-
forceExports: false,
|
|
449
|
-
})
|
|
825
|
+
return attemptLoad({ forceExports: false })
|
|
450
826
|
} catch (err) {
|
|
451
827
|
if (process.env.TAMAGUI_ENABLE_WARN_DYNAMIC_LOAD) {
|
|
452
|
-
console.info(
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
${name}
|
|
456
|
-
`)
|
|
828
|
+
console.info(
|
|
829
|
+
`\nTamagui attempted but failed to dynamically optimize components in:\n ${name}\n`
|
|
830
|
+
)
|
|
457
831
|
console.info(err)
|
|
458
832
|
console.info(
|
|
459
833
|
`At: ${loadModule}`,
|
|
@@ -481,7 +855,7 @@ Tamagui attempted but failed to dynamically optimize components in:
|
|
|
481
855
|
|
|
482
856
|
const esbuildit = (src: string, target?: 'modern') => {
|
|
483
857
|
return esbuild.transformSync(src, {
|
|
484
|
-
...
|
|
858
|
+
...esbuildTransformOptions,
|
|
485
859
|
...(target === 'modern' && {
|
|
486
860
|
target: 'es2022',
|
|
487
861
|
jsx: 'automatic',
|