@tamagui/vite-plugin 1.52.9 → 1.53.0

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.
@@ -1,23 +1,22 @@
1
- import { esbuildFlowPlugin } from '@bunchtogether/vite-plugin-flow'
1
+ import { readFile } from 'fs/promises'
2
+ import { dirname } from 'path'
3
+
4
+ import { transform } from '@swc/core'
5
+ import { parse } from 'es-module-lexer'
2
6
  import { OutputOptions } from 'rollup'
3
7
  import type { Plugin } from 'vite'
8
+ import { viteExternalsPlugin } from 'vite-plugin-externals'
4
9
 
5
10
  import { extensions } from './extensions'
11
+ import { getVitePath } from './getVitePath'
12
+ import { prebuiltFiles } from './nativePrebuild'
6
13
 
7
- export function nativePlugin(options: { port: number }): Plugin {
14
+ export function nativePlugin(options: { port: number; mode: 'build' | 'serve' }): Plugin {
8
15
  return {
9
16
  name: 'tamagui-native',
10
17
  enforce: 'post',
11
18
 
12
19
  config: (config) => {
13
- // // add hmr client
14
- // config.plugins.push({
15
- // name: 'add-hmr-client',
16
- // generateBundle(x) {
17
- // x.
18
- // }
19
- // })
20
-
21
20
  config.define ||= {}
22
21
  config.define['process.env.REACT_NATIVE_SERVER_PUBLIC_PORT'] = JSON.stringify(
23
22
  `${options.port}`
@@ -42,46 +41,33 @@ export function nativePlugin(options: { port: number }): Plugin {
42
41
 
43
42
  config.resolve.extensions = extensions
44
43
 
45
- // config.resolve.alias ??= {}
46
- // config.resolve.alias = {
47
- // ...config.resolve.alias,
48
- // // 'react-native/Libraries/Renderer/shims/ReactFabric':
49
- // // 'react-native/Libraries/Renderer/shims/ReactFabric',
50
- // // 'react-native/Libraries/Utilities/codegenNativeComponent':
51
- // // 'react-native/Libraries/Utilities/codegenNativeComponent',
52
- // // 'react-native-svg': 'react-native-svg',
53
- // // // 'react-native-web': 'react-native',
54
- // // 'react-native': 'react-native',
55
- // }
56
-
57
44
  config.optimizeDeps ??= {}
58
45
 
59
- // externals
60
- // breaks
61
- // config.optimizeDeps.exclude ??= []
62
- // config.optimizeDeps.exclude.push('react-native')
46
+ config.optimizeDeps.disabled = true
63
47
 
64
- config.optimizeDeps.needsInterop ??= []
65
- config.optimizeDeps.needsInterop.push('react-native')
48
+ // config.optimizeDeps.needsInterop ??= []
49
+ // config.optimizeDeps.needsInterop.push('react-native')
50
+
51
+ // config.esbuild = false
66
52
 
67
53
  config.optimizeDeps.esbuildOptions ??= {}
68
54
  config.optimizeDeps.esbuildOptions.resolveExtensions = extensions
69
55
 
70
56
  config.optimizeDeps.esbuildOptions.plugins ??= []
71
57
 
72
- config.optimizeDeps.esbuildOptions.plugins.push(
73
- esbuildFlowPlugin(
74
- /node_modules\/(react-native\/|@react-native\/)/,
75
- (_) => 'jsx',
76
- {
77
- all: true,
78
- }
79
- )
80
- )
81
- // config.optimizeDeps.esbuildOptions.plugins.push(esbuildCommonjs(['react-native']))
82
-
83
- config.optimizeDeps.include ??= []
84
- config.optimizeDeps.include.push('react-native')
58
+ config.optimizeDeps.esbuildOptions.alias = {
59
+ 'react-native': '@tamagui/proxy-worm'
60
+ }
61
+
62
+ // config.optimizeDeps.esbuildOptions.plugins.push(
63
+ // esbuildFlowPlugin(
64
+ // /node_modules\/(react-native\/|@react-native\/)/,
65
+ // (_) => 'jsx',
66
+ // {
67
+ // all: true,
68
+ // }
69
+ // )
70
+ // )
85
71
 
86
72
  config.optimizeDeps.esbuildOptions.loader ??= {}
87
73
  config.optimizeDeps.esbuildOptions.loader['.js'] = 'jsx'
@@ -111,17 +97,152 @@ export function nativePlugin(options: { port: number }): Plugin {
111
97
 
112
98
  config.build.rollupOptions.plugins ??= []
113
99
 
114
- config.build.rollupOptions.external = [
115
- 'react-native',
116
- 'react',
117
- 'react/jsx-runtime',
118
- 'react/jsx-dev-runtime',
119
- ]
100
+ if (options.mode === 'serve') {
101
+ config.build.rollupOptions.external = [
102
+ 'react-native',
103
+ 'react',
104
+ 'react/jsx-runtime',
105
+ 'react/jsx-dev-runtime',
106
+ ]
107
+ }
120
108
 
121
109
  if (!Array.isArray(config.build.rollupOptions.plugins)) {
122
110
  throw `x`
123
111
  }
124
112
 
113
+ if (options.mode === 'build') {
114
+ config.build.rollupOptions.plugins.push({
115
+ name: `swap-react-native`,
116
+
117
+ async load(id) {
118
+ if (id.endsWith('/react-native/index.js')) {
119
+ const bundled = await readFile(prebuiltFiles.reactNative, 'utf-8')
120
+ const code = `
121
+ const run = () => {
122
+ ${bundled
123
+ .replace(
124
+ `module.exports = require_react_native();`,
125
+ `return require_react_native();`
126
+ )
127
+ .replace(
128
+ `var require_jsx_runtime = `,
129
+ `var require_jsx_runtime = global['__JSX__'] = `
130
+ )
131
+ .replace(
132
+ `var require_react = `,
133
+ `var require_react = global['__React__'] = `
134
+ )}
135
+ }
136
+ const RN = run()
137
+ ${RNExportNames.map((n) => `export const ${n} = RN.${n}`).join('\n')}
138
+ `
139
+ return {
140
+ code,
141
+ }
142
+ }
143
+ },
144
+ })
145
+
146
+ config.build.rollupOptions.plugins.push(
147
+ viteExternalsPlugin(
148
+ {
149
+ react: '____react____',
150
+ 'react/jsx-runtime': '____jsx____',
151
+ 'react/jsx-dev-runtime': '____jsx____',
152
+ },
153
+ {
154
+ useWindow: false,
155
+ }
156
+ )
157
+ )
158
+
159
+ config.build.rollupOptions.plugins.push({
160
+ name: `force-export-all`,
161
+
162
+ async transform(code, id) {
163
+ const [imports, exports] = parse(code)
164
+
165
+ let forceExports = ''
166
+
167
+ // note that es-module-lexer parses export * from as an import (twice) for some reason
168
+ let counts = {}
169
+ for (const imp of imports) {
170
+ if (imp.n && imp.n[0] !== '.') {
171
+ counts[imp.n] ||= 0
172
+ counts[imp.n]++
173
+ if (counts[imp.n] == 2) {
174
+ // star export
175
+ const path = await getVitePath(dirname(id), imp.n)
176
+ forceExports += `Object.assign(exports, require("${path}"));`
177
+ }
178
+ }
179
+ }
180
+
181
+ forceExports += exports
182
+ .map((e) => {
183
+ if (e.n === 'default') {
184
+ return ''
185
+ }
186
+ let out = ''
187
+ if (e.ln !== e.n) {
188
+ // forces the "as x" to be referenced so it gets exported
189
+ out += `__ignore = typeof ${e.n} === 'undefined' ? 0 : 0;`
190
+ }
191
+ out += `globalThis.____forceExport = ${e.ln}`
192
+ return out
193
+ })
194
+ .join(';')
195
+
196
+ return code + '\n' + forceExports
197
+ },
198
+ })
199
+
200
+ config.build.rollupOptions.plugins.push({
201
+ name: `native-transform`,
202
+
203
+ async transform(code, id) {
204
+ if (
205
+ id.includes(`node_modules/react/jsx-dev-runtime.js`) ||
206
+ id.includes(`node_modules/react/index.js`) ||
207
+ id.includes(`node_modules/react/cjs/react.development.js`) ||
208
+ id.includes(`node_modules/react-native/index.js`) ||
209
+ id.includes(
210
+ `node_modules/react/cjs/react-jsx-dev-runtime.development.js`
211
+ ) ||
212
+ id.includes(`packages/vite-native-client/`)
213
+ ) {
214
+ return
215
+ }
216
+
217
+ let out = await transform(code, {
218
+ filename: id,
219
+ swcrc: false,
220
+ configFile: false,
221
+ sourceMaps: true,
222
+ jsc: {
223
+ target: 'es5',
224
+ parser: id.endsWith('.tsx')
225
+ ? { syntax: 'typescript', tsx: true, decorators: true }
226
+ : id.endsWith('.ts')
227
+ ? { syntax: 'typescript', tsx: false, decorators: true }
228
+ : id.endsWith('.jsx')
229
+ ? { syntax: 'ecmascript', jsx: true }
230
+ : { syntax: 'ecmascript' },
231
+ transform: {
232
+ useDefineForClassFields: true,
233
+ react: {
234
+ development: true,
235
+ runtime: 'automatic',
236
+ },
237
+ },
238
+ },
239
+ })
240
+
241
+ return out
242
+ },
243
+ })
244
+ }
245
+
125
246
  if (process.env.DEBUG) {
126
247
  console.log('config..', config)
127
248
  }
@@ -131,8 +252,14 @@ export function nativePlugin(options: { port: number }): Plugin {
131
252
  }
132
253
 
133
254
  const updateOutputOptions = (out: OutputOptions) => {
255
+ out.preserveModules = true
256
+
257
+ out.entryFileNames = (chunkInfo) => {
258
+ // ensures we have clean names for our require paths
259
+ return '[name].js'
260
+ }
134
261
  // Ensure that as many resources as possible are inlined.
135
- out.inlineDynamicImports = true
262
+ // out.inlineDynamicImports = true
136
263
 
137
264
  // added by me (nate):
138
265
  out.manualChunks = undefined
@@ -152,23 +279,18 @@ const RNExportNames = [
152
279
  'AccessibilityInfo',
153
280
  'ActivityIndicator',
154
281
  'Button',
155
- 'DatePickerIOS',
156
282
  'DrawerLayoutAndroid',
157
283
  'FlatList',
158
284
  'Image',
159
285
  'ImageBackground',
160
286
  'InputAccessoryView',
161
287
  'KeyboardAvoidingView',
162
- 'MaskedViewIOS',
163
288
  'Modal',
164
289
  'Pressable',
165
- 'ProgressBarAndroid',
166
- 'ProgressViewIOS',
167
290
  'RefreshControl',
168
291
  'SafeAreaView',
169
292
  'ScrollView',
170
293
  'SectionList',
171
- 'Slider',
172
294
  'StatusBar',
173
295
  'Switch',
174
296
  'Text',
@@ -187,16 +309,13 @@ const RNExportNames = [
187
309
  'Appearance',
188
310
  'AppRegistry',
189
311
  'AppState',
190
- 'AsyncStorage',
191
312
  'BackHandler',
192
- 'Clipboard',
193
313
  'DeviceInfo',
194
314
  'DevSettings',
195
315
  'Dimensions',
196
316
  'Easing',
197
317
  'findNodeHandle',
198
318
  'I18nManager',
199
- 'ImagePickerIOS',
200
319
  'InteractionManager',
201
320
  'Keyboard',
202
321
  'LayoutAnimation',
@@ -237,3 +356,67 @@ const RNExportNames = [
237
356
  // 'PointPropType',
238
357
  // 'ViewPropTypes',
239
358
  ]
359
+
360
+ // failed attempt to get vite to bundle rn, after a bunch of hacks still trouble
361
+
362
+ // config.build.rollupOptions.plugins.push({
363
+ // name: 'flow-remove-types',
364
+ // transform: async (codeIn, id) => {
365
+ // if (!id.includes('node_modules')) {
366
+ // return
367
+ // }
368
+ // const flowRemoved = flowRemoveTypes(codeIn).toString()
369
+ // let jsxRemoved = await nativeBabelRemoveJSX(flowRemoved)
370
+
371
+ // if (id.includes('BackHandler')) {
372
+ // jsxRemoved = jsxRemoved.replace(
373
+ // `module.exports = require('../Components/UnimplementedViews/UnimplementedView');`,
374
+ // ''
375
+ // )
376
+ // }
377
+
378
+ // if (jsxRemoved.includes(`module.exports = `)) {
379
+ // jsxRemoved = jsxRemoved.replace(
380
+ // /\nmodule.exports = /gi,
381
+ // `\nexport default `
382
+ // )
383
+ // }
384
+
385
+ // if (id.endsWith('ReactNativeViewConfigRegistry.js')) {
386
+ // jsxRemoved =
387
+ // jsxRemoved +
388
+ // `\nconst allExports = {...exports }; export default allExports;`
389
+ // }
390
+
391
+ // if (id.endsWith('ExceptionsManager.js')) {
392
+ // console.log('huh', id)
393
+ // jsxRemoved = jsxRemoved
394
+ // .replace(/\nfunction /g, 'export function')
395
+ // .replace('class SynthenticEvent', 'export class SyntheticEvent')
396
+ // .replace(
397
+ // `module.exports = {
398
+ // decoratedExtraDataKey,
399
+ // handleException,
400
+ // installConsoleErrorReporter,
401
+ // SyntheticError,
402
+ // unstable_setExceptionDecorator,
403
+ // };`,
404
+ // ``
405
+ // )
406
+ // }
407
+
408
+ // return {
409
+ // code: jsxRemoved,
410
+ // map: null,
411
+ // }
412
+ // },
413
+ // })
414
+
415
+ // config.build.rollupOptions.plugins.push(
416
+ // commonJs({
417
+ // include: ['**/node_modules/react-native/**', '**/node_modules/base64-js/**'],
418
+ // // ignoreGlobal: true,
419
+ // transformMixedEsModules: true,
420
+ // defaultIsModuleExports: true,
421
+ // }) as any
422
+ // )
@@ -6,21 +6,14 @@ import { build } from 'esbuild'
6
6
 
7
7
  import { extensions } from './extensions'
8
8
 
9
- export async function nativeBabelTransform(input: string) {
9
+ async function nativeBabelFlowTransform(input: string) {
10
10
  return await new Promise<string>((res, rej) => {
11
11
  babel.transform(
12
12
  input,
13
13
  {
14
- plugins: [
15
- '@babel/plugin-transform-modules-commonjs',
16
- '@babel/plugin-transform-classes',
17
- ],
14
+ presets: ['module:metro-react-native-babel-preset'],
18
15
  },
19
16
  (err: any, { code }) => {
20
- if (err) {
21
- console.error('error', err)
22
- }
23
-
24
17
  if (err) rej(err)
25
18
  res(code)
26
19
  }
@@ -28,78 +21,54 @@ export async function nativeBabelTransform(input: string) {
28
21
  })
29
22
  }
30
23
 
31
- export async function nativeBabelFlowTransform(input: string) {
32
- return await new Promise<string>((res, rej) => {
33
- babel.transform(
34
- input,
35
- {
36
- presets: ['module:metro-react-native-babel-preset'],
37
- },
38
- (err: any, { code }) => {
39
- if (err) rej(err)
40
- res(code)
41
- }
42
- )
43
- })
24
+ const prebuiltDir = join(process.cwd(), 'testing-area')
25
+ export const prebuiltFiles = {
26
+ react: join(prebuiltDir, 'react.js'),
27
+ reactJSXRuntime: join(prebuiltDir, 'react-jsx-runtime.js'),
28
+ reactNative: join(prebuiltDir, 'react-native.js'),
44
29
  }
45
30
 
46
31
  export async function nativePrebuild() {
47
32
  // rome-ignore lint/nursery/noConsoleLog: <explanation>
48
33
 
49
- if (process.env.SKIP_PREBUILD_RN) {
50
- console.log(`⚠️ skipping pre build of rn`)
34
+ // await build({
35
+ // bundle: true,
36
+ // entryPoints: [require.resolve('@tamagui/core')],
37
+ // outfile: prebuiltFiles.reactNative,
38
+ // format: 'cjs',
39
+ // target: 'node20',
40
+ // jsx: 'transform',
41
+ // jsxFactory: 'react',
42
+ // allowOverwrite: true,
43
+ // platform: 'node',
44
+ // external: ['react-native', 'react', 'react/jsx-runtime'],
45
+ // loader: {
46
+ // '.png': 'dataurl',
47
+ // '.jpg': 'dataurl',
48
+ // '.jpeg': 'dataurl',
49
+ // '.gif': 'dataurl',
50
+ // },
51
+ // define: {
52
+ // __DEV__: 'true',
53
+ // 'process.env.NODE_ENV': `"development"`,
54
+ // // TODO
55
+ // 'process.env.REACT_NATIVE_SERVER_PUBLIC_PORT': JSON.stringify('8081'),
56
+ // },
57
+ // logLevel: 'warning',
58
+ // resolveExtensions: extensions,
59
+ // })
51
60
 
61
+ if (process.env.SKIP_PREBUILD_RN) {
52
62
  return
53
63
  }
54
64
 
55
65
  console.log(`Prebuilding React Native (one time cost...)`)
56
66
 
57
- const outdir = join(process.cwd(), 'testing-area')
58
-
59
67
  await Promise.all([
60
- // react
61
- build({
62
- bundle: true,
63
- entryPoints: ['react'],
64
- outfile: join(outdir, 'react.js'),
65
- format: 'cjs',
66
- target: 'node20',
67
- jsx: 'transform',
68
- jsxFactory: 'react',
69
- allowOverwrite: true,
70
- platform: 'node',
71
- define: {
72
- __DEV__: 'true',
73
- 'process.env.NODE_ENV': `"development"`,
74
- },
75
- logLevel: 'warning',
76
- resolveExtensions: extensions,
77
- }),
78
- // react-jsx-runtime
79
68
  build({
80
69
  bundle: true,
81
- entryPoints: ['react/jsx-runtime'],
82
- outfile: join(outdir, 'react-jsx-runtime.js'),
83
- format: 'cjs',
84
- target: 'node20',
85
- jsx: 'transform',
86
- jsxFactory: 'react',
87
- external: ['react'],
88
- allowOverwrite: true,
89
- platform: 'node',
90
- define: {
91
- // metro serves this in production mode
92
- __DEV__: 'false',
93
- 'process.env.NODE_ENV': `"production"`,
94
- },
95
- logLevel: 'warning',
96
- resolveExtensions: extensions,
97
- }),
98
- // react native
99
- build({
100
- bundle: true,
101
- entryPoints: ['/Users/n8/tamagui/node_modules/react-native/index.js'],
102
- outfile: join(outdir, 'react-native.js'),
70
+ entryPoints: [require.resolve('react-native')],
71
+ outfile: prebuiltFiles.reactNative,
103
72
  format: 'cjs',
104
73
  target: 'node20',
105
74
  jsx: 'transform',
@@ -120,7 +89,6 @@ export async function nativePrebuild() {
120
89
  },
121
90
  logLevel: 'warning',
122
91
  resolveExtensions: extensions,
123
- external: ['react', 'react/jsx-runtime.js', 'react/jsx-runtime'],
124
92
  plugins: [
125
93
  {
126
94
  name: 'remove-flow',
@@ -163,5 +131,7 @@ export async function nativePrebuild() {
163
131
  },
164
132
  ],
165
133
  }),
134
+
135
+ ,
166
136
  ])
167
137
  }
@@ -0,0 +1,2 @@
1
+ export declare function getVitePath(importer: string, moduleName: string, absolute?: boolean): Promise<string>;
2
+ //# sourceMappingURL=getVitePath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getVitePath.d.ts","sourceRoot":"","sources":["../src/getVitePath.ts"],"names":[],"mappings":"AAKA,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,UAAQ,mBAsBjB"}
package/types/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './plugin';
2
2
  export * from './extract';
3
3
  export * from './nativePlugin';
4
+ export * from './getVitePath';
4
5
  export * from './nativePrebuild';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,kBAAkB,CAAA"}
@@ -1,5 +1,6 @@
1
1
  import type { Plugin } from 'vite';
2
2
  export declare function nativePlugin(options: {
3
3
  port: number;
4
+ mode: 'build' | 'serve';
4
5
  }): Plugin;
5
6
  //# sourceMappingURL=nativePlugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nativePlugin.d.ts","sourceRoot":"","sources":["../src/nativePlugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAIlC,wBAAgB,YAAY,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CA8I9D"}
1
+ {"version":3,"file":"nativePlugin.d.ts","sourceRoot":"","sources":["../src/nativePlugin.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAOlC,wBAAgB,YAAY,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;CAAE,GAAG,MAAM,CAsQvF"}
@@ -1,4 +1,7 @@
1
- export declare function nativeBabelTransform(input: string): Promise<string>;
2
- export declare function nativeBabelFlowTransform(input: string): Promise<string>;
1
+ export declare const prebuiltFiles: {
2
+ react: string;
3
+ reactJSXRuntime: string;
4
+ reactNative: string;
5
+ };
3
6
  export declare function nativePrebuild(): Promise<void>;
4
7
  //# sourceMappingURL=nativePrebuild.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nativePrebuild.d.ts","sourceRoot":"","sources":["../src/nativePrebuild.ts"],"names":[],"mappings":"AAQA,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,mBAoBvD;AAED,wBAAsB,wBAAwB,CAAC,KAAK,EAAE,MAAM,mBAa3D;AAED,wBAAsB,cAAc,kBAyHnC"}
1
+ {"version":3,"file":"nativePrebuild.d.ts","sourceRoot":"","sources":["../src/nativePrebuild.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,aAAa;;;;CAIzB,CAAA;AAED,wBAAsB,cAAc,kBA0GnC"}