@tamagui/build 1.61.3 → 1.62.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.
@@ -0,0 +1,42 @@
1
+ /**
2
+ * alias plugin
3
+ * @description
4
+ * config example:
5
+ * ```
6
+ * {
7
+ * '@lib': '/some/absolute/path'
8
+ * }
9
+ * ```
10
+ * then `import { something } from '@lib/xxx'` will be transformed to
11
+ * `import { something } from '/some/absolute/path/xxx'`
12
+ * @param {object} config
13
+ */
14
+ const aliasPlugin = (config) => {
15
+ const alias = config && Object.keys(config)
16
+ return {
17
+ name: 'path-alias',
18
+
19
+ setup(build) {
20
+ if (!alias || !alias.length) {
21
+ return
22
+ }
23
+ const main = (k, args) => {
24
+ const targetPath = config[k].replace(/\/$/, '')
25
+ return {
26
+ path: targetPath,
27
+ }
28
+ }
29
+
30
+ alias.forEach((k) => {
31
+ build.onResolve({ filter: new RegExp(`^.*${k}$`) }, (args) => {
32
+ return main(k, args)
33
+ })
34
+ build.onResolve({ filter: new RegExp(`^.*\\/${k}\\/.*$`) }, (args) => {
35
+ return main(k, args)
36
+ })
37
+ })
38
+ },
39
+ }
40
+ }
41
+
42
+ module.exports = aliasPlugin
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tamagui/build",
3
- "version": "1.61.3",
3
+ "version": "1.62.1",
4
4
  "bin": {
5
5
  "tamagui-build": "tamagui-build.js"
6
6
  },
package/tamagui-build.js CHANGED
@@ -8,6 +8,7 @@ const fg = require('fast-glob')
8
8
  const createExternalPlugin = require('./externalNodePlugin')
9
9
  const debounce = require('lodash.debounce')
10
10
  const { dirname } = require('path')
11
+ const alias = require('./esbuildAliasPlugin')
11
12
 
12
13
  const jsOnly = !!process.env.JS_ONLY
13
14
  const skipJS = !!(process.env.SKIP_JS || false)
@@ -15,7 +16,6 @@ const shouldSkipTypes = !!(
15
16
  process.argv.includes('--skip-types') || process.env.SKIP_TYPES
16
17
  )
17
18
  const shouldBundle = !!process.argv.includes('--bundle')
18
- const shouldIncludeMjs = !!process.argv.includes('--output-mjs')
19
19
  const shouldBundleNodeModules = !!process.argv.includes('--bundle-modules')
20
20
  const shouldClean = !!process.argv.includes('clean')
21
21
  const shouldCleanBuildOnly = !!process.argv.includes('clean:build')
@@ -24,12 +24,20 @@ const declarationToRoot = !!process.argv.includes('--declaration-root')
24
24
  const ignoreBaseUrl = process.argv.includes('--ignore-base-url')
25
25
  const baseUrlIndex = process.argv.indexOf('--base-url')
26
26
  const tsProjectIndex = process.argv.indexOf('--ts-project')
27
- const baseUrl = baseUrlIndex > -1 && process.argv[baseUrlIndex + 1] ? process.argv[baseUrlIndex + 1] : '.'
28
- const tsProject = tsProjectIndex > -1 && process.argv[tsProjectIndex + 1] ? process.argv[tsProjectIndex + 1] : null
27
+ const baseUrl =
28
+ baseUrlIndex > -1 && process.argv[baseUrlIndex + 1]
29
+ ? process.argv[baseUrlIndex + 1]
30
+ : '.'
31
+ const tsProject =
32
+ tsProjectIndex > -1 && process.argv[tsProjectIndex + 1]
33
+ ? process.argv[tsProjectIndex + 1]
34
+ : null
29
35
 
30
36
  const pkg = fs.readJSONSync('./package.json')
31
37
  let shouldSkipInitialTypes = !!process.env.SKIP_TYPES_INITIAL
32
38
  const pkgMain = pkg.main
39
+ const pkgSource = pkg.source
40
+ const bundleNative = pkg.tamagui?.bundleNative
33
41
  const pkgModule = pkg.module
34
42
  const pkgModuleJSX = pkg['module:jsx']
35
43
  const pkgTypes = Boolean(pkg['types'] || pkg['typings'])
@@ -76,9 +84,9 @@ if (shouldWatch) {
76
84
 
77
85
  // do one js build but not types
78
86
  build({
79
- skipTypes: true
87
+ skipTypes: true,
80
88
  })
81
-
89
+
82
90
  chokidar
83
91
  // prevent infinite loop but cause race condition if you just build directly
84
92
  .watch('src', {
@@ -128,7 +136,7 @@ async function buildTsc() {
128
136
  shouldSkipInitialTypes = false
129
137
  return
130
138
  }
131
-
139
+
132
140
  const targetDir = 'types'
133
141
  try {
134
142
  // typescripts build cache messes up when doing declarationOnly
@@ -140,7 +148,7 @@ async function buildTsc() {
140
148
  const tsProjectFlag = tsProject ? ` --project ${tsProject}` : ''
141
149
  const cmd = `tsc${baseUrlFlag}${tsProjectFlag} --outDir ${targetDir} --rootDir src ${declarationToRootFlag}--emitDeclarationOnly --declarationMap`
142
150
 
143
- // console.log('\x1b[2m$', `npx ${cmd}`)
151
+ console.log('\x1b[2m$', `npx ${cmd}`)
144
152
  await exec('npx', cmd.split(' '))
145
153
  } catch (err) {
146
154
  // rome-ignore lint/suspicious/noConsoleLog: <explanation>
@@ -157,117 +165,173 @@ async function buildJs() {
157
165
  if (skipJS) {
158
166
  return
159
167
  }
160
- let files = (await fg(['src/**/*.(m)?[jt]s(x)?', 'src/**/*.css'])).filter(
161
- (x) => !x.includes('.d.ts')
162
- )
168
+ let files = shouldBundle
169
+ ? [pkgSource || './src/index.ts']
170
+ : (await fg(['src/**/*.(m)?[jt]s(x)?', 'src/**/*.css'])).filter(
171
+ (x) => !x.includes('.d.ts')
172
+ )
163
173
  const externalPlugin = createExternalPlugin({
164
174
  skipNodeModulesBundle: true,
165
175
  })
166
176
 
167
177
  const external = shouldBundle ? ['@swc/*', '*.node'] : undefined
168
-
178
+
169
179
  const start = Date.now()
170
180
  return await Promise.all([
181
+ // web output to cjs
171
182
  pkgMain
172
- ? esbuildWriteIfChanged({
173
- entryPoints: files,
174
- outdir: flatOut ? 'dist' : 'dist/cjs',
175
- bundle: shouldBundle,
176
- external,
177
- sourcemap: true,
178
- sourcesContent: false,
179
- target: 'node14',
180
- keepNames: false,
181
- format: 'cjs',
182
- color: true,
183
- allowOverwrite: true,
184
- jsx: 'automatic',
185
- logLevel: 'error',
186
- plugins: shouldBundleNodeModules ? [] : [externalPlugin],
187
- minify: process.env.MINIFY ? true : false,
188
- platform: 'node',
189
- })
183
+ ? esbuildWriteIfChanged(
184
+ {
185
+ entryPoints: files,
186
+ outdir: flatOut ? 'dist' : 'dist/cjs',
187
+ bundle: shouldBundle,
188
+ external,
189
+ target: 'node18',
190
+ format: 'cjs',
191
+ jsx: 'automatic',
192
+ plugins: shouldBundleNodeModules ? [] : [externalPlugin],
193
+ minify: process.env.MINIFY ? true : false,
194
+ platform: 'node',
195
+ },
196
+ {
197
+ platform: 'web',
198
+ }
199
+ )
190
200
  : null,
191
- pkgModule
192
- ? esbuildWriteIfChanged({
193
- entryPoints: files,
194
- outdir: flatOut ? 'dist' : 'dist/esm',
195
- bundle: shouldBundle,
196
- external,
197
- sourcemap: true,
198
- sourcesContent: false,
199
- target: 'node16',
200
- keepNames: false,
201
- jsx: 'automatic',
202
- allowOverwrite: true,
203
- format: 'esm',
204
- color: true,
205
- logLevel: 'error',
206
- minify: process.env.MINIFY ? true : false,
207
- platform: shouldBundle ? 'node' : 'neutral',
208
- })
201
+
202
+ // native output to cjs
203
+ pkgMain
204
+ ? esbuildWriteIfChanged(
205
+ {
206
+ entryPoints: files,
207
+ outdir: flatOut ? 'dist' : 'dist/cjs',
208
+ bundle: shouldBundle,
209
+ external,
210
+ target: 'node18',
211
+ format: 'cjs',
212
+ jsx: 'automatic',
213
+ plugins: shouldBundleNodeModules ? [] : [externalPlugin],
214
+ minify: process.env.MINIFY ? true : false,
215
+ platform: 'node',
216
+ },
217
+ {
218
+ platform: 'native',
219
+ }
220
+ )
209
221
  : null,
210
- pkgModule && shouldIncludeMjs
211
- ? esbuildWriteIfChanged({
212
- entryPoints: files,
213
- outExtension: { '.js': '.mjs' },
214
- outdir: flatOut ? 'dist' : 'dist/esm',
215
- bundle: shouldBundle,
216
- external,
217
- sourcemap: true,
218
- sourcesContent: false,
219
- target: 'node16',
220
- keepNames: false,
221
- jsx: 'automatic',
222
- allowOverwrite: true,
223
- format: 'esm',
224
- color: true,
225
- logLevel: 'error',
226
- minify: process.env.MINIFY ? true : false,
227
- platform: shouldBundle ? 'node' : 'neutral',
228
- })
222
+
223
+ // for tests to load native-mode from node
224
+ bundleNative
225
+ ? esbuildWriteIfChanged(
226
+ {
227
+ entryPoints: [bundleNative],
228
+ outdir: 'dist',
229
+ bundle: true,
230
+ external,
231
+ target: 'node18',
232
+ format: 'cjs',
233
+ jsx: 'automatic',
234
+ plugins: [
235
+ alias({
236
+ '@tamagui/web': require.resolve('@tamagui/web/native'),
237
+ 'react-native': require.resolve('@tamagui/fake-react-native'),
238
+ 'react-native/Libraries/Pressability/Pressability': require.resolve(
239
+ '@tamagui/fake-react-native'
240
+ ),
241
+ 'react-native/Libraries/Pressability/usePressability': require.resolve(
242
+ '@tamagui/fake-react-native'
243
+ ),
244
+ 'react-native-safe-area-context': require.resolve(
245
+ '@tamagui/fake-react-native'
246
+ ),
247
+ 'react-native-gesture-handler': require.resolve('@tamagui/proxy-worm'),
248
+ }),
249
+ ],
250
+ external: ['react', 'react-dom'],
251
+ resolveExtensions: [
252
+ '.native.ts',
253
+ '.native.tsx',
254
+ '.native.js',
255
+ '.ts',
256
+ '.tsx',
257
+ '.js',
258
+ '.jsx',
259
+ ],
260
+ minify: process.env.MINIFY ? true : false,
261
+ define: {
262
+ 'process.env.TAMAGUI_IS_CORE_NODE': '"1"',
263
+ },
264
+ },
265
+ {
266
+ platform: 'native',
267
+ }
268
+ )
229
269
  : null,
230
- pkgModuleJSX && shouldIncludeMjs
231
- ? esbuildWriteIfChanged({
232
- // only diff is jsx preserve and outdir
233
- jsx: 'preserve',
234
- outdir: flatOut ? 'dist' : 'dist/jsx',
235
- outExtension: { '.js': '.mjs' },
236
- entryPoints: files,
237
- bundle: shouldBundle,
238
- external,
239
- sourcemap: true,
240
- sourcesContent: false,
241
- allowOverwrite: true,
242
- target: 'es2020',
243
- keepNames: false,
244
- format: 'esm',
245
- color: true,
246
- logLevel: 'error',
247
- minify: process.env.MINIFY ? true : false,
248
- platform: 'neutral',
249
- })
270
+
271
+ // web output to esm
272
+ pkgModule
273
+ ? esbuildWriteIfChanged(
274
+ {
275
+ entryPoints: files,
276
+ outdir: flatOut ? 'dist' : 'dist/esm',
277
+ bundle: shouldBundle,
278
+ external,
279
+ target: 'esnext',
280
+ jsx: 'automatic',
281
+ allowOverwrite: true,
282
+ format: 'esm',
283
+ minify: process.env.MINIFY ? true : false,
284
+ platform: shouldBundle ? 'node' : 'neutral',
285
+ },
286
+ {
287
+ platform: 'web',
288
+ }
289
+ )
250
290
  : null,
291
+
292
+ // jsx web
251
293
  pkgModuleJSX
252
- ? esbuildWriteIfChanged({
253
- // only diff is jsx preserve and outdir
254
- jsx: 'preserve',
255
- outdir: flatOut ? 'dist' : 'dist/jsx',
256
- entryPoints: files,
257
- bundle: shouldBundle,
258
- sourcemap: true,
259
- sourcesContent: false,
260
- allowOverwrite: true,
261
- target: 'es2020',
262
- keepNames: false,
263
- format: 'esm',
264
- color: true,
265
- logLevel: 'error',
266
- minify: process.env.MINIFY ? true : false,
267
- platform: 'neutral',
268
- })
294
+ ? esbuildWriteIfChanged(
295
+ {
296
+ // only diff is jsx preserve and outdir
297
+ jsx: 'preserve',
298
+ outdir: flatOut ? 'dist' : 'dist/jsx',
299
+ entryPoints: files,
300
+ bundle: shouldBundle,
301
+ allowOverwrite: true,
302
+ target: 'esnext',
303
+ format: 'esm',
304
+ minify: process.env.MINIFY ? true : false,
305
+ platform: 'neutral',
306
+ },
307
+ {
308
+ platform: 'web',
309
+ }
310
+ )
311
+ : null,
312
+
313
+ // jsx native
314
+ pkgModuleJSX
315
+ ? esbuildWriteIfChanged(
316
+ {
317
+ // only diff is jsx preserve and outdir
318
+ jsx: 'preserve',
319
+ outdir: flatOut ? 'dist' : 'dist/jsx',
320
+ entryPoints: files,
321
+ bundle: shouldBundle,
322
+ allowOverwrite: true,
323
+ target: 'node18',
324
+ format: 'esm',
325
+ minify: process.env.MINIFY ? true : false,
326
+ platform: 'neutral',
327
+ },
328
+ {
329
+ platform: 'native',
330
+ }
331
+ )
269
332
  : null,
270
333
  ]).then(() => {
334
+ // rome-ignore lint/suspicious/noConsoleLog: <explanation>
271
335
  if (process.env.DEBUG) console.log(`built js in ${Date.now() - start}ms`)
272
336
  })
273
337
  }
@@ -277,27 +341,112 @@ async function buildJs() {
277
341
  * @param {esbuild.BuildOptions} opts
278
342
  * @returns {Promise<void>}
279
343
  */
280
- async function esbuildWriteIfChanged(opts) {
281
- if (shouldWatch) {
282
- const built = await esbuild.build({ ...opts, write: false })
283
- if (!built.outputFiles) {
284
- return
285
- }
286
- await Promise.all(
287
- built.outputFiles.map(async (file) => {
288
- const outDir = dirname(file.path)
289
- await fs.ensureDir(outDir)
290
- const outString = new TextDecoder().decode(file.contents)
344
+ async function esbuildWriteIfChanged(
345
+ /** @type { import('esbuild').BuildOptions } */
346
+ opts,
347
+ { platform } = {
348
+ platform: '',
349
+ }
350
+ ) {
351
+ if (!shouldWatch && !platform) {
352
+ return await esbuild.build(opts)
353
+ }
354
+
355
+ const built = await esbuild.build({
356
+ ...opts,
357
+
358
+ treeShaking: true,
359
+ minifySyntax: true,
360
+ // minifyIdentifiers: true,
361
+ write: false,
362
+ color: true,
363
+ allowOverwrite: true,
364
+ color: true,
365
+ allowOverwrite: true,
366
+ keepNames: false,
367
+ sourcemap: true,
368
+ sourcesContent: false,
369
+ logLevel: 'error',
370
+
371
+ ...(platform === 'web' && {
372
+ tsconfigRaw: {
373
+ compilerOptions: {
374
+ paths: {
375
+ 'react-native': ['react-native-web'],
376
+ },
377
+ },
378
+ },
379
+ }),
380
+
381
+ define: {
382
+ ...(platform && {
383
+ 'process.env.TAMAGUI_TARGET': `"${platform}"`,
384
+ }),
385
+ ...opts.define,
386
+ },
387
+ })
388
+
389
+ if (!built.outputFiles) {
390
+ return
391
+ }
392
+
393
+ const nativeFilesMap = Object.fromEntries(
394
+ built.outputFiles.flatMap((p) => {
395
+ if (p.path.includes('.native.js')) {
396
+ return [[p.path, true]]
397
+ }
398
+ return []
399
+ })
400
+ )
401
+
402
+ await Promise.all(
403
+ built.outputFiles.map(async (file) => {
404
+ let outPath = file.path
405
+
406
+ if (outPath.endsWith('.js') || outPath.endsWith('.js.map')) {
407
+ const [_, extPlatform] =
408
+ outPath.match(/(web|native|ios|android)\.js(\.map)?$/) ?? []
409
+
410
+ if (platform === 'native') {
411
+ if (!extPlatform && nativeFilesMap[outPath.replace('.js', '.native.js')]) {
412
+ // if native exists, avoid outputting non-native
413
+ return
414
+ }
415
+
416
+ if (extPlatform === 'web') {
417
+ return
418
+ }
419
+ if (!extPlatform) {
420
+ outPath = outPath.replace('.js', '.native.js')
421
+ }
422
+ }
423
+
424
+ if (platform === 'web') {
425
+ if (
426
+ extPlatform === 'native' ||
427
+ extPlatform === 'android' ||
428
+ extPlatform === 'ios'
429
+ ) {
430
+ return
431
+ }
432
+ }
433
+ }
434
+
435
+ const outDir = dirname(outPath)
436
+
437
+ await fs.ensureDir(outDir)
438
+ const outString = new TextDecoder().decode(file.contents)
439
+
440
+ if (shouldWatch) {
291
441
  if (
292
- !(await fs.pathExists(file.path)) ||
293
- (await fs.readFile(file.path, 'utf8')) !== outString
442
+ !(await fs.pathExists(outPath)) ||
443
+ (await fs.readFile(outPath, 'utf8')) !== outString
294
444
  ) {
295
- // console.log('write', file.path)
296
- await fs.writeFile(file.path, outString)
445
+ await fs.writeFile(outPath, outString)
297
446
  }
298
- })
299
- )
300
- } else {
301
- await esbuild.build(opts)
302
- }
447
+ } else {
448
+ await fs.writeFile(outPath, outString)
449
+ }
450
+ })
451
+ )
303
452
  }