vxrn 1.12.8 → 1.13.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.
Files changed (208) hide show
  1. package/dist/config/getAdditionalViteConfig.mjs +1 -4
  2. package/dist/config/getAdditionalViteConfig.mjs.map +1 -1
  3. package/dist/config/getAdditionalViteConfig.native.js +1 -4
  4. package/dist/config/getAdditionalViteConfig.native.js.map +1 -1
  5. package/dist/config/getReactNativePlugins.mjs +1 -5
  6. package/dist/config/getReactNativePlugins.mjs.map +1 -1
  7. package/dist/config/getReactNativePlugins.native.js +1 -5
  8. package/dist/config/getReactNativePlugins.native.js.map +1 -1
  9. package/dist/exports/build.mjs +5 -0
  10. package/dist/exports/build.mjs.map +1 -1
  11. package/dist/exports/build.native.js +5 -0
  12. package/dist/exports/build.native.js.map +1 -1
  13. package/dist/exports/createServer.mjs +30 -25
  14. package/dist/exports/createServer.mjs.map +1 -1
  15. package/dist/exports/createServer.native.js +6 -3
  16. package/dist/exports/createServer.native.js.map +1 -1
  17. package/dist/exports/prebuild.mjs +25 -1
  18. package/dist/exports/prebuild.mjs.map +1 -1
  19. package/dist/exports/prebuild.native.js +30 -1
  20. package/dist/exports/prebuild.native.js.map +1 -1
  21. package/dist/exports/serve.mjs +2 -2
  22. package/dist/exports/serve.mjs.map +1 -1
  23. package/dist/exports/serve.native.js +2 -2
  24. package/dist/exports/serve.native.js.map +1 -1
  25. package/dist/exports/serveStaticAssets.mjs +43 -11
  26. package/dist/exports/serveStaticAssets.mjs.map +1 -1
  27. package/dist/exports/serveStaticAssets.native.js +69 -6
  28. package/dist/exports/serveStaticAssets.native.js.map +1 -1
  29. package/dist/index.js +1 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +1 -2
  32. package/dist/index.mjs.map +1 -1
  33. package/dist/index.native.js +1 -2
  34. package/dist/index.native.js.map +1 -1
  35. package/dist/patches/builtInDepPatches.mjs +14 -0
  36. package/dist/patches/builtInDepPatches.mjs.map +1 -1
  37. package/dist/patches/builtInDepPatches.native.js +14 -0
  38. package/dist/patches/builtInDepPatches.native.js.map +1 -1
  39. package/dist/plugins/clientInjectPlugin.mjs +2 -62
  40. package/dist/plugins/clientInjectPlugin.mjs.map +1 -1
  41. package/dist/plugins/clientInjectPlugin.native.js +2 -75
  42. package/dist/plugins/clientInjectPlugin.native.js.map +1 -1
  43. package/dist/plugins/reactNativeDevAssetPlugin.mjs +1 -3
  44. package/dist/plugins/reactNativeDevAssetPlugin.mjs.map +1 -1
  45. package/dist/plugins/reactNativeDevAssetPlugin.native.js +1 -3
  46. package/dist/plugins/reactNativeDevAssetPlugin.native.js.map +1 -1
  47. package/dist/plugins/reactNativeDevServer.mjs +55 -77
  48. package/dist/plugins/reactNativeDevServer.mjs.map +1 -1
  49. package/dist/plugins/reactNativeDevServer.native.js +73 -84
  50. package/dist/plugins/reactNativeDevServer.native.js.map +1 -1
  51. package/dist/plugins/serverExtensions.test.mjs +12 -6
  52. package/dist/plugins/serverExtensions.test.mjs.map +1 -1
  53. package/dist/plugins/serverExtensions.test.native.js +12 -6
  54. package/dist/plugins/serverExtensions.test.native.js.map +1 -1
  55. package/dist/rn-commands/bundle/buildBundle.mjs +11 -35
  56. package/dist/rn-commands/bundle/buildBundle.mjs.map +1 -1
  57. package/dist/rn-commands/bundle/buildBundle.native.js +9 -36
  58. package/dist/rn-commands/bundle/buildBundle.native.js.map +1 -1
  59. package/dist/runtime/hmr-client.mjs +125 -0
  60. package/dist/runtime/hmr-client.mjs.map +1 -0
  61. package/dist/runtime/hmr-client.native.js +197 -0
  62. package/dist/runtime/hmr-client.native.js.map +1 -0
  63. package/dist/runtime/hmr-runtime.mjs +162 -0
  64. package/dist/runtime/hmr-runtime.mjs.map +1 -0
  65. package/dist/runtime/hmr-runtime.native.js +348 -0
  66. package/dist/runtime/hmr-runtime.native.js.map +1 -0
  67. package/dist/runtime/hmr-types.mjs +2 -0
  68. package/dist/runtime/hmr-types.mjs.map +1 -0
  69. package/dist/runtime/hmr-types.native.js +2 -0
  70. package/dist/runtime/hmr-types.native.js.map +1 -0
  71. package/dist/runtime/native-prelude.mjs +97 -0
  72. package/dist/runtime/native-prelude.mjs.map +1 -0
  73. package/dist/runtime/native-prelude.native.js +97 -0
  74. package/dist/runtime/native-prelude.native.js.map +1 -0
  75. package/dist/runtime/react-refresh-utils.mjs +19 -0
  76. package/dist/runtime/react-refresh-utils.mjs.map +1 -0
  77. package/dist/runtime/react-refresh-utils.native.js +24 -0
  78. package/dist/runtime/react-refresh-utils.native.js.map +1 -0
  79. package/dist/utils/createNativeDevEngine.mjs +661 -0
  80. package/dist/utils/createNativeDevEngine.mjs.map +1 -0
  81. package/dist/utils/createNativeDevEngine.native.js +702 -0
  82. package/dist/utils/createNativeDevEngine.native.js.map +1 -0
  83. package/dist/utils/patches.mjs +6 -2
  84. package/dist/utils/patches.mjs.map +1 -1
  85. package/dist/utils/patches.native.js +6 -2
  86. package/dist/utils/patches.native.js.map +1 -1
  87. package/dist/utils/scanDepsToOptimize.mjs +4 -3
  88. package/dist/utils/scanDepsToOptimize.mjs.map +1 -1
  89. package/dist/utils/scanDepsToOptimize.native.js +4 -3
  90. package/dist/utils/scanDepsToOptimize.native.js.map +1 -1
  91. package/expo-plugin.cjs +122 -0
  92. package/package.json +15 -19
  93. package/src/config/getAdditionalViteConfig.ts +1 -3
  94. package/src/config/getReactNativePlugins.ts +0 -6
  95. package/src/exports/build.ts +5 -0
  96. package/src/exports/createServer.ts +7 -2
  97. package/src/exports/prebuild.ts +45 -0
  98. package/src/exports/serve.ts +2 -1
  99. package/src/exports/serveStaticAssets.ts +67 -4
  100. package/src/index.ts +0 -2
  101. package/src/patches/builtInDepPatches.ts +29 -0
  102. package/src/plugins/clientInjectPlugin.ts +2 -109
  103. package/src/plugins/reactNativeDevAssetPlugin.ts +0 -21
  104. package/src/plugins/reactNativeDevServer.ts +57 -84
  105. package/src/plugins/serverExtensions.test.ts +6 -8
  106. package/src/rn-commands/bundle/buildBundle.ts +9 -62
  107. package/src/runtime/hmr-client.ts +215 -0
  108. package/src/runtime/hmr-runtime.ts +276 -0
  109. package/src/runtime/hmr-types.ts +84 -0
  110. package/src/runtime/native-prelude.ts +110 -0
  111. package/src/runtime/react-refresh-utils.ts +36 -0
  112. package/src/types.ts +22 -4
  113. package/src/utils/createNativeDevEngine.ts +942 -0
  114. package/src/utils/patches.ts +36 -18
  115. package/src/utils/scanDepsToOptimize.ts +2 -3
  116. package/types/config/getAdditionalViteConfig.d.ts.map +1 -1
  117. package/types/config/getOptionsFilled.d.ts +2 -18
  118. package/types/config/getOptionsFilled.d.ts.map +1 -1
  119. package/types/config/getReactNativePlugins.d.ts.map +1 -1
  120. package/types/exports/build.d.ts +1 -9
  121. package/types/exports/build.d.ts.map +1 -1
  122. package/types/exports/createServer.d.ts.map +1 -1
  123. package/types/exports/prebuild.d.ts.map +1 -1
  124. package/types/exports/serve.d.ts +2 -1
  125. package/types/exports/serve.d.ts.map +1 -1
  126. package/types/exports/serveStaticAssets.d.ts +12 -1
  127. package/types/exports/serveStaticAssets.d.ts.map +1 -1
  128. package/types/index.d.ts +0 -1
  129. package/types/index.d.ts.map +1 -1
  130. package/types/patches/builtInDepPatches.d.ts.map +1 -1
  131. package/types/plugins/clientInjectPlugin.d.ts +1 -7
  132. package/types/plugins/clientInjectPlugin.d.ts.map +1 -1
  133. package/types/plugins/reactNativeDevAssetPlugin.d.ts.map +1 -1
  134. package/types/plugins/reactNativeDevServer.d.ts.map +1 -1
  135. package/types/rn-commands/bundle/buildBundle.d.ts.map +1 -1
  136. package/types/runtime/hmr-client.d.ts +40 -0
  137. package/types/runtime/hmr-client.d.ts.map +1 -0
  138. package/types/runtime/hmr-runtime.d.ts +69 -0
  139. package/types/runtime/hmr-runtime.d.ts.map +1 -0
  140. package/types/runtime/hmr-types.d.ts +76 -0
  141. package/types/runtime/hmr-types.d.ts.map +1 -0
  142. package/types/runtime/native-prelude.d.ts +11 -0
  143. package/types/runtime/native-prelude.d.ts.map +1 -0
  144. package/types/runtime/react-refresh-utils.d.ts +3 -0
  145. package/types/runtime/react-refresh-utils.d.ts.map +1 -0
  146. package/types/types.d.ts +15 -1
  147. package/types/types.d.ts.map +1 -1
  148. package/types/utils/createNativeDevEngine.d.ts +42 -0
  149. package/types/utils/createNativeDevEngine.d.ts.map +1 -0
  150. package/types/utils/patches.d.ts.map +1 -1
  151. package/types/utils/scanDepsToOptimize.d.ts.map +1 -1
  152. package/dist/config/getReactNativeBuildConfig.mjs +0 -200
  153. package/dist/config/getReactNativeBuildConfig.mjs.map +0 -1
  154. package/dist/config/getReactNativeBuildConfig.native.js +0 -204
  155. package/dist/config/getReactNativeBuildConfig.native.js.map +0 -1
  156. package/dist/plugins/reactNativeHMRPlugin.mjs +0 -120
  157. package/dist/plugins/reactNativeHMRPlugin.mjs.map +0 -1
  158. package/dist/plugins/reactNativeHMRPlugin.native.js +0 -151
  159. package/dist/plugins/reactNativeHMRPlugin.native.js.map +0 -1
  160. package/dist/utils/filterPluginsForNative.mjs +0 -27
  161. package/dist/utils/filterPluginsForNative.mjs.map +0 -1
  162. package/dist/utils/filterPluginsForNative.native.js +0 -33
  163. package/dist/utils/filterPluginsForNative.native.js.map +0 -1
  164. package/dist/utils/getReactNativeBundle.mjs +0 -104
  165. package/dist/utils/getReactNativeBundle.mjs.map +0 -1
  166. package/dist/utils/getReactNativeBundle.native.js +0 -135
  167. package/dist/utils/getReactNativeBundle.native.js.map +0 -1
  168. package/dist/utils/hotUpdateCache.mjs +0 -3
  169. package/dist/utils/hotUpdateCache.mjs.map +0 -1
  170. package/dist/utils/hotUpdateCache.native.js +0 -3
  171. package/dist/utils/hotUpdateCache.native.js.map +0 -1
  172. package/dist/utils/isBuildingNativeBundle.mjs +0 -6
  173. package/dist/utils/isBuildingNativeBundle.mjs.map +0 -1
  174. package/dist/utils/isBuildingNativeBundle.native.js +0 -7
  175. package/dist/utils/isBuildingNativeBundle.native.js.map +0 -1
  176. package/dist/utils/swapPrebuiltReactModules.mjs +0 -168
  177. package/dist/utils/swapPrebuiltReactModules.mjs.map +0 -1
  178. package/dist/utils/swapPrebuiltReactModules.native.js +0 -181
  179. package/dist/utils/swapPrebuiltReactModules.native.js.map +0 -1
  180. package/dist/worker.mjs +0 -55
  181. package/dist/worker.mjs.map +0 -1
  182. package/dist/worker.native.js +0 -55
  183. package/dist/worker.native.js.map +0 -1
  184. package/react-native-template.js +0 -375
  185. package/src/config/getReactNativeBuildConfig.ts +0 -349
  186. package/src/plugins/reactNativeHMRPlugin.ts +0 -237
  187. package/src/utils/filterPluginsForNative.ts +0 -55
  188. package/src/utils/getReactNativeBundle.ts +0 -243
  189. package/src/utils/hotUpdateCache.ts +0 -1
  190. package/src/utils/isBuildingNativeBundle.ts +0 -7
  191. package/src/utils/swapPrebuiltReactModules.ts +0 -341
  192. package/src/worker.ts +0 -90
  193. package/types/config/getReactNativeBuildConfig.d.ts +0 -72
  194. package/types/config/getReactNativeBuildConfig.d.ts.map +0 -1
  195. package/types/plugins/reactNativeHMRPlugin.d.ts +0 -10
  196. package/types/plugins/reactNativeHMRPlugin.d.ts.map +0 -1
  197. package/types/utils/filterPluginsForNative.d.ts +0 -8
  198. package/types/utils/filterPluginsForNative.d.ts.map +0 -1
  199. package/types/utils/getReactNativeBundle.d.ts +0 -12
  200. package/types/utils/getReactNativeBundle.d.ts.map +0 -1
  201. package/types/utils/hotUpdateCache.d.ts +0 -2
  202. package/types/utils/hotUpdateCache.d.ts.map +0 -1
  203. package/types/utils/isBuildingNativeBundle.d.ts +0 -3
  204. package/types/utils/isBuildingNativeBundle.d.ts.map +0 -1
  205. package/types/utils/swapPrebuiltReactModules.d.ts +0 -9
  206. package/types/utils/swapPrebuiltReactModules.d.ts.map +0 -1
  207. package/types/worker.d.ts +0 -13
  208. package/types/worker.d.ts.map +0 -1
@@ -1,349 +0,0 @@
1
- import nodeResolve from '@rollup/plugin-node-resolve'
2
- import { createVXRNCompilerPlugin } from '@vxrn/compiler'
3
- import { resolvePath } from '@vxrn/resolve'
4
- import { stat } from 'node:fs/promises'
5
- import { dirname, join } from 'node:path'
6
- import {
7
- createLogger,
8
- type InlineConfig,
9
- type Logger,
10
- type Plugin,
11
- resolveConfig,
12
- type ResolvedConfig,
13
- type UserConfig,
14
- } from 'vite'
15
- import { DEFAULT_ASSET_EXTS } from '../constants/defaults'
16
- import { nativeClientInjectPlugin } from '../plugins/clientInjectPlugin'
17
- import { reactNativeCommonJsPlugin } from '../plugins/reactNativeCommonJsPlugin'
18
- import { reactNativeDevAssetPlugin } from '../plugins/reactNativeDevAssetPlugin'
19
- import { dedupe } from './getBaseViteConfigOnly'
20
- import { getOptimizeDeps } from './getOptimizeDeps'
21
- import type { VXRNOptionsFilled } from './getOptionsFilled'
22
- import { swapPrebuiltReactModules } from '../utils/swapPrebuiltReactModules'
23
-
24
- // Suppress these logs:
25
- // * Use of eval in "(...)/react-native-prebuilt/vendor/react-native-0.74.1/index.js" is strongly discouraged as it poses security risks and may cause issues with minification.
26
- // * Use of eval in "(...)/one/dist/esm/useLoader.native.js" is strongly discouraged as it poses security risks and may cause issues with minification.
27
- // (not an exhaustive list)
28
- const IGNORE_ROLLUP_LOGS_RE =
29
- /vite-native-client\/dist\/esm\/client|node_modules\/\.vxrn\/react-native|react-native-prebuilt\/vendor|one\/dist/
30
-
31
- /**
32
- * This is not the config that you merge into the general Vite config.
33
- *
34
- * It is only for building native React Native bundles, while passed directly
35
- * to Vite's `createBuilder` function.
36
- *
37
- * Mainly used by the `getReactNativeBundle` function.
38
- */
39
- export async function getReactNativeBuildConfig(
40
- options: Pick<VXRNOptionsFilled, 'root' | 'cacheDir'> & {
41
- server: Pick<VXRNOptionsFilled['server'], 'url' | 'port'>
42
- entries: Pick<VXRNOptionsFilled['entries'], 'native'>
43
- },
44
- internal: { mode?: 'dev' | 'prod'; assetsDest?: string } = { mode: 'dev' },
45
- platform: 'ios' | 'android'
46
- ) {
47
- const {
48
- root,
49
- server: { port },
50
- } = options
51
- const { optimizeDeps } = getOptimizeDeps('build')
52
-
53
- const { mode } = internal
54
- const serverUrl = process.env.ONE_SERVER_URL || options.server.url
55
-
56
- const defaultLogger = createLogger()
57
-
58
- let disableLogging = false
59
- const customLogger = {
60
- ...defaultLogger,
61
- info(msg, options) {
62
- if (disableLogging) {
63
- if (msg.includes(`built in`)) {
64
- disableLogging = false
65
- defaultLogger.info(msg, options)
66
- }
67
- return
68
- }
69
- // this is a super noisy and large log on most react native apps
70
- // actually slows down compile-time significantly
71
- if (msg.includes('modules transformed.')) {
72
- disableLogging = true
73
- // safeguard, re-enable after a beat
74
- setTimeout(() => {
75
- disableLogging = false
76
- }, 2000)
77
- }
78
- defaultLogger.info(msg, options)
79
- },
80
- } satisfies Logger
81
-
82
- // build app
83
- let nativeBuildConfig = {
84
- plugins: [
85
- ...(globalThis.__vxrnAddNativePlugins || []),
86
-
87
- ...(mode === 'dev' ? [nativeClientInjectPlugin()] : []),
88
-
89
- {
90
- name: 'native-special-case-resolver',
91
- enforce: 'pre',
92
-
93
- /**
94
- * WORKAROUND: Since currently RN is considered as a "server" environment,
95
- * and [in such environment](https://github.com/vitejs/vite/blob/v6.0.5/packages/vite/src/node/plugins/resolve.ts#L385-L389), Node.js built-in modules such as `buffer` are [forced to be externalized](https://github.com/vitejs/vite/blob/v6.0.5/packages/vite/src/node/plugins/resolve.ts#L420),
96
- * even if there are available packages that can be resolved.
97
- *
98
- * But we also need RN to be a "server" environment so that other Node.js built-in modules we actually want to ignore [are externalized](https://github.com/vitejs/vite/blob/v6.0.5/packages/vite/src/node/plugins/resolve.ts#L428-L449) but not [polyfilled](https://github.com/vitejs/vite/blob/v6.0.5/packages/vite/src/node/plugins/resolve.ts#L462-L464), since currently we didn't filter out API routes in the RN bundle.
99
- *
100
- * Either doing one of the following can make this workaroud go away:
101
- *
102
- * 1. Filter out API routes in the RN bundle, so that we don't actually need to worry about Node.js built-ins used in the API routes not being externalized and ignored.
103
- * 2. Make Vite support a new environment type that is not a "server" nor a "client" (browser).
104
- */
105
- async resolveId(id, _importer, options) {
106
- // Skip during Vite's dependency optimization scan
107
- // @see https://github.com/remix-run/remix/discussions/8917
108
- // @ts-expect-error - scan is not in Vite's types but exists at runtime
109
- if (options?.scan) return
110
-
111
- // Only run this plugin for iOS and Android bundles
112
- if (this.environment.name !== 'ios' && this.environment.name !== 'android') {
113
- return
114
- }
115
-
116
- switch (id) {
117
- case 'buffer': {
118
- return findModulePath(join('buffer', 'index.js'), root)
119
- }
120
- case 'punycode': {
121
- return findModulePath(join('punycode', 'punycode.es6.js'), root)
122
- }
123
- }
124
- },
125
- } satisfies Plugin,
126
-
127
- {
128
- name: 'one:native-no-external',
129
- enforce: 'pre',
130
- config() {
131
- const noExternalsEnvConfig = {
132
- consumer: 'server',
133
- resolve: {
134
- noExternal: true,
135
- },
136
- } as const
137
-
138
- return {
139
- environments: {
140
- ios: noExternalsEnvConfig,
141
- android: noExternalsEnvConfig,
142
- },
143
- }
144
- },
145
- } satisfies Plugin,
146
-
147
- nodeResolve(),
148
-
149
- await swapPrebuiltReactModules(options.cacheDir, {
150
- // TODO: a better way to pass the mode (dev/prod) to PrebuiltReactModules
151
- mode: internal.mode || 'dev',
152
- platform,
153
- }),
154
-
155
- reactNativeDevAssetPlugin({
156
- mode: internal.mode,
157
- assetsDest: internal.assetsDest,
158
- assetExts: DEFAULT_ASSET_EXTS,
159
- }),
160
-
161
- reactNativeCommonJsPlugin({
162
- root,
163
- port,
164
- mode: 'build',
165
- }),
166
-
167
- // Avoid "failed to read input source map: failed to parse inline source map url" errors on certain packages, such as react-native-reanimated.
168
- {
169
- name: 'remove-inline-source-maps',
170
- transform: {
171
- order: 'pre',
172
- async handler(code, id) {
173
- if (!id.includes('react-native-reanimated')) {
174
- return null
175
- }
176
-
177
- const inlineSourceMapIndex = code.lastIndexOf('//# sourceMappingURL=')
178
- if (inlineSourceMapIndex >= 0) {
179
- return code.slice(0, inlineSourceMapIndex).trimEnd()
180
- }
181
-
182
- return null
183
- },
184
- },
185
- },
186
-
187
- createVXRNCompilerPlugin({
188
- mode: 'build',
189
- environment: 'ios',
190
- }),
191
-
192
- {
193
- // FIXME: This is a workaround to "tree-shake" things that will cause problems away before we have Rollup tree-shaking configured properly (https://github.com/onejs/one/pull/340).
194
- name: 'vxrn:manual-tree-shake',
195
- enforce: 'post',
196
- async renderChunk(code, chunk, options, meta) {
197
- if (chunk.name.endsWith('packages/one/dist/esm/createApp.native')) {
198
- // What we want to do here is to "tree-shake" `require('react-scan/native')` away if it's value is not assigned to anything (i.e. not used).
199
- // However, `react-scan/native` will be wrapped with a "commonjs-es-import" virtual module by the `@rollup/plugin-commonjs` plugin (Vite built-in) so that import won't have `react-scan/native` in it's name. The only thing for sure is that it's path will contain `_virtual`.
200
- // As in `createApp.native` the only "side-effect modules" we are currently using are './polyfills-mobile' and './setup', which won't be wrapped with a virtual module, this won't remove unintended things for now.
201
- return { code: code.replace(/^require\(.+_virtual.+\);/gm, '') }
202
- }
203
- },
204
- } satisfies Plugin,
205
- ].filter(Boolean),
206
-
207
- appType: 'custom',
208
- root,
209
- clearScreen: false,
210
- esbuild: false,
211
-
212
- // the huge logs actually add quite a bit of time to build
213
- customLogger,
214
-
215
- optimizeDeps: {
216
- ...optimizeDeps,
217
- rolldownOptions: {
218
- moduleTypes: { '.js': 'jsx' },
219
- },
220
- },
221
-
222
- resolve: {
223
- dedupe,
224
-
225
- alias: {
226
- 'react-native-css-interop/jsx-dev-runtime': join(
227
- resolvePath('react-native-css-interop'),
228
- '..',
229
- '..',
230
- 'dist',
231
- 'runtime',
232
- 'jsx-dev-runtime.js'
233
- ),
234
- },
235
- },
236
-
237
- mode: mode === 'dev' ? 'development' : 'production',
238
-
239
- define: {
240
- 'process.env.NODE_ENV': mode === 'dev' ? `"development"` : `"production"`,
241
- 'process.env.ONE_SERVER_URL': JSON.stringify(serverUrl),
242
- },
243
-
244
- build: {
245
- ssr: true,
246
- minify: false,
247
- rolldownOptions: {
248
- input: options.entries.native,
249
- treeshake: false,
250
- preserveEntrySignatures: 'strict',
251
- output: {
252
- preserveModules: true,
253
- format: 'cjs',
254
- },
255
-
256
- onwarn(message, warn) {
257
- // Suppress "Module level directives cause errors when bundled" warnings
258
- if (!process.env.DEBUG?.startsWith('vxrn')) {
259
- if (
260
- message.code === 'MODULE_LEVEL_DIRECTIVE' ||
261
- message.code === 'INVALID_ANNOTATION' ||
262
- message.code === 'MISSING_EXPORT' ||
263
- message.code === 'SOURCEMAP_ERROR'
264
- ) {
265
- warnAboutSuppressingLogsOnce()
266
- return
267
- }
268
- }
269
- warn(message)
270
- },
271
-
272
- onLog(level, log, handler) {
273
- if (!process.env.DEBUG?.startsWith('vxrn')) {
274
- if (IGNORE_ROLLUP_LOGS_RE.test(log.message)) {
275
- warnAboutSuppressingLogsOnce()
276
- return
277
- }
278
- }
279
-
280
- handler(level, log)
281
- },
282
- },
283
- },
284
- } satisfies InlineConfig
285
-
286
- // TODO
287
- // if (options.nativeConfig) {
288
- // nativeBuildConfig = mergeConfig(nativeBuildConfig, options.nativeConfig) as any
289
- // }
290
-
291
- // // this fixes my swap-react-native plugin not being called pre 😳
292
- resolvedConfig = await resolveConfig(nativeBuildConfig, 'build')
293
-
294
- // The `resolveConfig` function will load user's `vite.config.*` (by calling `loadConfigFromFile`).
295
- // Here we do this to make user defined global constant replacements (https://vite.dev/config/shared-options#define) to take effect in RN.
296
- // TODO: Ultimately, we should make all the user defined config options to take effect in RN.
297
- if (resolvedConfig.define) {
298
- nativeBuildConfig.define = {
299
- ...nativeBuildConfig.define,
300
- ...resolvedConfig.define,
301
- }
302
- }
303
-
304
- return nativeBuildConfig satisfies UserConfig
305
- }
306
-
307
- let resolvedConfig: ResolvedConfig | null = null
308
- /** Use by things such as the reactNativeHMRPlugin to get the config after the initial build. */
309
- export function getReactNativeResolvedConfig() {
310
- return resolvedConfig
311
- }
312
-
313
- let didWarnSuppressingLogs = false
314
- function warnAboutSuppressingLogsOnce() {
315
- if (!didWarnSuppressingLogs) {
316
- didWarnSuppressingLogs = true
317
- // honestly they are harmdless so no need to warn, but it would be nice to do it once ever and then save that we did to disk
318
- // console.warn(` [vxrn] Suppressing mostly harmless logs, enable with DEBUG=vxrn`)
319
- }
320
- }
321
-
322
- /**
323
- * Recursively search for a path in node_modules directories until file system root is reached.
324
- */
325
- async function findModulePath(
326
- modulePath: string,
327
- currentDir: string,
328
- triedPaths?: Array<string>
329
- ): Promise<string | null> {
330
- const currentModulePath = join(currentDir, 'node_modules', modulePath)
331
-
332
- try {
333
- await stat(currentModulePath)
334
- return currentModulePath
335
- } catch {
336
- const parentDir = dirname(currentDir)
337
-
338
- if (parentDir === currentDir) {
339
- throw new Error(
340
- `Could not find module in any of these paths: ${triedPaths?.join(', ')}`
341
- )
342
- }
343
-
344
- return findModulePath(modulePath, parentDir, [
345
- ...(triedPaths || []),
346
- currentModulePath,
347
- ])
348
- }
349
- }
@@ -1,237 +0,0 @@
1
- import { transformSWC, transformSWCStripJSX } from '@vxrn/compiler'
2
- import { parse } from 'es-module-lexer'
3
- import FSExtra from 'fs-extra'
4
- import { createIdResolver, type ResolvedConfig, type Plugin, type ResolveFn } from 'vite'
5
- import { connectedNativeClients } from '../utils/connectedNativeClients'
6
- import { filterPluginsForNative } from '../utils/filterPluginsForNative'
7
- import type { VXRNOptionsFilled } from '../config/getOptionsFilled'
8
- import { entryRoot } from '../utils/getReactNativeBundle'
9
- import { getReactNativeResolvedConfig } from '../config/getReactNativeBuildConfig'
10
- import { getVitePath } from '../utils/getVitePath'
11
- import { hotUpdateCache } from '../utils/hotUpdateCache'
12
- import { isWithin } from '../utils/isWithin'
13
- import { conditions } from './reactNativeCommonJsPlugin'
14
-
15
- export function reactNativeHMRPlugin({
16
- assetExts,
17
- root: rootIn,
18
- mode: modeIn,
19
- }: Partial<Pick<VXRNOptionsFilled, 'root' | 'mode'>> & { assetExts: string[] }) {
20
- let idResolver: ReturnType<typeof createIdResolver>
21
-
22
- const assetExtsRegExp = new RegExp(`\\.(${assetExts.join('|')})$`)
23
- const isAssetFile = (id: string) => assetExtsRegExp.test(id)
24
-
25
- let config: ResolvedConfig
26
-
27
- return {
28
- name: 'vxrn:native-hmr-transform',
29
-
30
- configResolved(resolvedConfig) {
31
- config = resolvedConfig
32
- },
33
-
34
- // TODO see about moving to hotUpdate
35
- // https://deploy-preview-16089--vite-docs-main.netlify.app/guide/api-vite-environment.html#the-hotupdate-hook
36
- async handleHotUpdate({ read, modules, file, server }) {
37
- const root = rootIn || config.root
38
- const mode = modeIn || config.mode
39
- const environment = server.environments.ios // TODO: android? How can we get the current environment here?
40
-
41
- if (!idResolver) {
42
- const rnConfig = getReactNativeResolvedConfig()
43
- if (!rnConfig) {
44
- // they are only running web app not native
45
- return
46
- }
47
-
48
- // for some reason rnConfig.resolve.conditions is empty array
49
- const resolverConfig = {
50
- conditions,
51
- mainFields: rnConfig.resolve.mainFields,
52
- extensions: rnConfig.resolve.extensions,
53
- }
54
- idResolver = createIdResolver(rnConfig, resolverConfig)
55
- }
56
-
57
- try {
58
- if (!isWithin(root, file)) {
59
- return
60
- }
61
- if (!connectedNativeClients) {
62
- return
63
- }
64
-
65
- const [module] = modules
66
- if (!module) return
67
-
68
- const fullId = module?.url || file
69
-
70
- let id = fullId.replace(root, '').replace('/@id', '')
71
- if (id[0] !== '/') {
72
- id = `/${id}`
73
- }
74
-
75
- if (isAssetFile(id)) {
76
- // TODO: Handle asset updates.
77
- return
78
- }
79
-
80
- const code = await read()
81
-
82
- // got a weird pre compiled file on startup
83
- if (code.startsWith(`'use strict';`)) {
84
- return
85
- }
86
-
87
- if (!code) {
88
- return
89
- }
90
-
91
- let source = code
92
-
93
- // we have to remove jsx before we can parse imports...
94
- try {
95
- // We create a new plugin container to ensure some plugins are filtered out,
96
- // since `pluginContainer.getSortedPlugins()` is using a cached that we
97
- // can't access thus can't make sure the cached plugins are filtered.
98
- const pluginContainerForTransform: typeof environment.pluginContainer = new (
99
- environment.pluginContainer.constructor as any
100
- )(
101
- environment,
102
- filterPluginsForNative(environment.plugins, { isNative: true }).filter(
103
- (p) =>
104
- p.name !==
105
- 'vite:import-analysis' /* will cause `ERR_OUTDATED_OPTIMIZED_DEP` error */
106
- ),
107
- server.watcher
108
- )
109
-
110
- const transformResult = await pluginContainerForTransform.transform(
111
- source,
112
- `vxrn-swc-preprocess:${file}`
113
- )
114
-
115
- source = transformResult.code
116
- } catch (e) {
117
- console.warn(
118
- `Error transforming source for HMR: ${e}. Retrying without plugins.`
119
- )
120
- source = (await transformSWCStripJSX(id, source))?.code || ''
121
- }
122
-
123
- // TODO: This is a hacky way to make HMR route files work, since if we don't run through the `clientTreeShakePlugin`, the source code might include imports to server side stuff (typically used inside `loader` functions) that will break the HMR update. Ideally, we should go though all user plugins for HMR updates.
124
- const clientTreeShakePlugin = environment.plugins.find((p) =>
125
- p.name.endsWith('client-tree-shake')
126
- )
127
- if (clientTreeShakePlugin) {
128
- let clientTreeShakePluginTransformFn = (clientTreeShakePlugin as any).transform
129
- if (typeof clientTreeShakePluginTransformFn === 'function') {
130
- try {
131
- clientTreeShakePluginTransformFn = clientTreeShakePluginTransformFn.bind({
132
- environment,
133
- })
134
- const result = await clientTreeShakePluginTransformFn(source, id, {})
135
- if (result) {
136
- source = result.code
137
- }
138
- } catch (e) {
139
- console.warn(`client-tree-shake failed on HMR: ${e}`)
140
- }
141
- }
142
- }
143
-
144
- const importsMap = {}
145
-
146
- // parse imports of modules into ids:
147
- // eg `import x from '@tamagui/core'` => `import x from '/me/node_modules/@tamagui/core/index.js'`
148
- const [imports] = parse(source)
149
-
150
- let accumulatedSliceOffset = 0
151
-
152
- for (const specifier of imports) {
153
- const { n: importName, s: start } = specifier
154
-
155
- if (importName) {
156
- // TODO: maybe we only need `resolverWithPlugins`?
157
- const resolver: ResolveFn = idResolver.bind(null, environment)
158
- const resolverWithPlugins: ResolveFn = async (id, importer) => {
159
- // Need this since `idResolver` will not run through user plugins, but we might need plugins like `vite-tsconfig-paths` to work if they are used
160
- const resolvedIdData = await environment.pluginContainer.resolveId(
161
- id,
162
- importer
163
- )
164
- return resolvedIdData?.id
165
- }
166
-
167
- let id = await getVitePath(
168
- entryRoot,
169
- file,
170
- importName,
171
- resolver,
172
- resolverWithPlugins
173
- )
174
- if (!id) {
175
- console.warn('???')
176
- continue
177
- }
178
-
179
- // It seems that it's not possible for Vite to use customized extensions for resolving imports from package.json entry (see: https://github.com/vitejs/vite/blob/v6.0.0-beta.2/packages/vite/src/node/plugins/resolve.ts#L1018),
180
- // so we need to manually check if the file with `.native.js` extension exists, and use it if it does.
181
- // @zetavg: We need to check how this is done during bundling, make sure it's consistent and probably merge the logic.
182
- const nativePath = id.replace(/(.m?js)/, '.native.js')
183
- try {
184
- if (nativePath !== id && (await FSExtra.stat(nativePath)).isFile()) {
185
- id = nativePath
186
- }
187
- } catch (e) {}
188
-
189
- importsMap[id] = id.replace(/^(\.\.\/)+/, '')
190
-
191
- // replace module name with id for hmr
192
- const len = importName.length
193
- const extraLen = id.length - len
194
- source =
195
- source.slice(0, start + accumulatedSliceOffset) +
196
- id +
197
- source.slice(start + accumulatedSliceOffset + len)
198
- accumulatedSliceOffset += extraLen
199
- }
200
- }
201
-
202
- // then we have to convert to commonjs..
203
- source =
204
- (
205
- await transformSWC(file, source, {
206
- mode: 'serve-cjs',
207
- environment: 'ios',
208
- production: mode === 'production',
209
- })
210
- )?.code || ''
211
-
212
- if (!source) {
213
- throw '❌ no source'
214
- }
215
-
216
- const hotUpdateSource = `exports = ((exports) => {
217
- const require = createRequire("${id}", ${JSON.stringify(importsMap, null, 2)})
218
- ${source
219
- .replace(`import.meta.hot.accept(() => {})`, ``)
220
- // replace import.meta.glob with empty array in hot reloads
221
- .replaceAll(
222
- /import.meta.glob\(.*\)/gi,
223
- `globalThis['__importMetaGlobbed'] || {}`
224
- )};
225
- return exports })({})`
226
-
227
- if (process.env.DEBUG) {
228
- console.info(`Sending hot update`, id, hotUpdateSource)
229
- }
230
-
231
- hotUpdateCache.set(id, hotUpdateSource)
232
- } catch (err) {
233
- console.error(`Error processing hmr update:`, err)
234
- }
235
- },
236
- } satisfies Plugin
237
- }
@@ -1,55 +0,0 @@
1
- import type { Plugin } from 'vite'
2
-
3
- /**
4
- * Filter out plugins and plugin hooks that are not needed for (or will even break) React Native.
5
- */
6
- export function filterPluginsForNative(
7
- plugins: readonly Plugin[],
8
- { isNative }: { isNative: boolean }
9
- ): Plugin[] {
10
- return plugins
11
- .flatMap((p) => {
12
- if (!p.name) {
13
- return p
14
- }
15
-
16
- if (p.name.endsWith('-web-only')) {
17
- return null
18
- }
19
-
20
- if (p.name === 'vite:reporter') {
21
- return {
22
- ...p,
23
- // Printing out bundle details such as all the files that are included in the bundle and their sizes will cutter the terminal and also waste time.
24
- writeBundle: undefined,
25
- }
26
- }
27
-
28
- // Filter out unnecessary `renderChunk` hooks that are not needed for RN
29
- if (
30
- isNative /* See: https://github.com/universal-future/one/pull/23#issuecomment-2381402764 */ &&
31
- p.renderChunk
32
- ) {
33
- if (
34
- [
35
- 'vite:build-metadata', // Inserts asset and CSS related metadata which is not needed for RN (see: https://github.com/vitejs/vite/blob/v6.0.0-alpha.18/packages/vite/src/node/plugins/metadata.ts#L10-L16)
36
- 'vite:worker', // See: https://github.com/vitejs/vite/blob/v6.0.0-alpha.18/packages/vite/src/node/plugins/worker.ts#L383-L429
37
- 'vite:asset', // Seems not needed since with RN we have our own asset handling logic (see: https://github.com/vitejs/vite/blob/v6.0.0-alpha.18/packages/vite/src/node/plugins/asset.ts#L214-L227)
38
- 'vite:css-post', // Seems not needed since we are not using CSS-in-JS for RN (see: https://github.com/vitejs/vite/blob/v6.0.0-alpha.18/packages/vite/src/node/plugins/css.ts#L560-L830)
39
- 'vite:force-systemjs-wrap-complete', // Not needed since we are not using SystemJS (see: https://github.com/vitejs/vite/blob/v6.0.0-alpha.18/packages/vite/src/node/plugins/completeSystemWrap.ts#L12-L21)
40
- // 'vite:build-import-analysis',
41
- 'vite:esbuild-transpile', // Seems to be ok to remove.
42
- 'vite:reporter',
43
- ].includes(p.name)
44
- ) {
45
- return {
46
- ...p,
47
- renderChunk: undefined,
48
- }
49
- }
50
- }
51
-
52
- return p
53
- })
54
- .filter((p) => p !== null)
55
- }