@tamagui/static 2.7.7 → 3.0.0-beta.1097.1
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/cjs/check-dep-versions.cjs +354 -0
- package/dist/cjs/checkDeps.cjs +301 -0
- package/dist/cjs/compiler.cjs +349 -0
- package/dist/cjs/compilerHost.cjs +2287 -0
- package/dist/cjs/componentDiscovery.cjs +94 -0
- package/dist/cjs/constants.cjs +32 -0
- package/dist/cjs/domStructuralPass.cjs +121 -0
- package/dist/cjs/exports.cjs +44 -0
- package/dist/cjs/extractor/addLocalExports.cjs +63 -0
- package/dist/cjs/extractor/bundle.cjs +229 -0
- package/dist/cjs/extractor/bundleConfig.cjs +769 -0
- package/dist/cjs/extractor/concatClassName.cjs +120 -0
- package/dist/cjs/extractor/detectModuleFormat.cjs +53 -0
- package/dist/cjs/extractor/esbuildAliasPlugin.cjs +46 -0
- package/dist/cjs/extractor/esbuildTsconfigPaths.cjs +91 -0
- package/dist/cjs/extractor/getTamaguiConfigPathFromOptionsConfig.cjs +42 -0
- package/dist/cjs/extractor/loadTamagui.cjs +394 -0
- package/dist/cjs/extractor/regenerateConfig.cjs +160 -0
- package/dist/cjs/extractor/watchTamaguiConfig.cjs +63 -0
- package/dist/cjs/getPragmaOptions.cjs +66 -0
- package/dist/cjs/helpers/memoize.cjs +41 -0
- package/dist/cjs/helpers/requireTamaguiCore.cjs +39 -0
- package/dist/cjs/index.cjs +33 -0
- package/dist/cjs/registerRequire.cjs +219 -0
- package/dist/cjs/server.cjs +65 -0
- package/dist/cjs/staticEvaluationIgnoredModules.cjs +85 -0
- package/dist/cjs/types.cjs +16 -0
- package/dist/cjs/zero/artifact.cjs +144 -0
- package/dist/cjs/zero/graph.cjs +208 -0
- package/dist/cjs/zero/identity.cjs +60 -0
- package/dist/cjs/zero/index.cjs +33 -0
- package/dist/cjs/zero/islands.cjs +235 -0
- package/dist/cjs/zero/options.cjs +162 -0
- package/dist/cjs/zero/ownership.cjs +78 -0
- package/dist/cjs/zero/theme.cjs +337 -0
- package/dist/cjs/zero/transform.cjs +207 -0
- package/dist/esm/check-dep-versions.mjs +329 -0
- package/dist/esm/check-dep-versions.mjs.map +1 -0
- package/dist/esm/checkDeps.mjs +279 -0
- package/dist/esm/checkDeps.mjs.map +1 -0
- package/dist/esm/compiler.mjs +319 -0
- package/dist/esm/compiler.mjs.map +1 -0
- package/dist/esm/compilerHost.mjs +2265 -0
- package/dist/esm/compilerHost.mjs.map +1 -0
- package/dist/esm/componentDiscovery.mjs +69 -0
- package/dist/esm/componentDiscovery.mjs.map +1 -0
- package/dist/esm/constants.mjs +7 -0
- package/dist/esm/constants.mjs.map +1 -0
- package/dist/esm/domStructuralPass.mjs +102 -0
- package/dist/esm/domStructuralPass.mjs.map +1 -0
- package/dist/esm/exports.mjs +29 -0
- package/dist/esm/extractor/addLocalExports.mjs +44 -0
- package/dist/esm/extractor/addLocalExports.mjs.map +1 -0
- package/dist/esm/extractor/bundle.mjs +199 -0
- package/dist/esm/extractor/bundle.mjs.map +1 -0
- package/dist/esm/extractor/bundleConfig.mjs +728 -0
- package/dist/esm/extractor/bundleConfig.mjs.map +1 -0
- package/dist/esm/extractor/concatClassName.mjs +100 -0
- package/dist/esm/extractor/concatClassName.mjs.map +1 -0
- package/dist/esm/extractor/detectModuleFormat.mjs +31 -0
- package/dist/esm/extractor/detectModuleFormat.mjs.map +1 -0
- package/dist/esm/extractor/esbuildAliasPlugin.mjs +26 -0
- package/dist/esm/extractor/esbuildAliasPlugin.mjs.map +1 -0
- package/dist/esm/extractor/esbuildTsconfigPaths.mjs +63 -0
- package/dist/esm/extractor/esbuildTsconfigPaths.mjs.map +1 -0
- package/dist/esm/extractor/getTamaguiConfigPathFromOptionsConfig.mjs +23 -0
- package/dist/esm/extractor/getTamaguiConfigPathFromOptionsConfig.mjs.map +1 -0
- package/dist/esm/extractor/loadTamagui.mjs +357 -0
- package/dist/esm/extractor/loadTamagui.mjs.map +1 -0
- package/dist/esm/extractor/regenerateConfig.mjs +131 -0
- package/dist/esm/extractor/regenerateConfig.mjs.map +1 -0
- package/dist/esm/extractor/watchTamaguiConfig.mjs +43 -0
- package/dist/esm/extractor/watchTamaguiConfig.mjs.map +1 -0
- package/dist/esm/getPragmaOptions.mjs +46 -0
- package/dist/esm/getPragmaOptions.mjs.map +1 -0
- package/dist/esm/helpers/memoize.mjs +21 -0
- package/dist/esm/helpers/memoize.mjs.map +1 -0
- package/dist/esm/helpers/requireTamaguiCore.mjs +19 -0
- package/dist/esm/helpers/requireTamaguiCore.mjs.map +1 -0
- package/dist/esm/index.mjs +8 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/registerRequire.mjs +195 -0
- package/dist/esm/registerRequire.mjs.map +1 -0
- package/dist/esm/server.mjs +40 -0
- package/dist/esm/server.mjs.map +1 -0
- package/dist/esm/setup.mjs +0 -0
- package/dist/esm/staticEvaluationIgnoredModules.mjs +61 -0
- package/dist/esm/staticEvaluationIgnoredModules.mjs.map +1 -0
- package/dist/esm/types.mjs +0 -0
- package/dist/esm/zero/artifact.mjs +119 -0
- package/dist/esm/zero/artifact.mjs.map +1 -0
- package/dist/esm/zero/graph.mjs +170 -0
- package/dist/esm/zero/graph.mjs.map +1 -0
- package/dist/esm/zero/identity.mjs +36 -0
- package/dist/esm/zero/identity.mjs.map +1 -0
- package/dist/esm/zero/index.mjs +19 -0
- package/dist/esm/zero/islands.mjs +201 -0
- package/dist/esm/zero/islands.mjs.map +1 -0
- package/dist/esm/zero/options.mjs +129 -0
- package/dist/esm/zero/options.mjs.map +1 -0
- package/dist/esm/zero/ownership.mjs +48 -0
- package/dist/esm/zero/ownership.mjs.map +1 -0
- package/dist/esm/zero/theme.mjs +313 -0
- package/dist/esm/zero/theme.mjs.map +1 -0
- package/dist/esm/zero/transform.mjs +182 -0
- package/dist/esm/zero/transform.mjs.map +1 -0
- package/package.json +38 -47
- package/src/check-dep-versions.ts +2 -2
- package/src/checkDeps.ts +3 -2
- package/src/compiler.ts +506 -0
- package/src/compilerHost.ts +3739 -0
- package/src/componentDiscovery.ts +105 -0
- package/src/constants.ts +0 -5
- package/src/domStructuralPass.ts +190 -0
- package/src/exports.ts +5 -6
- package/src/extractor/addLocalExports.ts +49 -0
- package/src/extractor/bundle.ts +38 -40
- package/src/extractor/bundleConfig.ts +368 -187
- package/src/extractor/concatClassName.ts +21 -24
- package/src/extractor/getTamaguiConfigPathFromOptionsConfig.ts +13 -5
- package/src/extractor/loadTamagui.ts +196 -143
- package/src/extractor/regenerateConfig.ts +65 -13
- package/src/extractor/watchTamaguiConfig.ts +6 -1
- package/src/helpers/requireTamaguiCore.ts +6 -1
- package/src/registerRequire.ts +94 -132
- package/src/staticEvaluationIgnoredModules.ts +74 -0
- package/src/types.ts +2 -107
- package/src/zero/artifact.ts +142 -0
- package/src/zero/graph.ts +359 -0
- package/src/zero/identity.ts +73 -0
- package/src/zero/index.ts +9 -0
- package/src/zero/islands.ts +266 -0
- package/src/zero/options.ts +239 -0
- package/src/zero/ownership.ts +113 -0
- package/src/zero/theme.ts +526 -0
- package/src/zero/transform.ts +329 -0
- package/types/check-dep-versions.d.ts.map +1 -1
- package/types/checkDeps.d.ts.map +1 -1
- package/types/compiler.d.ts +134 -0
- package/types/compiler.d.ts.map +1 -0
- package/types/compilerHost.d.ts +38 -0
- package/types/compilerHost.d.ts.map +1 -0
- package/types/componentDiscovery.d.ts +27 -0
- package/types/componentDiscovery.d.ts.map +1 -0
- package/types/constants.d.ts +0 -1
- package/types/constants.d.ts.map +1 -1
- package/types/domStructuralPass.d.ts +3 -0
- package/types/domStructuralPass.d.ts.map +1 -0
- package/types/exports.d.ts +5 -6
- package/types/exports.d.ts.map +1 -1
- package/types/extractor/addLocalExports.d.ts +3 -0
- package/types/extractor/addLocalExports.d.ts.map +1 -0
- package/types/extractor/bundle.d.ts +66 -65
- package/types/extractor/bundle.d.ts.map +1 -1
- package/types/extractor/bundleConfig.d.ts +26 -4
- package/types/extractor/bundleConfig.d.ts.map +1 -1
- package/types/extractor/esbuildAliasPlugin.d.ts.map +1 -1
- package/types/extractor/getTamaguiConfigPathFromOptionsConfig.d.ts +1 -1
- package/types/extractor/getTamaguiConfigPathFromOptionsConfig.d.ts.map +1 -1
- package/types/extractor/loadTamagui.d.ts +26 -3
- package/types/extractor/loadTamagui.d.ts.map +1 -1
- package/types/extractor/regenerateConfig.d.ts +1 -1
- package/types/extractor/regenerateConfig.d.ts.map +1 -1
- package/types/extractor/watchTamaguiConfig.d.ts.map +1 -1
- package/types/getPragmaOptions.d.ts +1 -1
- package/types/helpers/memoize.d.ts +1 -1
- package/types/helpers/memoize.d.ts.map +1 -1
- package/types/helpers/requireTamaguiCore.d.ts.map +1 -1
- package/types/index.d.ts.map +1 -1
- package/types/registerRequire.d.ts +2 -2
- package/types/registerRequire.d.ts.map +1 -1
- package/types/staticEvaluationIgnoredModules.d.ts +9 -0
- package/types/staticEvaluationIgnoredModules.d.ts.map +1 -0
- package/types/types.d.ts +2 -90
- package/types/types.d.ts.map +1 -1
- package/types/zero/artifact.d.ts +44 -0
- package/types/zero/artifact.d.ts.map +1 -0
- package/types/zero/graph.d.ts +139 -0
- package/types/zero/graph.d.ts.map +1 -0
- package/types/zero/identity.d.ts +33 -0
- package/types/zero/identity.d.ts.map +1 -0
- package/types/zero/index.d.ts +10 -0
- package/types/zero/index.d.ts.map +1 -0
- package/types/zero/islands.d.ts +56 -0
- package/types/zero/islands.d.ts.map +1 -0
- package/types/zero/options.d.ts +58 -0
- package/types/zero/options.d.ts.map +1 -0
- package/types/zero/ownership.d.ts +51 -0
- package/types/zero/ownership.d.ts.map +1 -0
- package/types/zero/theme.d.ts +85 -0
- package/types/zero/theme.d.ts.map +1 -0
- package/types/zero/transform.d.ts +53 -0
- package/types/zero/transform.d.ts.map +1 -0
- package/dist/check-dep-versions.cjs +0 -372
- package/dist/checkDeps.cjs +0 -271
- package/dist/constants.cjs +0 -51
- package/dist/exports.cjs +0 -48
- package/dist/extractor/accessSafe.cjs +0 -48
- package/dist/extractor/babelParse.cjs +0 -56
- package/dist/extractor/buildClassName.cjs +0 -86
- package/dist/extractor/bundle.cjs +0 -234
- package/dist/extractor/bundleConfig.cjs +0 -729
- package/dist/extractor/concatClassName.cjs +0 -129
- package/dist/extractor/createEvaluator.cjs +0 -88
- package/dist/extractor/createExtractor.cjs +0 -1968
- package/dist/extractor/createLogger.cjs +0 -50
- package/dist/extractor/detectModuleFormat.cjs +0 -55
- package/dist/extractor/ensureImportingConcat.cjs +0 -54
- package/dist/extractor/errors.cjs +0 -28
- package/dist/extractor/esbuildAliasPlugin.cjs +0 -56
- package/dist/extractor/esbuildTsconfigPaths.cjs +0 -108
- package/dist/extractor/evaluateAstNode.cjs +0 -128
- package/dist/extractor/extractHelpers.cjs +0 -182
- package/dist/extractor/extractMediaStyle.cjs +0 -169
- package/dist/extractor/extractToClassNames.cjs +0 -475
- package/dist/extractor/extractToNative.cjs +0 -369
- package/dist/extractor/findTopmostFunction.cjs +0 -43
- package/dist/extractor/generatedUid.cjs +0 -58
- package/dist/extractor/getPrefixLogs.cjs +0 -31
- package/dist/extractor/getPropValueFromAttributes.cjs +0 -85
- package/dist/extractor/getSourceModule.cjs +0 -100
- package/dist/extractor/getStaticBindingsForScope.cjs +0 -213
- package/dist/extractor/getTamaguiConfigPathFromOptionsConfig.cjs +0 -41
- package/dist/extractor/hasTopLevelAwait.cjs +0 -62
- package/dist/extractor/hoistClassNames.cjs +0 -76
- package/dist/extractor/literalToAst.cjs +0 -109
- package/dist/extractor/loadFile.cjs +0 -17
- package/dist/extractor/loadTamagui.cjs +0 -373
- package/dist/extractor/logLines.cjs +0 -43
- package/dist/extractor/normalizeTernaries.cjs +0 -100
- package/dist/extractor/propsToFontFamilyCache.cjs +0 -42
- package/dist/extractor/regenerateConfig.cjs +0 -178
- package/dist/extractor/removeUnusedHooks.cjs +0 -108
- package/dist/extractor/timer.cjs +0 -52
- package/dist/extractor/validHTMLAttributes.cjs +0 -79
- package/dist/extractor/watchTamaguiConfig.cjs +0 -70
- package/dist/getPragmaOptions.cjs +0 -73
- package/dist/helpers/memoize.cjs +0 -45
- package/dist/helpers/requireTamaguiCore.cjs +0 -40
- package/dist/index.cjs +0 -42
- package/dist/registerRequire.cjs +0 -209
- package/dist/server.cjs +0 -82
- package/dist/types.cjs +0 -18
- package/dist/worker.cjs +0 -111
- package/src/extractor/accessSafe.ts +0 -22
- package/src/extractor/babelParse.ts +0 -38
- package/src/extractor/buildClassName.ts +0 -76
- package/src/extractor/createEvaluator.ts +0 -82
- package/src/extractor/createExtractor.ts +0 -2970
- package/src/extractor/createLogger.ts +0 -41
- package/src/extractor/ensureImportingConcat.ts +0 -36
- package/src/extractor/errors.ts +0 -1
- package/src/extractor/evaluateAstNode.ts +0 -136
- package/src/extractor/extractHelpers.ts +0 -211
- package/src/extractor/extractMediaStyle.ts +0 -194
- package/src/extractor/extractToClassNames.ts +0 -733
- package/src/extractor/extractToNative.ts +0 -506
- package/src/extractor/findTopmostFunction.ts +0 -24
- package/src/extractor/generatedUid.ts +0 -41
- package/src/extractor/getPrefixLogs.ts +0 -9
- package/src/extractor/getPropValueFromAttributes.ts +0 -95
- package/src/extractor/getSourceModule.ts +0 -96
- package/src/extractor/getStaticBindingsForScope.ts +0 -237
- package/src/extractor/hasTopLevelAwait.ts +0 -28
- package/src/extractor/hoistClassNames.ts +0 -52
- package/src/extractor/literalToAst.ts +0 -85
- package/src/extractor/loadFile.ts +0 -17
- package/src/extractor/logLines.ts +0 -16
- package/src/extractor/normalizeTernaries.ts +0 -89
- package/src/extractor/propsToFontFamilyCache.ts +0 -18
- package/src/extractor/removeUnusedHooks.ts +0 -83
- package/src/extractor/timer.ts +0 -25
- package/src/extractor/validHTMLAttributes.ts +0 -52
- package/src/worker.ts +0 -142
- package/types/extractor/accessSafe.d.ts +0 -3
- package/types/extractor/accessSafe.d.ts.map +0 -1
- package/types/extractor/babelParse.d.ts +0 -5
- package/types/extractor/babelParse.d.ts.map +0 -1
- package/types/extractor/buildClassName.d.ts +0 -7
- package/types/extractor/buildClassName.d.ts.map +0 -1
- package/types/extractor/createEvaluator.d.ts +0 -12
- package/types/extractor/createEvaluator.d.ts.map +0 -1
- package/types/extractor/createExtractor.d.ts +0 -32
- package/types/extractor/createExtractor.d.ts.map +0 -1
- package/types/extractor/createLogger.d.ts +0 -3
- package/types/extractor/createLogger.d.ts.map +0 -1
- package/types/extractor/ensureImportingConcat.d.ts +0 -4
- package/types/extractor/ensureImportingConcat.d.ts.map +0 -1
- package/types/extractor/errors.d.ts +0 -3
- package/types/extractor/errors.d.ts.map +0 -1
- package/types/extractor/evaluateAstNode.d.ts +0 -3
- package/types/extractor/evaluateAstNode.d.ts.map +0 -1
- package/types/extractor/extractHelpers.d.ts +0 -28
- package/types/extractor/extractHelpers.d.ts.map +0 -1
- package/types/extractor/extractMediaStyle.d.ts +0 -11
- package/types/extractor/extractMediaStyle.d.ts.map +0 -1
- package/types/extractor/extractToClassNames.d.ts +0 -25
- package/types/extractor/extractToClassNames.d.ts.map +0 -1
- package/types/extractor/extractToNative.d.ts +0 -13
- package/types/extractor/extractToNative.d.ts.map +0 -1
- package/types/extractor/findTopmostFunction.d.ts +0 -4
- package/types/extractor/findTopmostFunction.d.ts.map +0 -1
- package/types/extractor/generatedUid.d.ts +0 -5
- package/types/extractor/generatedUid.d.ts.map +0 -1
- package/types/extractor/getPrefixLogs.d.ts +0 -3
- package/types/extractor/getPrefixLogs.d.ts.map +0 -1
- package/types/extractor/getPropValueFromAttributes.d.ts +0 -19
- package/types/extractor/getPropValueFromAttributes.d.ts.map +0 -1
- package/types/extractor/getSourceModule.d.ts +0 -16
- package/types/extractor/getSourceModule.d.ts.map +0 -1
- package/types/extractor/getStaticBindingsForScope.d.ts +0 -5
- package/types/extractor/getStaticBindingsForScope.d.ts.map +0 -1
- package/types/extractor/hasTopLevelAwait.d.ts +0 -2
- package/types/extractor/hasTopLevelAwait.d.ts.map +0 -1
- package/types/extractor/hoistClassNames.d.ts +0 -6
- package/types/extractor/hoistClassNames.d.ts.map +0 -1
- package/types/extractor/literalToAst.d.ts +0 -4
- package/types/extractor/literalToAst.d.ts.map +0 -1
- package/types/extractor/loadFile.d.ts +0 -1
- package/types/extractor/loadFile.d.ts.map +0 -1
- package/types/extractor/logLines.d.ts +0 -2
- package/types/extractor/logLines.d.ts.map +0 -1
- package/types/extractor/normalizeTernaries.d.ts +0 -5
- package/types/extractor/normalizeTernaries.d.ts.map +0 -1
- package/types/extractor/propsToFontFamilyCache.d.ts +0 -4
- package/types/extractor/propsToFontFamilyCache.d.ts.map +0 -1
- package/types/extractor/removeUnusedHooks.d.ts +0 -3
- package/types/extractor/removeUnusedHooks.d.ts.map +0 -1
- package/types/extractor/timer.d.ts +0 -5
- package/types/extractor/timer.d.ts.map +0 -1
- package/types/extractor/validHTMLAttributes.d.ts +0 -52
- package/types/extractor/validHTMLAttributes.d.ts.map +0 -1
- package/types/worker.d.ts +0 -46
- package/types/worker.d.ts.map +0 -1
- /package/dist/{setup.cjs → cjs/setup.cjs} +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { MaterializedModule } from '@tamagui/compiler-core'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
|
|
4
|
+
import type { CompilerComponentRegistry } from './compilerHost'
|
|
5
|
+
import {
|
|
6
|
+
getComponentStaticConfigByName,
|
|
7
|
+
type LoadedComponents,
|
|
8
|
+
} from './extractor/bundleConfig'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Evaluate a host-resolved module and return its exports, or null when the
|
|
12
|
+
* host cannot run it. Frontends supply this from their bundler's module runner
|
|
13
|
+
* (Vite) or the static-evaluation require hooks (`evaluateComponentModule`).
|
|
14
|
+
*/
|
|
15
|
+
export type ComponentModuleEvaluator = (module: {
|
|
16
|
+
id: string
|
|
17
|
+
specifier: string
|
|
18
|
+
}) => Promise<Record<string, unknown> | null>
|
|
19
|
+
|
|
20
|
+
// `pkg`, `@scope/pkg`, and their subpaths. `@/x` and `~/x` are path aliases
|
|
21
|
+
const packageSpecifier = /^(?:@[^/@\s]+\/)?[^./~@\s][^/\s]*(?:\/|$)/
|
|
22
|
+
|
|
23
|
+
function isPackageSpecifier(specifier: string): boolean {
|
|
24
|
+
return packageSpecifier.test(specifier)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Finds the component modules a file uses that the configured `components`
|
|
29
|
+
* list does not cover, evaluates each once, and registers what it exports so
|
|
30
|
+
* lowering resolves them like configured ones. Owned by a frontend for the
|
|
31
|
+
* life of a project generation; `prepare` runs between materialize and lower.
|
|
32
|
+
*/
|
|
33
|
+
export class ComponentDiscovery {
|
|
34
|
+
/** null records a module that had no components or could not evaluate */
|
|
35
|
+
readonly #discovered = new Map<string, LoadedComponents | null>()
|
|
36
|
+
|
|
37
|
+
clear(): void {
|
|
38
|
+
this.#discovered.clear()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** host-resolved ids of every module discovery found components in */
|
|
42
|
+
ids(): string[] {
|
|
43
|
+
return [...this.#discovered]
|
|
44
|
+
.filter(([, loaded]) => loaded !== null)
|
|
45
|
+
.map(([id]) => id)
|
|
46
|
+
.sort()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** re-register everything found so far into a freshly built registry */
|
|
50
|
+
seed(registry: CompilerComponentRegistry): void {
|
|
51
|
+
for (const [id, loaded] of this.#discovered) {
|
|
52
|
+
if (!loaded) continue
|
|
53
|
+
registry.modulesById.set(id, id)
|
|
54
|
+
registry.componentsByModule.set(id, loaded)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async prepare(
|
|
59
|
+
module: MaterializedModule,
|
|
60
|
+
registry: CompilerComponentRegistry,
|
|
61
|
+
evaluate: ComponentModuleEvaluator | undefined
|
|
62
|
+
): Promise<void> {
|
|
63
|
+
if (!evaluate) return
|
|
64
|
+
const seen = new Set<string>()
|
|
65
|
+
const provenances = [
|
|
66
|
+
...module.elements.map((element) => element.component.provenance),
|
|
67
|
+
...module.styledDefinitions.map((definition) => definition.base.provenance),
|
|
68
|
+
]
|
|
69
|
+
for (const provenance of provenances) {
|
|
70
|
+
// a relative or aliased import is the app's own module: the graph
|
|
71
|
+
// already models its styled definitions, and evaluating app code at
|
|
72
|
+
// build time runs its side effects
|
|
73
|
+
if (!provenance || !isPackageSpecifier(provenance.specifier)) continue
|
|
74
|
+
const id = provenance.resolvedId.split(/[?#]/, 1)[0]
|
|
75
|
+
if (seen.has(id) || registry.modulesById.has(id) || this.#discovered.has(id)) {
|
|
76
|
+
continue
|
|
77
|
+
}
|
|
78
|
+
seen.add(id)
|
|
79
|
+
if (!path.isAbsolute(id)) {
|
|
80
|
+
this.#discovered.set(id, null)
|
|
81
|
+
continue
|
|
82
|
+
}
|
|
83
|
+
let loaded: LoadedComponents | null = null
|
|
84
|
+
try {
|
|
85
|
+
const exports = await evaluate({ id, specifier: provenance.specifier })
|
|
86
|
+
if (exports) {
|
|
87
|
+
const nameToInfo = getComponentStaticConfigByName(
|
|
88
|
+
id,
|
|
89
|
+
(exports as { default?: unknown }).default ?? exports
|
|
90
|
+
)
|
|
91
|
+
if (Object.keys(nameToInfo).length) loaded = { moduleName: id, nameToInfo }
|
|
92
|
+
}
|
|
93
|
+
} catch (error) {
|
|
94
|
+
if (process.env.DEBUG === 'tamagui') {
|
|
95
|
+
console.info(`[tamagui] component discovery skipped ${id}:`, error)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
this.#discovered.set(id, loaded)
|
|
99
|
+
if (loaded) {
|
|
100
|
+
registry.modulesById.set(id, id)
|
|
101
|
+
registry.componentsByModule.set(id, loaded)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
package/src/constants.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import findCacheDir from 'find-cache-dir'
|
|
2
|
-
|
|
3
1
|
export const CSS_FILE_NAME = '__snack.css'
|
|
4
2
|
|
|
5
3
|
// ENSURE THIS ISNT THE SAME AS THE SEPARATOR USED FOR STYLE KEYS
|
|
6
4
|
export const MEDIA_SEP = '_'
|
|
7
5
|
|
|
8
|
-
// ensure cache dir
|
|
9
|
-
export const cacheDir = findCacheDir({ name: 'tamagui', create: true })
|
|
10
|
-
|
|
11
6
|
export const FAILED_EVAL = Symbol('failed_style_eval')
|
|
12
7
|
|
|
13
8
|
export const SHOULD_DEBUG =
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ATTRIBUTES,
|
|
3
|
+
EVENTS,
|
|
4
|
+
NATIVE_BACKING,
|
|
5
|
+
TAGS,
|
|
6
|
+
type PropTags,
|
|
7
|
+
type TagName,
|
|
8
|
+
} from '@tamagui/dom'
|
|
9
|
+
import {
|
|
10
|
+
localBailout,
|
|
11
|
+
type BailoutReason,
|
|
12
|
+
type MaterializedElement,
|
|
13
|
+
type MaterializedModule,
|
|
14
|
+
type SourceEdit,
|
|
15
|
+
type StructuralModulePass,
|
|
16
|
+
} from '@tamagui/compiler-core'
|
|
17
|
+
import { createHash } from 'node:crypto'
|
|
18
|
+
|
|
19
|
+
const DOM_FRONTENDS = new Set([
|
|
20
|
+
'tamagui',
|
|
21
|
+
'tamagui/dom',
|
|
22
|
+
'@tamagui/core',
|
|
23
|
+
'@tamagui/core/dom',
|
|
24
|
+
'@tamagui/tailwind',
|
|
25
|
+
])
|
|
26
|
+
|
|
27
|
+
const RUNTIME_STYLE_FRONTENDS = new Set(['tamagui', '@tamagui/core', '@tamagui/web'])
|
|
28
|
+
|
|
29
|
+
const acceptsTag = (accepted: PropTags, tag: TagName) =>
|
|
30
|
+
accepted === '*' || accepted.includes(tag)
|
|
31
|
+
|
|
32
|
+
function isDOMElement(element: MaterializedElement) {
|
|
33
|
+
const provenance = element.component.provenance
|
|
34
|
+
return provenance?.importedName === 'html' && DOM_FRONTENDS.has(provenance.specifier)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const versionHash = createHash('sha256')
|
|
38
|
+
.update(
|
|
39
|
+
JSON.stringify({
|
|
40
|
+
ATTRIBUTES,
|
|
41
|
+
EVENTS,
|
|
42
|
+
NATIVE_BACKING,
|
|
43
|
+
TAGS,
|
|
44
|
+
})
|
|
45
|
+
)
|
|
46
|
+
.digest('hex')
|
|
47
|
+
|
|
48
|
+
export const domStructuralPass: StructuralModulePass = {
|
|
49
|
+
versionHash: `dom-structural-v4-${versionHash}`,
|
|
50
|
+
transform({ module, source, target }) {
|
|
51
|
+
const edits: SourceEdit[] = []
|
|
52
|
+
const diagnostics: BailoutReason[] = []
|
|
53
|
+
const domElements = module.elements.filter(isDOMElement)
|
|
54
|
+
const supportedDOMElements = domElements.filter(
|
|
55
|
+
(
|
|
56
|
+
element
|
|
57
|
+
): element is MaterializedElement & {
|
|
58
|
+
component: MaterializedElement['component'] & { name: TagName }
|
|
59
|
+
} => element.component.name in TAGS
|
|
60
|
+
)
|
|
61
|
+
const domBySpan = new Map(
|
|
62
|
+
supportedDOMElements.map((element) => [
|
|
63
|
+
`${element.span.start}:${element.span.end}`,
|
|
64
|
+
element,
|
|
65
|
+
])
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
for (const element of domElements) {
|
|
69
|
+
const tagName = element.component.name as TagName
|
|
70
|
+
if (!(tagName in TAGS)) {
|
|
71
|
+
diagnostics.push(
|
|
72
|
+
localBailout(
|
|
73
|
+
'local/unsupported-target',
|
|
74
|
+
element.component.span,
|
|
75
|
+
`html.${element.component.name} is not part of the Tamagui DOM contract`
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
continue
|
|
79
|
+
}
|
|
80
|
+
const tag = TAGS[tagName]
|
|
81
|
+
if (target === 'native' && tag.native === 'none') {
|
|
82
|
+
diagnostics.push(
|
|
83
|
+
localBailout(
|
|
84
|
+
'local/unsupported-target',
|
|
85
|
+
element.component.span,
|
|
86
|
+
`html.${tagName} is not supported on native: ${tag.note ?? 'no native backing'}`
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
continue
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (const entry of element.entries) {
|
|
93
|
+
if (entry.kind !== 'prop') continue
|
|
94
|
+
const attribute =
|
|
95
|
+
(entry.name in ATTRIBUTES ? ATTRIBUTES[entry.name] : undefined) ??
|
|
96
|
+
(entry.name.startsWith('data-') ? ATTRIBUTES['data-*'] : undefined)
|
|
97
|
+
const event = entry.name in EVENTS ? EVENTS[entry.name] : undefined
|
|
98
|
+
const row = attribute ?? event
|
|
99
|
+
if (!row) continue
|
|
100
|
+
if (!acceptsTag(row.tags, tagName)) {
|
|
101
|
+
diagnostics.push(
|
|
102
|
+
localBailout(
|
|
103
|
+
'local/unsupported-prop-key',
|
|
104
|
+
entry.span,
|
|
105
|
+
`${entry.name} is not supported on html.${tagName}`
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
if (target === 'native' && row.native === 'none') {
|
|
111
|
+
if (event) continue
|
|
112
|
+
diagnostics.push(
|
|
113
|
+
localBailout(
|
|
114
|
+
'local/unsupported-prop-key',
|
|
115
|
+
entry.span,
|
|
116
|
+
`${entry.name} is not supported on native html.${tagName}: ${row.note ?? 'no native equivalent'}`
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
for (const entry of element.entries) {
|
|
123
|
+
if (entry.kind !== 'child' || entry.value.kind !== 'element') continue
|
|
124
|
+
const child = domBySpan.get(`${entry.value.span.start}:${entry.value.span.end}`)
|
|
125
|
+
if (!child) continue
|
|
126
|
+
const childTag = child.component.name
|
|
127
|
+
const invalid =
|
|
128
|
+
tag.content === 'void' ||
|
|
129
|
+
tag.content === 'text' ||
|
|
130
|
+
(tag.content === 'phrasing' && TAGS[childTag].display === 'block') ||
|
|
131
|
+
(tag.content === 'tags' && !tag.childTags?.includes(childTag))
|
|
132
|
+
if (invalid) {
|
|
133
|
+
diagnostics.push(
|
|
134
|
+
localBailout(
|
|
135
|
+
'local/unsupported-child',
|
|
136
|
+
child.component.span,
|
|
137
|
+
`html.${childTag} cannot be nested directly inside html.${tagName}`
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
for (const definition of module.domStyleDefinitions) {
|
|
145
|
+
if (definition.value.kind !== 'static') {
|
|
146
|
+
diagnostics.push(
|
|
147
|
+
localBailout(
|
|
148
|
+
'local/dynamic-style-value',
|
|
149
|
+
definition.value.span,
|
|
150
|
+
`style() definition ${definition.name} must be statically evaluable`
|
|
151
|
+
)
|
|
152
|
+
)
|
|
153
|
+
continue
|
|
154
|
+
}
|
|
155
|
+
const isRuntimeStyle = RUNTIME_STYLE_FRONTENDS.has(definition.factory.specifier)
|
|
156
|
+
if (
|
|
157
|
+
isRuntimeStyle &&
|
|
158
|
+
(!definition.value.value ||
|
|
159
|
+
typeof definition.value.value !== 'object' ||
|
|
160
|
+
Array.isArray(definition.value.value))
|
|
161
|
+
) {
|
|
162
|
+
diagnostics.push(
|
|
163
|
+
localBailout(
|
|
164
|
+
'local/dynamic-style-value',
|
|
165
|
+
definition.value.span,
|
|
166
|
+
`style() definition ${definition.name} must be an object literal`
|
|
167
|
+
)
|
|
168
|
+
)
|
|
169
|
+
continue
|
|
170
|
+
}
|
|
171
|
+
edits.push({
|
|
172
|
+
start: definition.span.start,
|
|
173
|
+
end: definition.span.end,
|
|
174
|
+
content: isRuntimeStyle
|
|
175
|
+
? `({ className: "", [Symbol.for("tamagui.stylePiece")]: { byKey: {}, styleObject: ${JSON.stringify(definition.value.value)} } })`
|
|
176
|
+
: 'undefined',
|
|
177
|
+
origin: definition.span,
|
|
178
|
+
})
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const nextModule: MaterializedModule = module
|
|
182
|
+
return {
|
|
183
|
+
module: nextModule,
|
|
184
|
+
edits,
|
|
185
|
+
imports: [],
|
|
186
|
+
diagnostics,
|
|
187
|
+
dependencies: [],
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
}
|
package/src/exports.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
export * from './checkDeps'
|
|
2
|
+
export * from './compilerHost'
|
|
3
|
+
export * from './compiler'
|
|
2
4
|
export * from './types'
|
|
3
|
-
export { createExtractor } from './extractor/createExtractor'
|
|
4
|
-
export { literalToAst } from './extractor/literalToAst'
|
|
5
5
|
export * from './constants'
|
|
6
|
-
export * from './extractor/extractToClassNames'
|
|
7
6
|
export * from './extractor/concatClassName'
|
|
8
|
-
export * from './extractor/extractToNative'
|
|
9
|
-
export * from './extractor/extractHelpers'
|
|
10
7
|
export * from './extractor/loadTamagui'
|
|
8
|
+
export { evaluateComponentModule } from './extractor/bundleConfig'
|
|
9
|
+
export * from './componentDiscovery'
|
|
11
10
|
export * from './extractor/watchTamaguiConfig'
|
|
12
|
-
export * from './extractor/createLogger'
|
|
13
11
|
export * from './registerRequire'
|
|
14
12
|
export { detectModuleFormat, clearFormatCache } from './extractor/detectModuleFormat'
|
|
15
13
|
export { esbundleTamaguiConfig } from './extractor/bundle'
|
|
16
14
|
export * from './getPragmaOptions'
|
|
15
|
+
export * from './zero'
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
childNode,
|
|
3
|
+
childNodes,
|
|
4
|
+
identifierName,
|
|
5
|
+
parseModuleAst,
|
|
6
|
+
} from '@tamagui/compiler-core'
|
|
7
|
+
|
|
8
|
+
function declarationName(node: ReturnType<typeof childNode>): string | null {
|
|
9
|
+
return identifierName(node ? childNode(node, 'id') : null)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Adds exports used only while evaluating local component modules. */
|
|
13
|
+
export function addLocalExports(source: string, id?: string): string {
|
|
14
|
+
const program = parseModuleAst(source, id)
|
|
15
|
+
const usedNames = new Set<string>()
|
|
16
|
+
const candidates: string[] = []
|
|
17
|
+
|
|
18
|
+
for (const statement of childNodes(program, 'body')) {
|
|
19
|
+
if (statement.type === 'ExportNamedDeclaration') {
|
|
20
|
+
for (const specifier of childNodes(statement, 'specifiers')) {
|
|
21
|
+
const exported = childNode(specifier, 'exported')
|
|
22
|
+
const name = identifierName(exported)
|
|
23
|
+
if (name) usedNames.add(name)
|
|
24
|
+
}
|
|
25
|
+
const declaration = childNode(statement, 'declaration')
|
|
26
|
+
if (declaration?.type === 'VariableDeclaration') {
|
|
27
|
+
for (const declarator of childNodes(declaration, 'declarations')) {
|
|
28
|
+
const name = declarationName(declarator)
|
|
29
|
+
if (name) usedNames.add(name)
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
const name = declarationName(declaration)
|
|
33
|
+
if (name) usedNames.add(name)
|
|
34
|
+
}
|
|
35
|
+
continue
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (statement.type !== 'VariableDeclaration') continue
|
|
39
|
+
const declarations = childNodes(statement, 'declarations')
|
|
40
|
+
if (declarations.length !== 1) continue
|
|
41
|
+
const declaration = declarations[0]!
|
|
42
|
+
const name = declarationName(declaration)
|
|
43
|
+
if (!name || !childNode(declaration, 'init') || usedNames.has(name)) continue
|
|
44
|
+
candidates.push(name)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const names = candidates.filter((name) => !usedNames.has(name))
|
|
48
|
+
return names.length ? `${source}\nexport { ${names.join(', ')} }\n` : source
|
|
49
|
+
}
|
package/src/extractor/bundle.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto'
|
|
1
2
|
import { readFileSync } from 'node:fs'
|
|
3
|
+
import { createRequire } from 'node:module'
|
|
2
4
|
import esbuild from 'esbuild'
|
|
3
|
-
import
|
|
5
|
+
import FS from 'fs-extra'
|
|
4
6
|
import type { TamaguiPlatform } from '../types'
|
|
7
|
+
import { staticEvaluationIgnorePlugin } from '../staticEvaluationIgnoredModules'
|
|
5
8
|
import { detectModuleFormat } from './detectModuleFormat'
|
|
6
9
|
import { esbuildAliasPlugin } from './esbuildAliasPlugin'
|
|
7
|
-
import { hasTopLevelAwait } from './hasTopLevelAwait'
|
|
8
10
|
import { resolveWebOrNativeSpecificEntry } from './loadTamagui'
|
|
9
11
|
import { TsconfigPathsPlugin } from './esbuildTsconfigPaths'
|
|
10
12
|
|
|
13
|
+
const nodeRequire = createRequire(
|
|
14
|
+
typeof __filename === 'string' ? __filename : import.meta.url
|
|
15
|
+
)
|
|
16
|
+
|
|
11
17
|
export const esbuildLoaderConfig = {
|
|
12
18
|
'.js': 'jsx',
|
|
13
19
|
'.png': 'dataurl',
|
|
@@ -50,12 +56,14 @@ type Props = Omit<Partial<esbuild.BuildOptions>, 'entryPoints'> & {
|
|
|
50
56
|
outfile: string
|
|
51
57
|
entryPoints: string[]
|
|
52
58
|
resolvePlatformSpecificEntries?: boolean
|
|
59
|
+
dangerouslyIgnoreStaticEvaluationModules?: string[]
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
function getESBuildConfig(
|
|
56
63
|
{
|
|
57
64
|
entryPoints,
|
|
58
65
|
resolvePlatformSpecificEntries,
|
|
66
|
+
dangerouslyIgnoreStaticEvaluationModules = [],
|
|
59
67
|
define: callerDefine,
|
|
60
68
|
...options
|
|
61
69
|
}: Props,
|
|
@@ -101,10 +109,16 @@ function getESBuildConfig(
|
|
|
101
109
|
...platformDefines,
|
|
102
110
|
...callerDefine,
|
|
103
111
|
},
|
|
112
|
+
...(platform === 'native'
|
|
113
|
+
? {
|
|
114
|
+
conditions: ['react-native'],
|
|
115
|
+
mainFields: ['react-native', 'module', 'main'],
|
|
116
|
+
}
|
|
117
|
+
: {}),
|
|
104
118
|
// for ESM: prefer "module" field for resolution, add require() shim for bundled CJS deps
|
|
105
119
|
...(detectedFormat === 'esm'
|
|
106
120
|
? {
|
|
107
|
-
mainFields: ['module', 'main'],
|
|
121
|
+
...(platform === 'web' ? { mainFields: ['module', 'main'] } : {}),
|
|
108
122
|
banner: {
|
|
109
123
|
js: 'import { createRequire as __cr } from "module"; const require = __cr(import.meta.url);',
|
|
110
124
|
},
|
|
@@ -134,6 +148,7 @@ function getESBuildConfig(
|
|
|
134
148
|
logLevel: 'warning',
|
|
135
149
|
plugins: [
|
|
136
150
|
TsconfigPathsPlugin(),
|
|
151
|
+
staticEvaluationIgnorePlugin(dangerouslyIgnoreStaticEvaluationModules),
|
|
137
152
|
|
|
138
153
|
// handle ESM-only features that can't be used with CJS output
|
|
139
154
|
{
|
|
@@ -175,19 +190,6 @@ function getESBuildConfig(
|
|
|
175
190
|
modified = true
|
|
176
191
|
}
|
|
177
192
|
|
|
178
|
-
// stub files with top-level await - they're typically runtime-only
|
|
179
|
-
if (hasTopLevelAwait(contents, args.path)) {
|
|
180
|
-
if (process.env.DEBUG?.startsWith('tamagui')) {
|
|
181
|
-
console.info(`[tamagui] stubbing file with top-level await: ${args.path}`)
|
|
182
|
-
}
|
|
183
|
-
return {
|
|
184
|
-
// Keep this as an ESM-shaped stub so esbuild doesn't inline a
|
|
185
|
-
// top-level `module.exports = {}` into the parent bundle.
|
|
186
|
-
contents: `// stubbed - contains top-level await\nexport default {}`,
|
|
187
|
-
loader: 'js',
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
193
|
if (modified) {
|
|
192
194
|
return {
|
|
193
195
|
contents,
|
|
@@ -209,10 +211,8 @@ function getESBuildConfig(
|
|
|
209
211
|
{
|
|
210
212
|
name: 'external',
|
|
211
213
|
setup(build) {
|
|
212
|
-
const proxyWormPath = require.resolve('@tamagui/proxy-worm')
|
|
213
|
-
|
|
214
214
|
// only externalize @tamagui/core and @tamagui/web - these are provided at runtime
|
|
215
|
-
// other @tamagui/* packages (like @tamagui/config/
|
|
215
|
+
// other @tamagui/* packages (like @tamagui/config/v6) must be bundled in to avoid
|
|
216
216
|
// ESM race conditions when multiple threads require() them concurrently
|
|
217
217
|
build.onResolve({ filter: /^@tamagui\/(core|web)$/ }, (args) => {
|
|
218
218
|
if (args.kind === 'entry-point') {
|
|
@@ -231,25 +231,13 @@ function getESBuildConfig(
|
|
|
231
231
|
}
|
|
232
232
|
})
|
|
233
233
|
|
|
234
|
-
build.onResolve({ filter: /^(react-native|react-native\/.*)$/ }, () => {
|
|
234
|
+
build.onResolve({ filter: /^(react-native|react-native\/.*)$/ }, (args) => {
|
|
235
235
|
return {
|
|
236
|
-
path: '@tamagui/react-native-web-lite',
|
|
236
|
+
path: args.path.replace(/^react-native/, '@tamagui/react-native-web-lite'),
|
|
237
237
|
external: true,
|
|
238
238
|
}
|
|
239
239
|
})
|
|
240
240
|
|
|
241
|
-
build.onResolve({ filter: /^react-native-reanimated(?:\/.*)?$/ }, () => {
|
|
242
|
-
return {
|
|
243
|
-
path: proxyWormPath,
|
|
244
|
-
}
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
build.onResolve({ filter: /^react-native-worklets(?:\/.*)?$/ }, () => {
|
|
248
|
-
return {
|
|
249
|
-
path: proxyWormPath,
|
|
250
|
-
}
|
|
251
|
-
})
|
|
252
|
-
|
|
253
241
|
// externalize animation libraries - not needed for static extraction
|
|
254
242
|
build.onResolve({ filter: /^(framer-motion|motion)/ }, (args) => {
|
|
255
243
|
return {
|
|
@@ -276,7 +264,7 @@ function detectEntryFormat(entryPoint: string): esbuild.BuildOptions['format'] {
|
|
|
276
264
|
}
|
|
277
265
|
// bare module specifier - check package.json type field
|
|
278
266
|
try {
|
|
279
|
-
const pkgJsonPath =
|
|
267
|
+
const pkgJsonPath = nodeRequire.resolve(entryPoint + '/package.json')
|
|
280
268
|
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'))
|
|
281
269
|
return pkg.type === 'module' ? 'esm' : 'cjs'
|
|
282
270
|
} catch {
|
|
@@ -292,12 +280,22 @@ export async function esbundleTamaguiConfig(
|
|
|
292
280
|
const config = getESBuildConfig(props, platform, aliases)
|
|
293
281
|
|
|
294
282
|
// build to memory first, then write atomically (temp file + rename)
|
|
295
|
-
// to prevent other threads from reading partially-written files
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
283
|
+
// to prevent other threads from reading partially-written files.
|
|
284
|
+
// The suffix is per call, not per process: two bundles of the same config in
|
|
285
|
+
// one process (or one worker thread) shared a temp path, and whichever
|
|
286
|
+
// renamed first left the other renaming a file that no longer existed.
|
|
287
|
+
const tmpFile = `${props.outfile}.tmp.${process.pid}-${randomBytes(6).toString('hex')}`
|
|
288
|
+
|
|
289
|
+
const result = await esbuild
|
|
290
|
+
.build({
|
|
291
|
+
...config,
|
|
292
|
+
outfile: tmpFile,
|
|
293
|
+
})
|
|
294
|
+
.catch(async (err) => {
|
|
295
|
+
// a failed build can still leave a partial temp file behind
|
|
296
|
+
await FS.remove(tmpFile).catch(() => {})
|
|
297
|
+
throw err
|
|
298
|
+
})
|
|
301
299
|
|
|
302
300
|
// atomic rename prevents other threads from reading partial files
|
|
303
301
|
await FS.rename(tmpFile, props.outfile)
|