@tamagui/build 2.7.7 → 3.0.0-beta.1091.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/README.md +19 -0
- package/esbuild-es5.js +4 -0
- package/package.json +30 -7
- package/pretty-print-errors.js +0 -31
- package/tamagui-build-workspace.js +296 -0
- package/tamagui-build.js +480 -212
- package/tamagui-tsgo.js +14 -0
- package/typescript-native.js +13 -0
- package/.turbo/turbo-test$colon$web.log +0 -68
- package/.turbo/turbo-test.log +0 -44
- package/__tests__/fixtures/js-main-package/.turbo/turbo-build.log +0 -2
- package/__tests__/fixtures/js-main-package/LICENSE +0 -1
- package/__tests__/fixtures/js-main-package/dist/cjs/index.js +0 -24
- package/__tests__/fixtures/js-main-package/dist/cjs/index.js.map +0 -6
- package/__tests__/fixtures/js-main-package/dist/cjs/index.native.js +0 -31
- package/__tests__/fixtures/js-main-package/dist/cjs/index.native.js.map +0 -1
- package/__tests__/fixtures/js-main-package/dist/esm/index.mjs +0 -3
- package/__tests__/fixtures/js-main-package/dist/esm/index.mjs.map +0 -1
- package/__tests__/fixtures/js-main-package/dist/esm/index.native.js +0 -3
- package/__tests__/fixtures/js-main-package/dist/esm/index.native.js.map +0 -1
- package/__tests__/fixtures/js-main-package/package.json +0 -14
- package/__tests__/fixtures/js-main-package/src/index.ts +0 -1
- package/__tests__/fixtures/js-main-package/tsconfig.json +0 -13
- package/__tests__/fixtures/js-main-package/types/index.d.ts +0 -2
- package/__tests__/fixtures/js-main-package/types/index.d.ts.map +0 -1
- package/__tests__/fixtures/simple-package/.turbo/turbo-build.log +0 -2
- package/__tests__/fixtures/simple-package/LICENSE +0 -21
- package/__tests__/fixtures/simple-package/index.d.ts +0 -2
- package/__tests__/fixtures/simple-package/index.d.ts.map +0 -1
- package/__tests__/fixtures/simple-package/package.json +0 -25
- package/__tests__/fixtures/simple-package/src/index.ts +0 -71
- package/__tests__/fixtures/simple-package/src/nativeOnly.ts +0 -3
- package/__tests__/fixtures/simple-package/src/nested/index.ts +0 -1
- package/__tests__/fixtures/simple-package/tsconfig.json +0 -42
- package/__tests__/fixtures/subpath-only-package/.turbo/turbo-build.log +0 -3
- package/__tests__/fixtures/subpath-only-package/dist/cjs/feature.cjs +0 -25
- package/__tests__/fixtures/subpath-only-package/dist/cjs/feature.native.cjs +0 -27
- package/__tests__/fixtures/subpath-only-package/dist/cjs/feature.native.js +0 -29
- package/__tests__/fixtures/subpath-only-package/dist/cjs/feature.native.js.map +0 -1
- package/__tests__/fixtures/subpath-only-package/dist/esm/feature.mjs +0 -4
- package/__tests__/fixtures/subpath-only-package/dist/esm/feature.mjs.map +0 -1
- package/__tests__/fixtures/subpath-only-package/dist/esm/feature.native.js +0 -4
- package/__tests__/fixtures/subpath-only-package/dist/esm/feature.native.js.map +0 -1
- package/__tests__/fixtures/subpath-only-package/types/feature.d.ts.map +0 -11
- package/__tests__/fixtures/watch-package/.turbo/turbo-build.log +0 -2
- package/__tests__/fixtures/watch-package/LICENSE +0 -21
- package/__tests__/fixtures/watch-package/index.d.ts +0 -2
- package/__tests__/fixtures/watch-package/index.d.ts.map +0 -1
- package/__tests__/fixtures/watch-package/package.json +0 -22
- package/__tests__/fixtures/watch-package/src/watch.ts +0 -3
- package/__tests__/fixtures/watch-package/tsconfig.json +0 -42
- package/__tests__/fixtures/watch-package/watch.d.ts +0 -2
- package/__tests__/fixtures/watch-package/watch.d.ts.map +0 -1
- package/__tests__/integration.test.ts +0 -341
package/tamagui-build.js
CHANGED
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
* tamagui-build --swap-exports -- pnpm publish --no-git-checks
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
const { transform } = require('@babel/core')
|
|
27
26
|
const FSE = require('fs-extra')
|
|
28
27
|
const esbuild = require('esbuild')
|
|
29
28
|
const fastGlob = require('fast-glob')
|
|
@@ -34,11 +33,11 @@ const debounce = require('lodash.debounce')
|
|
|
34
33
|
const { basename, dirname } = require('node:path')
|
|
35
34
|
const { es5Plugin } = require('./esbuild-es5')
|
|
36
35
|
const { transformSync: oxcTransformSync } = require('oxc-transform')
|
|
37
|
-
const
|
|
36
|
+
const { getTsconfig } = require('get-tsconfig')
|
|
38
37
|
const path = require('node:path')
|
|
39
38
|
const childProcess = require('node:child_process')
|
|
39
|
+
const { getTypeScriptNativePath } = require('./typescript-native')
|
|
40
40
|
const {
|
|
41
|
-
printTypescriptDiagnostics,
|
|
42
41
|
printEsbuildError,
|
|
43
42
|
printBuildError,
|
|
44
43
|
printTypescriptCompilationError,
|
|
@@ -73,14 +72,18 @@ function dceTamaguiTarget(contents, { format, jsx, platform }) {
|
|
|
73
72
|
return contents
|
|
74
73
|
}
|
|
75
74
|
|
|
76
|
-
const result = oxcTransformSync(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
'
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
const result = oxcTransformSync(
|
|
76
|
+
`tamagui-target.${jsx === 'preserve' ? 'jsx' : 'js'}`,
|
|
77
|
+
contents,
|
|
78
|
+
{
|
|
79
|
+
lang: jsx === 'preserve' ? 'jsx' : 'js',
|
|
80
|
+
jsx: jsx === 'preserve' ? 'preserve' : undefined,
|
|
81
|
+
sourceType: format === 'cjs' ? 'commonjs' : 'module',
|
|
82
|
+
define: {
|
|
83
|
+
'process.env.TAMAGUI_TARGET': JSON.stringify(platform),
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
)
|
|
84
87
|
|
|
85
88
|
if (result.errors?.length) {
|
|
86
89
|
throw new Error(
|
|
@@ -270,6 +273,143 @@ async function pruneUnusedImports(contents, filePath) {
|
|
|
270
273
|
}
|
|
271
274
|
}
|
|
272
275
|
|
|
276
|
+
function resolveOutputModuleSpecifier(
|
|
277
|
+
specifier,
|
|
278
|
+
filePath,
|
|
279
|
+
outputExtension,
|
|
280
|
+
outputPaths = new Set()
|
|
281
|
+
) {
|
|
282
|
+
if (!specifier.startsWith('.') && !specifier.startsWith('/')) {
|
|
283
|
+
return specifier
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const suffixIndex = specifier.search(/[?#]/)
|
|
287
|
+
const suffix = suffixIndex === -1 ? '' : specifier.slice(suffixIndex)
|
|
288
|
+
const pathname = suffixIndex === -1 ? specifier : specifier.slice(0, suffixIndex)
|
|
289
|
+
|
|
290
|
+
const targetPath = path.resolve(path.dirname(filePath), pathname)
|
|
291
|
+
if (
|
|
292
|
+
pathname.endsWith('.js') &&
|
|
293
|
+
(outputPaths.has(targetPath) || FSE.existsSync(targetPath))
|
|
294
|
+
) {
|
|
295
|
+
const base = pathname.slice(0, -3)
|
|
296
|
+
const platformExtension = outputExtension.match(/^\.(native|web|ios|android)\./)?.[1]
|
|
297
|
+
return platformExtension && base.endsWith(`.${platformExtension}`)
|
|
298
|
+
? `${base}.js${suffix}`
|
|
299
|
+
: `${base}${outputExtension}${suffix}`
|
|
300
|
+
}
|
|
301
|
+
if (outputPaths.has(`${targetPath}.js`) || FSE.existsSync(`${targetPath}.js`)) {
|
|
302
|
+
const platformExtension = outputExtension.match(/^\.(native|web|ios|android)\./)?.[1]
|
|
303
|
+
const explicitPlatformExtension = pathname.match(/\.(native|web|ios|android)$/)?.[1]
|
|
304
|
+
let extension = outputExtension
|
|
305
|
+
if (explicitPlatformExtension && outputExtension === '.mjs') {
|
|
306
|
+
extension = '.js'
|
|
307
|
+
} else if (platformExtension && pathname.endsWith(`.${platformExtension}`)) {
|
|
308
|
+
extension = outputExtension.replace(`.${platformExtension}`, '')
|
|
309
|
+
}
|
|
310
|
+
return `${pathname}${extension}${suffix}`
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (path.extname(pathname)) {
|
|
314
|
+
return specifier
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (
|
|
318
|
+
outputPaths.has(path.join(targetPath, 'index.js')) ||
|
|
319
|
+
(FSE.existsSync(targetPath) &&
|
|
320
|
+
FSE.lstatSync(targetPath).isDirectory() &&
|
|
321
|
+
FSE.existsSync(path.join(targetPath, 'index.js')))
|
|
322
|
+
) {
|
|
323
|
+
return `${pathname.replace(/\/$/, '')}/index${outputExtension}${suffix}`
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return specifier
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
async function fullySpecifyOutputs(
|
|
330
|
+
outputs,
|
|
331
|
+
{ format, outputExtension, availableOutputPaths }
|
|
332
|
+
) {
|
|
333
|
+
const jsOutputs = outputs.filter((file) => file?.path.endsWith('.js'))
|
|
334
|
+
if (!jsOutputs.length) {
|
|
335
|
+
return new Map()
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const outputPaths = new Set([
|
|
339
|
+
...Array.from(availableOutputPaths || [], (file) => path.resolve(file)),
|
|
340
|
+
...jsOutputs.map((file) => path.resolve(file.path)),
|
|
341
|
+
])
|
|
342
|
+
const transformed = new Map()
|
|
343
|
+
|
|
344
|
+
await Promise.all(
|
|
345
|
+
jsOutputs.map(async (file) => {
|
|
346
|
+
const bundle = await rolldown({
|
|
347
|
+
input: file.path,
|
|
348
|
+
platform: 'neutral',
|
|
349
|
+
treeshake: false,
|
|
350
|
+
plugins: [
|
|
351
|
+
{
|
|
352
|
+
name: 'tamagui-build-fully-specified',
|
|
353
|
+
resolveId(id, importer) {
|
|
354
|
+
if (!importer) return id
|
|
355
|
+
const resolved = resolveOutputModuleSpecifier(
|
|
356
|
+
id,
|
|
357
|
+
file.path,
|
|
358
|
+
outputExtension,
|
|
359
|
+
outputPaths
|
|
360
|
+
)
|
|
361
|
+
return {
|
|
362
|
+
id: resolved,
|
|
363
|
+
external: true,
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
load(id) {
|
|
367
|
+
if (id === file.path) return file.contents
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
],
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
try {
|
|
374
|
+
const result = await bundle.generate({
|
|
375
|
+
format,
|
|
376
|
+
codeSplitting: false,
|
|
377
|
+
sourcemap: !shouldSkipSourceMaps,
|
|
378
|
+
comments: true,
|
|
379
|
+
minify: false,
|
|
380
|
+
polyfillRequire: false,
|
|
381
|
+
})
|
|
382
|
+
const chunk = result.output.find(
|
|
383
|
+
(output) => output.type === 'chunk' && output.facadeModuleId === file.path
|
|
384
|
+
)
|
|
385
|
+
if (!chunk) {
|
|
386
|
+
throw new Error(`rolldown did not emit ${file.path}`)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
transformed.set(file.path, {
|
|
390
|
+
code: stripRolldownRegionComments(chunk.code).replace(
|
|
391
|
+
/\n?\/\/# sourceMappingURL=.*(?:\n|$)/g,
|
|
392
|
+
''
|
|
393
|
+
),
|
|
394
|
+
map: chunk.map || null,
|
|
395
|
+
})
|
|
396
|
+
} finally {
|
|
397
|
+
await bundle.close?.()
|
|
398
|
+
}
|
|
399
|
+
})
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
return transformed
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function getFullySpecifiedOutput(outputs, filePath) {
|
|
406
|
+
const result = outputs.get(filePath)
|
|
407
|
+
if (!result) {
|
|
408
|
+
throw new Error(`rolldown did not emit ${filePath}`)
|
|
409
|
+
}
|
|
410
|
+
return result
|
|
411
|
+
}
|
|
412
|
+
|
|
273
413
|
function hasFlag(flag) {
|
|
274
414
|
return process.argv.includes(flag)
|
|
275
415
|
}
|
|
@@ -291,6 +431,7 @@ const reactCompilerPlugin = {
|
|
|
291
431
|
const isTSX = args.path.endsWith('.tsx')
|
|
292
432
|
|
|
293
433
|
try {
|
|
434
|
+
const { transform } = require('@babel/core')
|
|
294
435
|
const result = transform(source, {
|
|
295
436
|
filename: args.path,
|
|
296
437
|
configFile: false,
|
|
@@ -342,18 +483,22 @@ const shouldSkipTypes = shouldSwapExports
|
|
|
342
483
|
: !!(hasFlag('--skip-types') || process.env.SKIP_TYPES)
|
|
343
484
|
|
|
344
485
|
const shouldSkipNative = hasFlag('--skip-native')
|
|
486
|
+
// a package that hosts both platforms at runtime (the compiler evaluates
|
|
487
|
+
// modules per-platform and saves/restores process.env.TAMAGUI_TARGET) must
|
|
488
|
+
// keep its env reads live: inlining them turns its save/restore into an
|
|
489
|
+
// unconditional env flip
|
|
490
|
+
const shouldSkipTargetDCE = hasFlag('--keep-env-target')
|
|
345
491
|
const shouldSkipMJS = hasFlag('--skip-mjs')
|
|
346
492
|
const shouldSkipSourceMaps =
|
|
347
493
|
hasFlag('--skip-sourcemaps') || getEnvFlag('TAMAGUI_BUILD_SKIP_SOURCEMAPS')
|
|
348
494
|
// React Compiler is disabled by default - use --react-compiler to enable
|
|
349
|
-
const shouldEnableCompiler = !!(
|
|
350
|
-
hasFlag('--react-compiler') || process.env.REACT_COMPILER
|
|
351
|
-
)
|
|
495
|
+
const shouldEnableCompiler = !!(hasFlag('--react-compiler') || process.env.REACT_COMPILER)
|
|
352
496
|
const shouldBundleFlag = hasFlag('--bundle')
|
|
353
497
|
const shouldBundleNodeModules = hasFlag('--bundle-modules')
|
|
354
498
|
const shouldClean = !!process.argv.includes('clean')
|
|
355
499
|
const shouldCleanBuildOnly = !!process.argv.includes('clean:build')
|
|
356
500
|
const shouldWatch = hasFlag('--watch')
|
|
501
|
+
const packageBuildLock = '.tamagui-build-lock'
|
|
357
502
|
|
|
358
503
|
// get command after "--" to run with swapped exports
|
|
359
504
|
const dashDashIndex = process.argv.indexOf('--')
|
|
@@ -368,7 +513,7 @@ const exludeIndex = process.argv.indexOf('--exclude')
|
|
|
368
513
|
const baseUrl =
|
|
369
514
|
baseUrlIndex > -1 && process.argv[baseUrlIndex + 1]
|
|
370
515
|
? process.argv[baseUrlIndex + 1]
|
|
371
|
-
:
|
|
516
|
+
: null
|
|
372
517
|
const tsProject =
|
|
373
518
|
tsProjectIndex > -1 && process.argv[tsProjectIndex + 1]
|
|
374
519
|
? process.argv[tsProjectIndex + 1]
|
|
@@ -383,17 +528,25 @@ const pkgMain = pkg.main
|
|
|
383
528
|
const pkgSource = pkg.source
|
|
384
529
|
const pkgModule = pkg.module
|
|
385
530
|
const pkgModuleJSX = pkg['module:jsx']
|
|
531
|
+
const pkgBin = pkg.bin
|
|
386
532
|
const pkgTypes = Boolean(pkg.types || pkg.typings)
|
|
387
533
|
|
|
388
534
|
// build config from package.json
|
|
389
535
|
const buildConfig = pkg['tamagui-build'] || {}
|
|
536
|
+
const buildOutputs = new Set(buildConfig.outputs || [])
|
|
390
537
|
// if bundleOnly is set, only bundle those packages (old behavior)
|
|
391
538
|
// otherwise bundle ALL packages by default (new behavior)
|
|
392
539
|
const bundleOnly = buildConfig.bundleOnly || null
|
|
393
540
|
// if bundleExternal is set, always keep those packages external
|
|
394
541
|
const bundleExternal = buildConfig.bundleExternal || null
|
|
395
542
|
|
|
396
|
-
const
|
|
543
|
+
const shouldBuildCJS = Boolean(pkgMain || buildOutputs.has('cjs'))
|
|
544
|
+
const shouldBuildESM = Boolean(
|
|
545
|
+
pkgModule || buildOutputs.has('esm') || (!pkgMain && !pkgModuleJSX && pkgBin)
|
|
546
|
+
)
|
|
547
|
+
const shouldBuildTypes = Boolean(pkgTypes || buildOutputs.has('types'))
|
|
548
|
+
const flatOut =
|
|
549
|
+
[shouldBuildCJS, shouldBuildESM, Boolean(pkgModuleJSX)].filter(Boolean).length === 1
|
|
397
550
|
|
|
398
551
|
const avoidCJS = pkgMain?.endsWith('.js')
|
|
399
552
|
const getJsEntryAliasPath = (entry) => {
|
|
@@ -407,9 +560,10 @@ const getJsEntryAliasPath = (entry) => {
|
|
|
407
560
|
return null
|
|
408
561
|
}
|
|
409
562
|
const cjsMainAliasPath = getJsEntryAliasPath(pkgMain)
|
|
410
|
-
const esmAliasPaths = [
|
|
411
|
-
|
|
412
|
-
)
|
|
563
|
+
const esmAliasPaths = [
|
|
564
|
+
getJsEntryAliasPath(pkgModule),
|
|
565
|
+
getJsEntryAliasPath(pkgModuleJSX),
|
|
566
|
+
].filter(Boolean)
|
|
413
567
|
|
|
414
568
|
const replaceRNWeb = {
|
|
415
569
|
esm: (content) =>
|
|
@@ -438,7 +592,7 @@ const getProcessLabel = () => {
|
|
|
438
592
|
if (shouldSkipTypes) return labels.js
|
|
439
593
|
if (!skipJS && !jsOnly) return labels.build
|
|
440
594
|
if (jsOnly) return labels.js
|
|
441
|
-
if (!shouldSkipTypes &&
|
|
595
|
+
if (!shouldSkipTypes && shouldBuildTypes) return labels.tsc
|
|
442
596
|
|
|
443
597
|
return 'Unknown'
|
|
444
598
|
}
|
|
@@ -453,7 +607,7 @@ async function clean() {
|
|
|
453
607
|
//
|
|
454
608
|
FSE.remove('.turbo'),
|
|
455
609
|
FSE.remove('node_modules'),
|
|
456
|
-
FSE.remove('types'),
|
|
610
|
+
shouldSkipTypes ? null : FSE.remove('types'),
|
|
457
611
|
FSE.remove('dist'),
|
|
458
612
|
])
|
|
459
613
|
} catch {
|
|
@@ -480,12 +634,17 @@ if (shouldClean || shouldCleanBuildOnly) {
|
|
|
480
634
|
if (shouldWatch) {
|
|
481
635
|
process.env.IS_WATCHING = true
|
|
482
636
|
process.env.DISABLE_AUTORUN = true
|
|
483
|
-
|
|
637
|
+
let buildQueue = Promise.resolve()
|
|
638
|
+
const queueBuild = (options) => {
|
|
639
|
+
buildQueue = buildQueue.then(() => build(options))
|
|
640
|
+
return buildQueue
|
|
641
|
+
}
|
|
642
|
+
const rebuild = debounce(() => void queueBuild({ cleanOutput: false }), 100)
|
|
484
643
|
const chokidar = require('chokidar')
|
|
485
644
|
|
|
486
645
|
if (!process.env.SKIP_INITIAL_BUILD) {
|
|
487
646
|
// do one js build but not types
|
|
488
|
-
|
|
647
|
+
void queueBuild({
|
|
489
648
|
skipTypes: true,
|
|
490
649
|
cleanOutput: true,
|
|
491
650
|
})
|
|
@@ -610,37 +769,112 @@ function swapExportsTypes(pkg, direction) {
|
|
|
610
769
|
return swapped
|
|
611
770
|
}
|
|
612
771
|
|
|
613
|
-
|
|
772
|
+
function processIsRunning(pid) {
|
|
773
|
+
try {
|
|
774
|
+
process.kill(pid, 0)
|
|
775
|
+
return true
|
|
776
|
+
} catch (error) {
|
|
777
|
+
return error?.code !== 'ESRCH'
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
async function withPackageBuildLock(run) {
|
|
782
|
+
while (true) {
|
|
783
|
+
try {
|
|
784
|
+
await FSE.mkdir(packageBuildLock)
|
|
785
|
+
await FSE.writeJSON(path.join(packageBuildLock, 'owner.json'), {
|
|
786
|
+
pid: process.pid,
|
|
787
|
+
})
|
|
788
|
+
break
|
|
789
|
+
} catch (error) {
|
|
790
|
+
if (error?.code !== 'EEXIST') throw error
|
|
791
|
+
const owner = await FSE.readJSON(path.join(packageBuildLock, 'owner.json')).catch(
|
|
792
|
+
() => null
|
|
793
|
+
)
|
|
794
|
+
if (owner?.pid && !processIsRunning(owner.pid)) {
|
|
795
|
+
await FSE.remove(packageBuildLock)
|
|
796
|
+
continue
|
|
797
|
+
}
|
|
798
|
+
const stat = await FSE.stat(packageBuildLock).catch(() => null)
|
|
799
|
+
if (!owner && stat && Date.now() - stat.mtimeMs > 30_000) {
|
|
800
|
+
await FSE.remove(packageBuildLock)
|
|
801
|
+
continue
|
|
802
|
+
}
|
|
803
|
+
await new Promise((resolve) => setTimeout(resolve, 25))
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
try {
|
|
808
|
+
return await run()
|
|
809
|
+
} finally {
|
|
810
|
+
await FSE.remove(packageBuildLock)
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
async function build(options) {
|
|
815
|
+
return withPackageBuildLock(() => buildUnlocked(options))
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
async function buildUnlocked({ skipTypes, cleanOutput = !shouldWatch } = {}) {
|
|
614
819
|
if (process.env.DEBUG) console.info('🔹', pkg.name)
|
|
615
820
|
try {
|
|
616
821
|
const start = Date.now()
|
|
617
|
-
const
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
isSkippingTypesForBuild ? null : FSE.remove('types'),
|
|
623
|
-
])
|
|
822
|
+
const distBuild = {
|
|
823
|
+
available: new Set(),
|
|
824
|
+
outputs: new Set(),
|
|
825
|
+
removals: new Set(),
|
|
826
|
+
writes: new Map(),
|
|
624
827
|
}
|
|
625
828
|
|
|
829
|
+
// dist/ and types/ stay available while a build runs. Removing either up
|
|
830
|
+
// front breaks every concurrent consumer when an emit fails. Successful
|
|
831
|
+
// emits record their complete output set and prune stale files below.
|
|
832
|
+
|
|
626
833
|
const allFiles = (await fastGlob(['src/**/*.(m)?[jt]s(x)?', 'src/**/*.css'])).filter(
|
|
627
|
-
(x) =>
|
|
834
|
+
(x) =>
|
|
835
|
+
!x.includes('.d.ts') &&
|
|
836
|
+
!/(?:^|\/)(?:__tests__|tests?)(?:\/|$)/.test(x) &&
|
|
837
|
+
!/\.(?:test-d|test|spec)\.[cm]?[jt]sx?$/.test(x) &&
|
|
838
|
+
(exclude ? !x.match(exclude) : true)
|
|
628
839
|
)
|
|
629
840
|
|
|
630
|
-
await Promise.
|
|
841
|
+
const results = await Promise.allSettled([
|
|
631
842
|
//
|
|
632
843
|
skipTypes ? null : buildTsc(allFiles.filter((x) => /\.tsx?$/.test(x))),
|
|
633
|
-
buildJs(allFiles),
|
|
844
|
+
buildJs(allFiles, distBuild),
|
|
634
845
|
])
|
|
635
|
-
|
|
636
|
-
|
|
846
|
+
const failure = results.find((result) => result.status === 'rejected')
|
|
847
|
+
if (failure) {
|
|
848
|
+
throw failure.reason
|
|
849
|
+
}
|
|
637
850
|
|
|
638
851
|
// Run afterBuild script if defined
|
|
639
852
|
await runAfterBuild()
|
|
853
|
+
|
|
854
|
+
if (!skipJS) {
|
|
855
|
+
await Promise.all(
|
|
856
|
+
Array.from(distBuild.writes, ([filePath, contents]) =>
|
|
857
|
+
writeIfUnchanged(filePath, contents)
|
|
858
|
+
)
|
|
859
|
+
)
|
|
860
|
+
await Promise.all(
|
|
861
|
+
Array.from(distBuild.removals, (filePath) => FSE.remove(filePath))
|
|
862
|
+
)
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
if (cleanOutput && !skipJS) {
|
|
866
|
+
await pruneStaleOutputs(
|
|
867
|
+
'dist',
|
|
868
|
+
distBuild.outputs,
|
|
869
|
+
flatOut ? ['**/*'] : ['cjs/**/*', 'esm/**/*', 'jsx/**/*']
|
|
870
|
+
)
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
console.info('built', pkg.name, 'in', Date.now() - start, 'ms')
|
|
640
874
|
} catch (error) {
|
|
641
875
|
printBuildError(error, pkg.name, process.cwd())
|
|
642
876
|
if (!shouldWatch) {
|
|
643
|
-
|
|
877
|
+
throw error
|
|
644
878
|
}
|
|
645
879
|
}
|
|
646
880
|
}
|
|
@@ -668,7 +902,7 @@ async function runAfterBuild() {
|
|
|
668
902
|
}
|
|
669
903
|
|
|
670
904
|
async function buildTsc(allFiles) {
|
|
671
|
-
if (!
|
|
905
|
+
if (!shouldBuildTypes || jsOnly || shouldSkipTypes) return
|
|
672
906
|
if (shouldSkipInitialTypes) {
|
|
673
907
|
shouldSkipInitialTypes = false
|
|
674
908
|
return
|
|
@@ -681,18 +915,6 @@ async function buildTsc(allFiles) {
|
|
|
681
915
|
const { config, error } = await loadTsConfig()
|
|
682
916
|
if (error) throw error
|
|
683
917
|
|
|
684
|
-
// much slower
|
|
685
|
-
// if (config.options.isolatedDeclarations) {
|
|
686
|
-
// console.info(
|
|
687
|
-
// childProcess
|
|
688
|
-
// .execSync(`npx tsgo --project ./tsconfig.json --emitDeclarationOnly`)
|
|
689
|
-
// .toString()
|
|
690
|
-
// )
|
|
691
|
-
// return
|
|
692
|
-
// }
|
|
693
|
-
|
|
694
|
-
const compilerOptions = createCompilerOptions(config.options, targetDir)
|
|
695
|
-
|
|
696
918
|
if (config.options.isolatedDeclarations) {
|
|
697
919
|
const oxc = await import('oxc-transform')
|
|
698
920
|
|
|
@@ -731,134 +953,164 @@ async function buildTsc(allFiles) {
|
|
|
731
953
|
|
|
732
954
|
if (allErrors.length > 0) {
|
|
733
955
|
printOxcErrors(allErrors)
|
|
734
|
-
|
|
735
|
-
process.exit(1)
|
|
736
|
-
}
|
|
956
|
+
throw new Error('isolated declaration emit failed')
|
|
737
957
|
}
|
|
738
958
|
|
|
959
|
+
await pruneStaleDeclarations(targetDir, allFiles)
|
|
739
960
|
return
|
|
740
961
|
}
|
|
741
962
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
compilerOptions
|
|
745
|
-
)
|
|
746
|
-
|
|
747
|
-
// exit on errors
|
|
748
|
-
if (diagnostics.some((x) => x.code) && !shouldWatch) {
|
|
749
|
-
printTypescriptDiagnostics(diagnostics, ts)
|
|
750
|
-
if (shouldWatch) {
|
|
751
|
-
return
|
|
752
|
-
}
|
|
753
|
-
process.exit(1)
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
reportDiagnostics(diagnostics)
|
|
757
|
-
|
|
758
|
-
if (emitResult.emitSkipped) {
|
|
759
|
-
throw new Error('TypeScript compilation failed')
|
|
760
|
-
}
|
|
963
|
+
await emitDeclarationsWithTsgo(targetDir, allFiles)
|
|
964
|
+
await pruneStaleDeclarations(targetDir, allFiles)
|
|
761
965
|
} catch (err) {
|
|
762
966
|
printTypescriptCompilationError(err, pkg.name)
|
|
763
|
-
|
|
764
|
-
process.exit(1)
|
|
765
|
-
}
|
|
967
|
+
throw err
|
|
766
968
|
} finally {
|
|
767
969
|
await FSE.remove('tsconfig.tsbuildinfo')
|
|
768
970
|
}
|
|
769
971
|
}
|
|
770
972
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
if (configFile.error) {
|
|
787
|
-
return {
|
|
788
|
-
error: new Error(`Error reading tsconfig.json: ${configFile.error.messageText}`),
|
|
973
|
+
// dist/ and types/ are never wiped before a build, so successful emits prune
|
|
974
|
+
// files that no longer belong to the source-derived output set.
|
|
975
|
+
async function pruneStaleOutputs(targetDir, expected, patterns) {
|
|
976
|
+
const targetRoot = path.resolve(targetDir)
|
|
977
|
+
const normalize = (file) =>
|
|
978
|
+
path.relative(process.cwd(), path.resolve(file)).split(path.sep).join('/')
|
|
979
|
+
const dir = normalize(targetDir)
|
|
980
|
+
const normalizedExpected = new Set(Array.from(expected, normalize))
|
|
981
|
+
const existing = await fastGlob(
|
|
982
|
+
patterns.map((pattern) => `${dir}/${pattern}`),
|
|
983
|
+
{
|
|
984
|
+
dot: true,
|
|
985
|
+
followSymbolicLinks: false,
|
|
986
|
+
objectMode: true,
|
|
987
|
+
onlyFiles: false,
|
|
789
988
|
}
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
const parsedCommandLine = ts.parseJsonConfigFileContent(
|
|
793
|
-
configFile.config,
|
|
794
|
-
ts.sys,
|
|
795
|
-
path.dirname(configPath)
|
|
796
989
|
)
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
)
|
|
990
|
+
for (const entry of existing) {
|
|
991
|
+
if (!entry.dirent.isFile() && !entry.dirent.isSymbolicLink()) continue
|
|
992
|
+
const file = entry.path
|
|
993
|
+
if (!normalizedExpected.has(normalize(file))) {
|
|
994
|
+
const candidate = path.resolve(file)
|
|
995
|
+
if (candidate !== targetRoot && !candidate.startsWith(`${targetRoot}${path.sep}`)) {
|
|
996
|
+
throw new Error(`refusing to prune output outside ${targetDir}: ${file}`)
|
|
997
|
+
}
|
|
998
|
+
await FSE.unlink(candidate)
|
|
803
999
|
}
|
|
804
1000
|
}
|
|
805
|
-
|
|
806
|
-
cachedConfig = { config: parsedCommandLine }
|
|
807
|
-
return cachedConfig
|
|
808
1001
|
}
|
|
809
1002
|
|
|
810
|
-
function
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
1003
|
+
async function pruneStaleDeclarations(targetDir, allFiles) {
|
|
1004
|
+
if (declarationToRoot) return
|
|
1005
|
+
// fast-glob echoes the pattern's leading "./" back in its results, so both
|
|
1006
|
+
// sides are normalized before comparison — mismatched prefixes here would
|
|
1007
|
+
// prune every declaration in the package.
|
|
1008
|
+
const normalize = (p) => p.replace(/^\.\//, '')
|
|
1009
|
+
const dir = normalize(targetDir)
|
|
1010
|
+
const expected = new Set()
|
|
1011
|
+
for (const file of allFiles) {
|
|
1012
|
+
const base = path.join(dir, ...file.split('/').slice(1)).replace(/\.tsx?$/, '')
|
|
1013
|
+
expected.add(`${base}.d.ts`)
|
|
1014
|
+
expected.add(`${base}.d.ts.map`)
|
|
820
1015
|
}
|
|
1016
|
+
await pruneStaleOutputs(dir, expected, ['**/*.d.ts', '**/*.d.ts.map'])
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
async function emitDeclarationsWithTsgo(targetDir, allFiles) {
|
|
1020
|
+
const tsgoPath = getTypeScriptNativePath()
|
|
1021
|
+
const declarationProject = `.tamagui-build-tsconfig-${process.pid}.json`
|
|
1022
|
+
const sourceProject = path
|
|
1023
|
+
.relative(process.cwd(), path.resolve(tsProject || 'tsconfig.json'))
|
|
1024
|
+
.replaceAll(path.sep, '/')
|
|
1025
|
+
await FSE.writeJSON(
|
|
1026
|
+
declarationProject,
|
|
1027
|
+
{
|
|
1028
|
+
extends: sourceProject.startsWith('.') ? sourceProject : `./${sourceProject}`,
|
|
1029
|
+
files: allFiles,
|
|
1030
|
+
include: [],
|
|
1031
|
+
exclude: [],
|
|
1032
|
+
},
|
|
1033
|
+
{ spaces: 2 }
|
|
1034
|
+
)
|
|
1035
|
+
await FSE.remove('tsconfig.tsbuildinfo')
|
|
1036
|
+
const args = [
|
|
1037
|
+
'--project',
|
|
1038
|
+
declarationProject,
|
|
1039
|
+
'--declaration',
|
|
1040
|
+
'--emitDeclarationOnly',
|
|
1041
|
+
'--declarationMap',
|
|
1042
|
+
String(!shouldSkipSourceMaps),
|
|
1043
|
+
'--outDir',
|
|
1044
|
+
targetDir,
|
|
1045
|
+
'--rootDir',
|
|
1046
|
+
'src',
|
|
1047
|
+
'--tsBuildInfoFile',
|
|
1048
|
+
'tsconfig.tsbuildinfo',
|
|
1049
|
+
]
|
|
821
1050
|
|
|
822
1051
|
if (declarationToRoot) {
|
|
823
|
-
|
|
1052
|
+
args.push('--declarationDir', './')
|
|
1053
|
+
}
|
|
1054
|
+
if (!ignoreBaseUrl && baseUrl) {
|
|
1055
|
+
args.push('--baseUrl', path.resolve(baseUrl))
|
|
824
1056
|
}
|
|
825
1057
|
|
|
826
|
-
|
|
827
|
-
|
|
1058
|
+
try {
|
|
1059
|
+
await new Promise((resolve, reject) => {
|
|
1060
|
+
const child = childProcess.spawn(tsgoPath, args, { stdio: 'inherit' })
|
|
1061
|
+
child.once('error', reject)
|
|
1062
|
+
child.once('exit', (code, signal) => {
|
|
1063
|
+
if (code === 0) {
|
|
1064
|
+
resolve()
|
|
1065
|
+
return
|
|
1066
|
+
}
|
|
1067
|
+
reject(
|
|
1068
|
+
new Error(
|
|
1069
|
+
signal
|
|
1070
|
+
? `TypeScript native declaration emit stopped by ${signal}`
|
|
1071
|
+
: `TypeScript native declaration emit exited with code ${code}`
|
|
1072
|
+
)
|
|
1073
|
+
)
|
|
1074
|
+
})
|
|
1075
|
+
})
|
|
1076
|
+
} finally {
|
|
1077
|
+
await FSE.remove(declarationProject)
|
|
828
1078
|
}
|
|
829
1079
|
|
|
830
|
-
|
|
1080
|
+
const declarationRoot = declarationToRoot ? '.' : targetDir
|
|
1081
|
+
await Promise.all(
|
|
1082
|
+
allFiles.map(async (file) => {
|
|
1083
|
+
const relativeFile = path.relative(path.resolve('src'), path.resolve(file))
|
|
1084
|
+
const declarationPath = path
|
|
1085
|
+
.join(declarationRoot, relativeFile)
|
|
1086
|
+
.replace(/\.tsx?$/, '.d.ts')
|
|
1087
|
+
const output = await FSE.readFile(declarationPath, 'utf8')
|
|
1088
|
+
const normalized = output.replace(
|
|
1089
|
+
/(["'])@tamagui\/([^/"']+)\/types\1/g,
|
|
1090
|
+
'$1@tamagui/$2$1'
|
|
1091
|
+
)
|
|
1092
|
+
if (normalized !== output) {
|
|
1093
|
+
await writeIfUnchanged(declarationPath, normalized)
|
|
1094
|
+
}
|
|
1095
|
+
})
|
|
1096
|
+
)
|
|
831
1097
|
}
|
|
832
1098
|
|
|
833
|
-
async function
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
return { program, emitResult, diagnostics: allDiagnostics }
|
|
839
|
-
}
|
|
1099
|
+
async function loadTsConfig() {
|
|
1100
|
+
if (cachedConfig && shouldWatch) {
|
|
1101
|
+
return cachedConfig
|
|
1102
|
+
}
|
|
840
1103
|
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
}
|
|
1104
|
+
const result = getTsconfig(process.cwd(), tsProject || 'tsconfig.json')
|
|
1105
|
+
if (!result) {
|
|
1106
|
+
return { error: new Error("Could not find a valid 'tsconfig.json'.") }
|
|
1107
|
+
}
|
|
846
1108
|
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')
|
|
850
|
-
if (diagnostic.file && diagnostic.start !== undefined) {
|
|
851
|
-
const { line, character } = ts.getLineAndCharacterOfPosition(
|
|
852
|
-
diagnostic.file,
|
|
853
|
-
diagnostic.start
|
|
854
|
-
)
|
|
855
|
-
message = `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
|
|
856
|
-
}
|
|
857
|
-
console.error(message)
|
|
858
|
-
})
|
|
1109
|
+
cachedConfig = { config: { options: result.config.compilerOptions || {} } }
|
|
1110
|
+
return cachedConfig
|
|
859
1111
|
}
|
|
860
1112
|
|
|
861
|
-
async function buildJs(allFiles) {
|
|
1113
|
+
async function buildJs(allFiles, distBuild) {
|
|
862
1114
|
if (skipJS) {
|
|
863
1115
|
return
|
|
864
1116
|
}
|
|
@@ -966,38 +1218,42 @@ async function buildJs(allFiles) {
|
|
|
966
1218
|
}
|
|
967
1219
|
}
|
|
968
1220
|
|
|
969
|
-
|
|
1221
|
+
const results = await Promise.allSettled([
|
|
970
1222
|
// web output to cjs
|
|
971
|
-
|
|
1223
|
+
shouldBuildCJS
|
|
972
1224
|
? esbuildWriteIfChanged(cjsConfigWeb, {
|
|
973
1225
|
platform: 'web',
|
|
974
1226
|
bundle: shouldBundleFlag,
|
|
975
1227
|
specifyCJS: !avoidCJS,
|
|
976
1228
|
keepJsOutput: avoidCJS,
|
|
977
1229
|
preserveJsPaths: [],
|
|
1230
|
+
distBuild,
|
|
978
1231
|
})
|
|
979
1232
|
: null,
|
|
980
1233
|
|
|
981
1234
|
// native output to cjs
|
|
982
|
-
|
|
1235
|
+
shouldBuildCJS && !shouldSkipNative
|
|
983
1236
|
? esbuildWriteIfChanged(cjsConfig, {
|
|
984
1237
|
platform: 'native',
|
|
1238
|
+
distBuild,
|
|
985
1239
|
})
|
|
986
1240
|
: null,
|
|
987
1241
|
|
|
988
1242
|
// web output to esm
|
|
989
|
-
|
|
1243
|
+
shouldBuildESM
|
|
990
1244
|
? esbuildWriteIfChanged(esmConfig, {
|
|
991
1245
|
platform: 'web',
|
|
992
1246
|
bundle: shouldBundleFlag,
|
|
993
1247
|
preserveJsPaths: esmAliasPaths,
|
|
1248
|
+
distBuild,
|
|
994
1249
|
})
|
|
995
1250
|
: null,
|
|
996
1251
|
|
|
997
1252
|
// native output to esm
|
|
998
|
-
|
|
1253
|
+
shouldBuildESM && !shouldSkipNative
|
|
999
1254
|
? esbuildWriteIfChanged(esmConfig, {
|
|
1000
1255
|
platform: 'native',
|
|
1256
|
+
distBuild,
|
|
1001
1257
|
})
|
|
1002
1258
|
: null,
|
|
1003
1259
|
|
|
@@ -1019,6 +1275,7 @@ async function buildJs(allFiles) {
|
|
|
1019
1275
|
{
|
|
1020
1276
|
platform: 'web',
|
|
1021
1277
|
preserveJsPaths: esmAliasPaths,
|
|
1278
|
+
distBuild,
|
|
1022
1279
|
}
|
|
1023
1280
|
)
|
|
1024
1281
|
: null,
|
|
@@ -1040,16 +1297,20 @@ async function buildJs(allFiles) {
|
|
|
1040
1297
|
},
|
|
1041
1298
|
{
|
|
1042
1299
|
platform: 'native',
|
|
1300
|
+
distBuild,
|
|
1043
1301
|
}
|
|
1044
1302
|
)
|
|
1045
1303
|
: null,
|
|
1046
|
-
])
|
|
1047
|
-
if (process.env.DEBUG) {
|
|
1048
|
-
console.info(`built js in ${Date.now() - start}ms`)
|
|
1049
|
-
}
|
|
1304
|
+
])
|
|
1050
1305
|
|
|
1051
|
-
|
|
1052
|
-
|
|
1306
|
+
void esbuild.stop()
|
|
1307
|
+
const failure = results.find((result) => result.status === 'rejected')
|
|
1308
|
+
if (failure) {
|
|
1309
|
+
throw failure.reason
|
|
1310
|
+
}
|
|
1311
|
+
if (process.env.DEBUG) {
|
|
1312
|
+
console.info(`built js in ${Date.now() - start}ms`)
|
|
1313
|
+
}
|
|
1053
1314
|
}
|
|
1054
1315
|
|
|
1055
1316
|
/**
|
|
@@ -1060,12 +1321,18 @@ async function buildJs(allFiles) {
|
|
|
1060
1321
|
async function esbuildWriteIfChanged(
|
|
1061
1322
|
/** @type { import('esbuild').BuildOptions } */
|
|
1062
1323
|
opts,
|
|
1063
|
-
{ platform, env, specifyCJS, keepJsOutput, preserveJsPaths } = {
|
|
1324
|
+
{ platform, env, specifyCJS, keepJsOutput, preserveJsPaths, distBuild } = {
|
|
1064
1325
|
platform: '',
|
|
1065
1326
|
specifyCJS: false,
|
|
1066
1327
|
keepJsOutput: false,
|
|
1067
1328
|
preserveJsPaths: [],
|
|
1068
1329
|
env: '',
|
|
1330
|
+
distBuild: {
|
|
1331
|
+
available: new Set(),
|
|
1332
|
+
outputs: new Set(),
|
|
1333
|
+
removals: new Set(),
|
|
1334
|
+
writes: new Map(),
|
|
1335
|
+
},
|
|
1069
1336
|
}
|
|
1070
1337
|
) {
|
|
1071
1338
|
if (!platform) {
|
|
@@ -1163,9 +1430,7 @@ async function esbuildWriteIfChanged(
|
|
|
1163
1430
|
built = await esbuild.build(buildSettings)
|
|
1164
1431
|
} catch (err) {
|
|
1165
1432
|
printEsbuildError(err)
|
|
1166
|
-
|
|
1167
|
-
process.exit(1)
|
|
1168
|
-
}
|
|
1433
|
+
throw err
|
|
1169
1434
|
}
|
|
1170
1435
|
|
|
1171
1436
|
if (!built.outputFiles) {
|
|
@@ -1176,6 +1441,7 @@ async function esbuildWriteIfChanged(
|
|
|
1176
1441
|
const webFilesMap = {}
|
|
1177
1442
|
|
|
1178
1443
|
for (const p of built.outputFiles) {
|
|
1444
|
+
distBuild.available.add(p.path)
|
|
1179
1445
|
if (p.path.includes('.native.js')) {
|
|
1180
1446
|
nativeFilesMap[p.path] = true
|
|
1181
1447
|
} else if (p.path.includes('.web.js')) {
|
|
@@ -1186,7 +1452,15 @@ async function esbuildWriteIfChanged(
|
|
|
1186
1452
|
const cleanupNonMjsFiles = []
|
|
1187
1453
|
const cleanupNonCjsFiles = []
|
|
1188
1454
|
|
|
1189
|
-
const flush =
|
|
1455
|
+
const flush = (filePath, contents) => {
|
|
1456
|
+
distBuild.outputs.add(filePath)
|
|
1457
|
+
distBuild.removals.delete(filePath)
|
|
1458
|
+
distBuild.writes.set(filePath, contents)
|
|
1459
|
+
}
|
|
1460
|
+
const remove = (filePath) => {
|
|
1461
|
+
distBuild.writes.delete(filePath)
|
|
1462
|
+
distBuild.removals.add(filePath)
|
|
1463
|
+
}
|
|
1190
1464
|
|
|
1191
1465
|
const outputs = (
|
|
1192
1466
|
await Promise.all(
|
|
@@ -1244,23 +1518,24 @@ async function esbuildWriteIfChanged(
|
|
|
1244
1518
|
}
|
|
1245
1519
|
|
|
1246
1520
|
if (!isMap && path.endsWith('.js')) {
|
|
1247
|
-
const hadTamaguiTarget =
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1521
|
+
const hadTamaguiTarget =
|
|
1522
|
+
!shouldSkipTargetDCE && contents.includes('process.env.TAMAGUI_TARGET')
|
|
1523
|
+
if (!shouldSkipTargetDCE) {
|
|
1524
|
+
contents = dceTamaguiTarget(contents, {
|
|
1525
|
+
format: opts.format,
|
|
1526
|
+
jsx: opts.jsx,
|
|
1527
|
+
platform,
|
|
1528
|
+
})
|
|
1529
|
+
}
|
|
1253
1530
|
|
|
1254
1531
|
if (isESM && hadTamaguiTarget) {
|
|
1255
1532
|
contents = await pruneUnusedImports(contents, path)
|
|
1256
1533
|
}
|
|
1257
1534
|
|
|
1258
|
-
// esbuild
|
|
1259
|
-
//
|
|
1260
|
-
//
|
|
1261
|
-
|
|
1262
|
-
// native instead of crashing at runtime (e.g. toast PanResponder).
|
|
1263
|
-
if (platform === 'native' && isESM) {
|
|
1535
|
+
// expose esbuild's require shim so rolldown can resolve and rewrite local
|
|
1536
|
+
// specifiers. rolldown restores the shim for web esm, while the native output
|
|
1537
|
+
// below keeps a real require for metro.
|
|
1538
|
+
if (isESM) {
|
|
1264
1539
|
contents = contents.replaceAll('__require(', 'require(')
|
|
1265
1540
|
}
|
|
1266
1541
|
}
|
|
@@ -1317,6 +1592,14 @@ async function esbuildWriteIfChanged(
|
|
|
1317
1592
|
)
|
|
1318
1593
|
|
|
1319
1594
|
if (specifyCJS) {
|
|
1595
|
+
const transformedOutputs = opts.bundle
|
|
1596
|
+
? new Map()
|
|
1597
|
+
: await fullySpecifyOutputs(outputs, {
|
|
1598
|
+
format: 'cjs',
|
|
1599
|
+
outputExtension: platform === 'native' ? '.native.cjs' : '.cjs',
|
|
1600
|
+
availableOutputPaths: distBuild.available,
|
|
1601
|
+
})
|
|
1602
|
+
|
|
1320
1603
|
await Promise.all(
|
|
1321
1604
|
outputs.map(async (file) => {
|
|
1322
1605
|
if (!file) return
|
|
@@ -1325,19 +1608,7 @@ async function esbuildWriteIfChanged(
|
|
|
1325
1608
|
|
|
1326
1609
|
const result = opts.bundle
|
|
1327
1610
|
? { code: contents }
|
|
1328
|
-
:
|
|
1329
|
-
filename: path,
|
|
1330
|
-
configFile: false,
|
|
1331
|
-
sourceMap: !shouldSkipSourceMaps,
|
|
1332
|
-
plugins: [
|
|
1333
|
-
[
|
|
1334
|
-
require.resolve('@tamagui/babel-plugin-fully-specified/commonjs'),
|
|
1335
|
-
{
|
|
1336
|
-
esExtensionDefault: platform === 'native' ? '.native.cjs' : '.cjs',
|
|
1337
|
-
},
|
|
1338
|
-
],
|
|
1339
|
-
].filter(Boolean),
|
|
1340
|
-
})
|
|
1611
|
+
: getFullySpecifiedOutput(transformedOutputs, path)
|
|
1341
1612
|
|
|
1342
1613
|
const shouldPreserveJsAlias =
|
|
1343
1614
|
preserveJsPathSet.has(path) || preserveJsPathAbsoluteSet.has(path)
|
|
@@ -1355,7 +1626,7 @@ async function esbuildWriteIfChanged(
|
|
|
1355
1626
|
})
|
|
1356
1627
|
)
|
|
1357
1628
|
if (cleanupNonCjsFiles.length) {
|
|
1358
|
-
|
|
1629
|
+
for (const file of cleanupNonCjsFiles) remove(file)
|
|
1359
1630
|
}
|
|
1360
1631
|
return
|
|
1361
1632
|
}
|
|
@@ -1369,6 +1640,14 @@ async function esbuildWriteIfChanged(
|
|
|
1369
1640
|
return
|
|
1370
1641
|
}
|
|
1371
1642
|
|
|
1643
|
+
const transformedOutputs = opts.bundle
|
|
1644
|
+
? new Map()
|
|
1645
|
+
: await fullySpecifyOutputs(outputs, {
|
|
1646
|
+
format: isESM ? 'esm' : 'cjs',
|
|
1647
|
+
outputExtension: platform === 'native' ? '.native.js' : '.mjs',
|
|
1648
|
+
availableOutputPaths: distBuild.available,
|
|
1649
|
+
})
|
|
1650
|
+
|
|
1372
1651
|
await Promise.all(
|
|
1373
1652
|
outputs.map(async (file) => {
|
|
1374
1653
|
if (!file) return
|
|
@@ -1384,22 +1663,15 @@ async function esbuildWriteIfChanged(
|
|
|
1384
1663
|
// and babel is bad on huge bundled files
|
|
1385
1664
|
const result = opts.bundle
|
|
1386
1665
|
? { code: contents }
|
|
1387
|
-
:
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
{
|
|
1397
|
-
esExtensionDefault: platform === 'native' ? '.native.js' : '.mjs',
|
|
1398
|
-
esExtensions: platform === 'native' ? ['.js'] : ['.mjs'],
|
|
1399
|
-
},
|
|
1400
|
-
],
|
|
1401
|
-
].filter(Boolean),
|
|
1402
|
-
})
|
|
1666
|
+
: getFullySpecifiedOutput(transformedOutputs, path)
|
|
1667
|
+
|
|
1668
|
+
if (platform === 'native' && isESM) {
|
|
1669
|
+
result.code = result.code.replace(/\b__require(?:\$\d+)?\(/g, 'require(')
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
if (platform === 'native' && !isESM && !avoidCJS) {
|
|
1673
|
+
await flush(path.replace(/\.js$/, '.cjs'), result.code)
|
|
1674
|
+
}
|
|
1403
1675
|
|
|
1404
1676
|
const shouldPreserveJsAlias =
|
|
1405
1677
|
preserveJsPathSet.has(path) || preserveJsPathAbsoluteSet.has(path)
|
|
@@ -1420,7 +1692,7 @@ async function esbuildWriteIfChanged(
|
|
|
1420
1692
|
if (result.map && !shouldSkipSourceMaps) {
|
|
1421
1693
|
await flush(newOutPath + '.map', JSON.stringify(result.map))
|
|
1422
1694
|
} else {
|
|
1423
|
-
|
|
1695
|
+
remove(newOutPath + '.map')
|
|
1424
1696
|
}
|
|
1425
1697
|
|
|
1426
1698
|
if (shouldPreserveJsAlias) {
|
|
@@ -1434,7 +1706,7 @@ async function esbuildWriteIfChanged(
|
|
|
1434
1706
|
if (result.map && !shouldSkipSourceMaps) {
|
|
1435
1707
|
await flush(path + '.map', JSON.stringify(result.map))
|
|
1436
1708
|
} else {
|
|
1437
|
-
|
|
1709
|
+
remove(path + '.map')
|
|
1438
1710
|
}
|
|
1439
1711
|
}
|
|
1440
1712
|
})
|
|
@@ -1442,10 +1714,6 @@ async function esbuildWriteIfChanged(
|
|
|
1442
1714
|
|
|
1443
1715
|
// remove intermediary .js files once the final .mjs/.cjs outputs exist
|
|
1444
1716
|
if (cleanupNonMjsFiles.length || cleanupNonCjsFiles.length) {
|
|
1445
|
-
|
|
1446
|
-
[...cleanupNonMjsFiles, ...cleanupNonCjsFiles].map(async (file) => {
|
|
1447
|
-
await FSE.remove(file)
|
|
1448
|
-
})
|
|
1449
|
-
)
|
|
1717
|
+
for (const file of [...cleanupNonMjsFiles, ...cleanupNonCjsFiles]) remove(file)
|
|
1450
1718
|
}
|
|
1451
1719
|
}
|