vxrn 2.9.2 → 2.11.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.
- package/dist/config/getBaseVitePlugins.mjs +3 -1
- package/dist/config/getBaseVitePlugins.mjs.map +1 -1
- package/dist/config/getBaseVitePlugins.native.js +3 -1
- package/dist/config/getBaseVitePlugins.native.js.map +1 -1
- package/dist/constants.mjs +23 -1
- package/dist/constants.mjs.map +1 -1
- package/dist/constants.native.js +23 -1
- package/dist/constants.native.js.map +1 -1
- package/dist/exports/build.mjs +11 -12
- package/dist/exports/build.mjs.map +1 -1
- package/dist/exports/build.native.js +11 -12
- package/dist/exports/build.native.js.map +1 -1
- package/dist/exports/prebuildWithoutExpo.mjs +16 -1
- package/dist/exports/prebuildWithoutExpo.mjs.map +1 -1
- package/dist/exports/prebuildWithoutExpo.native.js +16 -1
- package/dist/exports/prebuildWithoutExpo.native.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.mjs +2 -1
- package/dist/index.native.js +2 -1
- package/dist/plugins/reactNativeDevServer.mjs +7 -5
- package/dist/plugins/reactNativeDevServer.mjs.map +1 -1
- package/dist/plugins/reactNativeDevServer.native.js +8 -5
- package/dist/plugins/reactNativeDevServer.native.js.map +1 -1
- package/dist/rn-commands/bundle/buildBundle.mjs +9 -0
- package/dist/rn-commands/bundle/buildBundle.mjs.map +1 -1
- package/dist/rn-commands/bundle/buildBundle.native.js +9 -0
- package/dist/rn-commands/bundle/buildBundle.native.js.map +1 -1
- package/dist/runtime/native-prelude.mjs +7 -1
- package/dist/runtime/native-prelude.mjs.map +1 -1
- package/dist/runtime/native-prelude.native.js +7 -1
- package/dist/runtime/native-prelude.native.js.map +1 -1
- package/dist/utils/compileNativeDevBytecode.mjs +13 -3
- package/dist/utils/compileNativeDevBytecode.mjs.map +1 -1
- package/dist/utils/compileNativeDevBytecode.native.js +13 -3
- package/dist/utils/compileNativeDevBytecode.native.js.map +1 -1
- package/dist/utils/createNativeDevEngine.mjs +375 -173
- package/dist/utils/createNativeDevEngine.mjs.map +1 -1
- package/dist/utils/createNativeDevEngine.native.js +429 -193
- package/dist/utils/createNativeDevEngine.native.js.map +1 -1
- package/dist/utils/environmentUtils.mjs +1 -1
- package/dist/utils/environmentUtils.mjs.map +1 -1
- package/dist/utils/environmentUtils.native.js +1 -1
- package/dist/utils/environmentUtils.native.js.map +1 -1
- package/dist/utils/scanDepsToOptimize.mjs +37 -15
- package/dist/utils/scanDepsToOptimize.mjs.map +1 -1
- package/dist/utils/scanDepsToOptimize.native.js +45 -15
- package/dist/utils/scanDepsToOptimize.native.js.map +1 -1
- package/package.json +13 -13
- package/src/config/getBaseVitePlugins.ts +2 -0
- package/src/constants.ts +24 -0
- package/src/exports/build.lifecycle.test.ts +152 -0
- package/src/exports/build.ts +16 -14
- package/src/exports/prebuildWithoutExpo.ts +16 -1
- package/src/index.ts +1 -0
- package/src/plugins/reactNativeCommonJsPlugin.ts +1 -1
- package/src/plugins/reactNativeDevServer.ts +19 -8
- package/src/rn-commands/bundle/buildBundle.ts +13 -1
- package/src/runtime/native-prelude.ts +7 -1
- package/src/types.ts +1 -1
- package/src/utils/compileNativeDevBytecode.test.ts +8 -8
- package/src/utils/compileNativeDevBytecode.ts +22 -2
- package/src/utils/createNativeDevEngine.test.ts +52 -25
- package/src/utils/createNativeDevEngine.ts +567 -254
- package/src/utils/environmentUtils.ts +6 -1
- package/src/utils/scanDepsToOptimize.test.ts +46 -2
- package/src/utils/scanDepsToOptimize.ts +78 -18
- package/types/config/getBaseVitePlugins.d.ts.map +1 -1
- package/types/constants.d.ts +2 -0
- package/types/constants.d.ts.map +1 -1
- package/types/exports/build.d.ts.map +1 -1
- package/types/exports/prebuildWithoutExpo.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/plugins/reactNativeDevServer.d.ts.map +1 -1
- package/types/rn-commands/bundle/buildBundle.d.ts.map +1 -1
- package/types/runtime/native-prelude.d.ts.map +1 -1
- package/types/types.d.ts +1 -1
- package/types/types.d.ts.map +1 -1
- package/types/utils/compileNativeDevBytecode.d.ts +2 -1
- package/types/utils/compileNativeDevBytecode.d.ts.map +1 -1
- package/types/utils/createNativeDevEngine.d.ts +11 -5
- package/types/utils/createNativeDevEngine.d.ts.map +1 -1
- package/types/utils/environmentUtils.d.ts.map +1 -1
- package/types/utils/scanDepsToOptimize.d.ts.map +1 -1
|
@@ -7,6 +7,7 @@ import { parseSync } from "oxc-parser";
|
|
|
7
7
|
import { loadEnv, normalizePath } from "vite";
|
|
8
8
|
import { shouldStripFlow, transformHermesAsync } from "@vxrn/compiler";
|
|
9
9
|
import { resolvePath } from "@vxrn/resolve";
|
|
10
|
+
import { desktopReactNativeFile, requireOnePackageRoot } from "@vxrn/utils/desktopReactNativeResolve";
|
|
10
11
|
import { nativeAppDefines } from "@vxrn/utils/nativeAppManifest";
|
|
11
12
|
import { withExpoPublicEnvAliases } from "@vxrn/utils/publicEnv";
|
|
12
13
|
import { DEFAULT_ASSET_EXTS } from "../constants/defaults.mjs";
|
|
@@ -27,37 +28,52 @@ const HERMES_ASYNC_TRANSFORMS = ["transform-async-to-generator"];
|
|
|
27
28
|
function getHermesSWCIncludes(dev) {
|
|
28
29
|
return [...HERMES_CLASS_TRANSFORMS, ...HERMES_ASYNC_TRANSFORMS];
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const NATIVE_PLATFORM_EXTENSIONS = {
|
|
32
|
+
ios: [
|
|
32
33
|
".ios.tsx",
|
|
33
34
|
".ios.ts",
|
|
34
35
|
".ios.jsx",
|
|
35
36
|
".ios.js"
|
|
36
|
-
]
|
|
37
|
+
],
|
|
38
|
+
android: [
|
|
37
39
|
".android.tsx",
|
|
38
40
|
".android.ts",
|
|
39
41
|
".android.jsx",
|
|
40
42
|
".android.js"
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
".
|
|
44
|
-
".
|
|
45
|
-
".
|
|
46
|
-
".
|
|
47
|
-
]
|
|
48
|
-
|
|
49
|
-
".tsx",
|
|
50
|
-
".ts",
|
|
51
|
-
".jsx",
|
|
52
|
-
".js"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
43
|
+
],
|
|
44
|
+
macos: [
|
|
45
|
+
".macos.tsx",
|
|
46
|
+
".macos.ts",
|
|
47
|
+
".macos.jsx",
|
|
48
|
+
".macos.js"
|
|
49
|
+
],
|
|
50
|
+
linux: [
|
|
51
|
+
".linux.tsx",
|
|
52
|
+
".linux.ts",
|
|
53
|
+
".linux.jsx",
|
|
54
|
+
".linux.js"
|
|
55
|
+
]
|
|
56
|
+
};
|
|
57
|
+
const NATIVE_SHARED_EXTENSIONS = [
|
|
58
|
+
".native.tsx",
|
|
59
|
+
".native.ts",
|
|
60
|
+
".native.jsx",
|
|
61
|
+
".native.js"
|
|
62
|
+
];
|
|
63
|
+
const PLAIN_EXTENSIONS = [
|
|
64
|
+
".tsx",
|
|
65
|
+
".ts",
|
|
66
|
+
".jsx",
|
|
67
|
+
".js",
|
|
68
|
+
".mjs",
|
|
69
|
+
".cjs",
|
|
70
|
+
".json"
|
|
71
|
+
];
|
|
72
|
+
function getResolveExtensions(platform) {
|
|
57
73
|
return [
|
|
58
|
-
...
|
|
59
|
-
...
|
|
60
|
-
...
|
|
74
|
+
...NATIVE_PLATFORM_EXTENSIONS[platform],
|
|
75
|
+
...NATIVE_SHARED_EXTENSIONS,
|
|
76
|
+
...PLAIN_EXTENSIONS
|
|
61
77
|
];
|
|
62
78
|
}
|
|
63
79
|
function getNativeResolveConfig(platform) {
|
|
@@ -153,14 +169,112 @@ function getNativeTransformConfig(platform, dev, root) {
|
|
|
153
169
|
inject: { React: "react" }
|
|
154
170
|
};
|
|
155
171
|
}
|
|
156
|
-
function
|
|
172
|
+
function desktopReactNativeResolvePlugin(root, platform) {
|
|
173
|
+
const oneRoot = requireOnePackageRoot(root, platform);
|
|
174
|
+
return {
|
|
175
|
+
name: `vxrn:${platform}-react-native-resolve`,
|
|
176
|
+
resolveId(source, importer) {
|
|
177
|
+
if (!importer) return;
|
|
178
|
+
const file = desktopReactNativeFile(importer, source, oneRoot, platform);
|
|
179
|
+
if (file) return file;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
const PLATFORM_VARIANT_EXTS = [
|
|
184
|
+
".ios.tsx",
|
|
185
|
+
".ios.ts",
|
|
186
|
+
".ios.jsx",
|
|
187
|
+
".ios.js",
|
|
188
|
+
".android.tsx",
|
|
189
|
+
".android.ts",
|
|
190
|
+
".android.jsx",
|
|
191
|
+
".android.js",
|
|
192
|
+
".web.tsx",
|
|
193
|
+
".web.ts",
|
|
194
|
+
".web.jsx",
|
|
195
|
+
".web.js"
|
|
196
|
+
];
|
|
197
|
+
function desktopNormalFile(target, source, platform) {
|
|
198
|
+
if (/\.(?:tsx|ts|jsx|js|mjs|cjs|json)$/.test(source)) return existsSync(target);
|
|
199
|
+
const extensions = getResolveExtensions(platform);
|
|
200
|
+
for (const ext of extensions) {
|
|
201
|
+
if (existsSync(target + ext)) return true;
|
|
202
|
+
if (existsSync(join(target, "index" + ext))) return true;
|
|
203
|
+
}
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
function desktopVariantSource(target) {
|
|
207
|
+
for (const ext of PLATFORM_VARIANT_EXTS) {
|
|
208
|
+
const file = target + ext;
|
|
209
|
+
if (existsSync(file)) return file;
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
function desktopPackageImportLabel(variantFile) {
|
|
214
|
+
let dir = dirname(variantFile);
|
|
215
|
+
for (let i = 0; i < 8; i++) {
|
|
216
|
+
const manifest = join(dir, "package.json");
|
|
217
|
+
if (existsSync(manifest)) try {
|
|
218
|
+
const name = JSON.parse(readFileSync(manifest, "utf8")).name;
|
|
219
|
+
if (typeof name === "string" && name.length > 0) return `${name}/${relative(dir, variantFile).split("\\").join("/").replace(/\.(?:ios|android|web)\.(?:tsx|ts|jsx|js)$/, "")}`;
|
|
220
|
+
} catch {}
|
|
221
|
+
const parent = dirname(dir);
|
|
222
|
+
if (parent === dir) break;
|
|
223
|
+
dir = parent;
|
|
224
|
+
}
|
|
225
|
+
return variantFile;
|
|
226
|
+
}
|
|
227
|
+
function desktopUnsupportedImportPlugin(platform) {
|
|
228
|
+
const label = platform === "macos" ? "macOS" : "Linux";
|
|
229
|
+
return {
|
|
230
|
+
name: `vxrn:${platform}-unsupported-import`,
|
|
231
|
+
onLog(_level, log) {
|
|
232
|
+
if (log.code === "UNRESOLVED_IMPORT") this.error({
|
|
233
|
+
...log,
|
|
234
|
+
message: `[vxrn] ${label} bundle cannot resolve an import: ${log.message}`
|
|
235
|
+
});
|
|
236
|
+
},
|
|
237
|
+
resolveId(source, importer) {
|
|
238
|
+
if (!importer || !source.startsWith(".") || source.includes("\0")) return;
|
|
239
|
+
if (source.includes("?") || source.includes("#")) return;
|
|
240
|
+
const target = resolve(dirname(importer), source);
|
|
241
|
+
if (desktopNormalFile(target, source, platform)) return;
|
|
242
|
+
const variant = desktopVariantSource(target);
|
|
243
|
+
if (!variant) return;
|
|
244
|
+
this.error(`[vxrn] ${desktopPackageImportLabel(variant)} has no ${label} implementation: cannot resolve import "${source}" from "${importer}". Add a .${platform}, .native or plain file.`);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function desktopDistVariantPlugin(platform) {
|
|
249
|
+
return {
|
|
250
|
+
name: `vxrn:${platform}-dist-variant`,
|
|
251
|
+
resolveId(source, importer) {
|
|
252
|
+
if (!importer || !source.startsWith(".") || !source.endsWith(".native.js")) return;
|
|
253
|
+
if (source.endsWith(`.${platform}.native.js`)) return;
|
|
254
|
+
const variant = resolve(dirname(importer), source).replace(/\.native\.js$/, `.${platform}.native.js`);
|
|
255
|
+
if (variant === importer || !existsSync(variant)) return;
|
|
256
|
+
return variant;
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest, onAsset, sourceMaps = false, userPlugins = [], minify = false, command = "serve") {
|
|
157
261
|
const context = {
|
|
158
262
|
root,
|
|
159
263
|
platform,
|
|
160
|
-
dev
|
|
264
|
+
dev,
|
|
265
|
+
command,
|
|
266
|
+
assetsDest
|
|
161
267
|
};
|
|
162
|
-
|
|
163
|
-
|
|
268
|
+
const desktopPlugins = platform === "macos" || platform === "linux" ? [
|
|
269
|
+
desktopReactNativeResolvePlugin(root, platform),
|
|
270
|
+
desktopDistVariantPlugin(platform),
|
|
271
|
+
desktopUnsupportedImportPlugin(platform)
|
|
272
|
+
] : [];
|
|
273
|
+
const globalPlugins = globalThis.__vxrnAddNativePlugins?.(platform) || [];
|
|
274
|
+
const trace = dev && command === "serve" ? [...globalPlugins, ...userPlugins].find((plugin) => plugin.api?.vxrnNativeCompilerTrace)?.api.vxrnNativeCompilerTrace : void 0;
|
|
275
|
+
const plugins = [
|
|
276
|
+
...desktopPlugins,
|
|
277
|
+
...globalPlugins,
|
|
164
278
|
serverFileExclusionPlugin(),
|
|
165
279
|
environmentGuardPlugin(),
|
|
166
280
|
missingDynamicImportPlugin(),
|
|
@@ -173,7 +287,7 @@ function getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest,
|
|
|
173
287
|
viteImportGlobPlugin({ root }),
|
|
174
288
|
rnCodegenPlugin({ projectRoot: root }),
|
|
175
289
|
flowStripPlugin(),
|
|
176
|
-
vxrnCompilerPlugin(platform, dev, root, sourceMaps),
|
|
290
|
+
vxrnCompilerPlugin(platform, dev, root, sourceMaps, trace),
|
|
177
291
|
mixedNativeModulePlugin(sourceMaps),
|
|
178
292
|
nativeAnimatedGuardPlugin(),
|
|
179
293
|
assetPlugin({
|
|
@@ -188,6 +302,55 @@ function getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest,
|
|
|
188
302
|
nativeExportsPrecedencePlugin(root, platform),
|
|
189
303
|
nativeDeclarationAliasPlugin(root, platform)
|
|
190
304
|
].map((plugin) => plugin.api?.vxrnNative ? plugin.api.vxrnNative(context) : plugin);
|
|
305
|
+
if (!trace) return plugins;
|
|
306
|
+
const start = (id, stage) => {
|
|
307
|
+
try {
|
|
308
|
+
const record = trace(id);
|
|
309
|
+
if (!record) return;
|
|
310
|
+
const mark = (status) => {
|
|
311
|
+
try {
|
|
312
|
+
record(stage, status);
|
|
313
|
+
} catch {}
|
|
314
|
+
};
|
|
315
|
+
mark("start");
|
|
316
|
+
return mark;
|
|
317
|
+
} catch {}
|
|
318
|
+
};
|
|
319
|
+
return [{
|
|
320
|
+
name: "test-native-hmr-trace-first-pre",
|
|
321
|
+
transform: {
|
|
322
|
+
order: "pre",
|
|
323
|
+
handler(_code, id) {
|
|
324
|
+
start(id, "pre:first")?.("end");
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}, ...plugins.map((plugin, index) => {
|
|
329
|
+
if (plugin.name !== "one:use-dom-native" && plugin.name !== "vxrn:rn-codegen" && plugin.name !== "one:background-computation:native" && plugin.name !== "one-client-tree-shake") return plugin;
|
|
330
|
+
const hook = plugin.transform;
|
|
331
|
+
if (!hook || typeof hook === "function" || hook.order !== "pre") return plugin;
|
|
332
|
+
return {
|
|
333
|
+
...plugin,
|
|
334
|
+
transform: {
|
|
335
|
+
...hook,
|
|
336
|
+
handler(...args) {
|
|
337
|
+
const mark = start(args[1], `pre:${index}:${plugin.name}`);
|
|
338
|
+
if (!mark) return hook.handler.apply(this, args);
|
|
339
|
+
try {
|
|
340
|
+
const result = hook.handler.apply(this, args);
|
|
341
|
+
if (result instanceof Promise) try {
|
|
342
|
+
Promise.prototype.then.call(result, () => mark("end"), () => mark("error"));
|
|
343
|
+
} catch {}
|
|
344
|
+
else mark("end");
|
|
345
|
+
return result;
|
|
346
|
+
} catch (error) {
|
|
347
|
+
mark("error");
|
|
348
|
+
throw error;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
})];
|
|
191
354
|
}
|
|
192
355
|
function getNativeOutputOptions(prelude, sourcemap, minify) {
|
|
193
356
|
return {
|
|
@@ -312,19 +475,19 @@ function postProcessNativeBundle(code) {
|
|
|
312
475
|
}
|
|
313
476
|
return code;
|
|
314
477
|
}
|
|
478
|
+
const NATIVE_MODULE_SCOPE_MARKER = "// vxrn: native module scope";
|
|
479
|
+
const NATIVE_DEV_RUNTIME_END = "globalThis.__rolldown_runtime__ = new ReactNativeDevRuntime();";
|
|
315
480
|
function wrapNativeBundleModuleScope(code) {
|
|
316
|
-
const idx = code.indexOf(
|
|
317
|
-
if (idx === -1)
|
|
481
|
+
const idx = code.indexOf(NATIVE_MODULE_SCOPE_MARKER);
|
|
482
|
+
if (idx === -1) throw new Error("[vxrn] the dev bundle lost the end of its prelude, so its modules would run at script scope");
|
|
318
483
|
return code.slice(0, idx) + ";(function() {" + code.slice(idx) + "\n})();\n";
|
|
319
484
|
}
|
|
320
485
|
async function downlevelClassFieldsInBundle(code) {
|
|
321
|
-
const
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
const
|
|
326
|
-
if (endIdx === -1) return code;
|
|
327
|
-
const runtimeEnd = endIdx + 12;
|
|
486
|
+
const markerIdx = code.indexOf(NATIVE_MODULE_SCOPE_MARKER);
|
|
487
|
+
const endIdx = markerIdx === -1 ? -1 : code.indexOf(NATIVE_DEV_RUNTIME_END, markerIdx);
|
|
488
|
+
if (endIdx === -1) throw new Error("[vxrn] could not locate the rolldown runtime in the dev bundle");
|
|
489
|
+
const startIdx = code.indexOf("\n", markerIdx) + 1;
|
|
490
|
+
const runtimeEnd = endIdx + 62;
|
|
328
491
|
const runtimeSection = code.slice(startIdx, runtimeEnd);
|
|
329
492
|
const originalNewlines = runtimeSection.match(/\n/g)?.length ?? 0;
|
|
330
493
|
const { transformSync } = await import("oxc-transform");
|
|
@@ -333,19 +496,17 @@ async function downlevelClassFieldsInBundle(code) {
|
|
|
333
496
|
assumptions: { setPublicClassFields: true }
|
|
334
497
|
});
|
|
335
498
|
if (result.errors?.length) throw new Error(result.errors.map((e) => e.message).join("\n"));
|
|
336
|
-
const
|
|
337
|
-
const transformed = transformedCode.includes(startMarker) ? transformedCode : `${startMarker}
|
|
338
|
-
${transformedCode}`;
|
|
499
|
+
const transformed = result.code.trimEnd();
|
|
339
500
|
const transformedNewlines = transformed.match(/\n/g)?.length ?? 0;
|
|
340
|
-
if (transformedNewlines > originalNewlines) throw new Error("[vxrn] Hermes runtime transform added lines and would invalidate the
|
|
501
|
+
if (transformedNewlines > originalNewlines) throw new Error("[vxrn] Hermes runtime transform added lines and would invalidate the dev source map");
|
|
341
502
|
const linePreservingRuntime = transformed + "\n".repeat(originalNewlines - transformedNewlines);
|
|
342
503
|
return code.slice(0, startIdx) + linePreservingRuntime + code.slice(runtimeEnd);
|
|
343
504
|
}
|
|
344
505
|
function nativeBundlePostProcessPlugin() {
|
|
345
506
|
return {
|
|
346
507
|
name: "vxrn:native-post-process",
|
|
347
|
-
|
|
348
|
-
const processed =
|
|
508
|
+
renderChunk(code) {
|
|
509
|
+
const processed = postProcessNativeBundle(code);
|
|
349
510
|
assertBundleLinesPreserved(code, processed, "production");
|
|
350
511
|
return {
|
|
351
512
|
code: processed,
|
|
@@ -401,7 +562,8 @@ async function createNativeDevEngine(options) {
|
|
|
401
562
|
plugins: [virtualEntry.plugin, ...getNativePlugins(root, platform, viteImportGlobPlugin, true, void 0, assetRegistry.register, true, userPlugins)]
|
|
402
563
|
};
|
|
403
564
|
const outputOptions = {
|
|
404
|
-
...getNativeOutputOptions(prelude
|
|
565
|
+
...getNativeOutputOptions(`${prelude}
|
|
566
|
+
${NATIVE_MODULE_SCOPE_MARKER}`, true, false),
|
|
405
567
|
outro: `
|
|
406
568
|
try {
|
|
407
569
|
var __WS = (init_WebSocket(), __toCommonJS(WebSocket_exports)).default;
|
|
@@ -493,6 +655,7 @@ try {
|
|
|
493
655
|
code = postProcessNativeBundle(chunk.code);
|
|
494
656
|
code = await downlevelClassFieldsInBundle(code);
|
|
495
657
|
assertBundleLinesPreserved(chunk.code, code, "dev");
|
|
658
|
+
code = wrapNativeBundleModuleScope(code);
|
|
496
659
|
} catch (error) {
|
|
497
660
|
const failure = error instanceof Error ? error : new Error(String(error));
|
|
498
661
|
console.error("[vxrn] native bundle post-processing failed:", failure.message);
|
|
@@ -508,7 +671,6 @@ try {
|
|
|
508
671
|
}
|
|
509
672
|
return;
|
|
510
673
|
}
|
|
511
|
-
code = wrapNativeBundleModuleScope(code);
|
|
512
674
|
if (!chunk.map) throw new Error("[vxrn] rolldown produced no source map for the dev bundle, so /symbolicate cannot resolve a frame");
|
|
513
675
|
currentBundle = {
|
|
514
676
|
code,
|
|
@@ -612,7 +774,7 @@ async function buildNativeBundle(options) {
|
|
|
612
774
|
dev,
|
|
613
775
|
platform
|
|
614
776
|
}).plugin],
|
|
615
|
-
...getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest, void 0, sourcemap, userPlugins, minify),
|
|
777
|
+
...getNativePlugins(root, platform, viteImportGlobPlugin, dev, assetsDest, void 0, sourcemap, userPlugins, minify, "build"),
|
|
616
778
|
nativeBundlePostProcessPlugin()
|
|
617
779
|
],
|
|
618
780
|
output: {
|
|
@@ -639,7 +801,8 @@ function nativeVirtualEntryPlugin(root, opts) {
|
|
|
639
801
|
const setupFileImport = (() => {
|
|
640
802
|
const sf = entryConfig.setupFile;
|
|
641
803
|
if (!sf) return "";
|
|
642
|
-
const
|
|
804
|
+
const perPlatform = sf;
|
|
805
|
+
const file = typeof sf === "string" ? sf : "native" in sf ? sf.native : opts.platform === "macos" || opts.platform === "linux" ? perPlatform[opts.platform] : sf.ios;
|
|
643
806
|
if (!file) return "";
|
|
644
807
|
const resolved = pathToFileURL(resolve(root, file)).href;
|
|
645
808
|
return `import ${JSON.stringify(resolved)};`;
|
|
@@ -1084,7 +1247,7 @@ function cssStubPlugin() {
|
|
|
1084
1247
|
} }
|
|
1085
1248
|
};
|
|
1086
1249
|
}
|
|
1087
|
-
function vxrnCompilerPlugin(platform, dev, projectRoot = process.cwd(), sourceMaps = false) {
|
|
1250
|
+
function vxrnCompilerPlugin(platform, dev, projectRoot = process.cwd(), sourceMaps = false, trace) {
|
|
1088
1251
|
let compiler = null;
|
|
1089
1252
|
const isRefreshCandidate = (id) => dev && !id.includes("node_modules") && !id.includes("__virtual-native-entry") && /\.[tj]sx?$/.test(id);
|
|
1090
1253
|
return {
|
|
@@ -1092,93 +1255,92 @@ function vxrnCompilerPlugin(platform, dev, projectRoot = process.cwd(), sourceMa
|
|
|
1092
1255
|
async transform(code, id) {
|
|
1093
1256
|
if (!/\.[cm]?[jt]sx?$/.test(id)) return;
|
|
1094
1257
|
if (id.includes("\0") || id.includes("virtual:")) return;
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
const workletPluginOptions = Array.isArray(workletEntry) ? workletEntry[1] : void 0;
|
|
1115
|
-
const useWorklets = compiler.isNativeWorkletsEnabled() && (Boolean(workletEntry) || compiler.shouldTransformWorklets({
|
|
1116
|
-
id,
|
|
1117
|
-
code
|
|
1118
|
-
}));
|
|
1119
|
-
const compilerPluginIndex = babelOptions?.plugins?.findIndex((x) => Array.isArray(x) && x[0] === "babel-plugin-react-compiler") ?? -1;
|
|
1120
|
-
if (compilerPluginIndex !== -1) {
|
|
1121
|
-
if (useWorklets) {
|
|
1122
|
-
const prepared = compiler.prepareWorkletsForReactCompiler(id, curCode, sourceMaps);
|
|
1123
|
-
if (prepared) {
|
|
1124
|
-
curCode = prepared.code;
|
|
1125
|
-
if (prepared.map) intermediateMaps.push(prepared.map);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
const compilerPluginOptions = babelOptions.plugins[compilerPluginIndex][1] || {};
|
|
1129
|
-
if (!(compilerPluginOptions.compiler === "babel" || process.env.ONE_REACT_COMPILER === "babel" || process.env.VXRN_REACT_COMPILER === "babel")) {
|
|
1130
|
-
const compilerOut = await compiler.transformOxcReactCompiler(id, curCode, compilerPluginOptions, sourceMaps);
|
|
1131
|
-
if (compilerOut?.code) {
|
|
1132
|
-
curCode = compilerOut.code;
|
|
1133
|
-
if (sourceMaps && compilerOut.map) intermediateMaps.push(compilerOut.map);
|
|
1134
|
-
}
|
|
1135
|
-
babelOptions.plugins.splice(compilerPluginIndex, 1);
|
|
1136
|
-
if (babelOptions.plugins.length === 0 && !babelOptions.configFile && !babelOptions.babelrc) babelOptions = null;
|
|
1258
|
+
let active = "transform";
|
|
1259
|
+
let failed = false;
|
|
1260
|
+
let mark;
|
|
1261
|
+
if (trace) try {
|
|
1262
|
+
const record = trace(id);
|
|
1263
|
+
if (record) mark = (stage, status) => {
|
|
1264
|
+
active = status === "start" ? stage : "transform";
|
|
1265
|
+
try {
|
|
1266
|
+
record(stage, status);
|
|
1267
|
+
} catch {}
|
|
1268
|
+
};
|
|
1269
|
+
} catch {}
|
|
1270
|
+
mark?.("transform", "start");
|
|
1271
|
+
try {
|
|
1272
|
+
const needsRefresh = isRefreshCandidate(id);
|
|
1273
|
+
if (!compiler) {
|
|
1274
|
+
mark?.("compiler-import", "start");
|
|
1275
|
+
compiler = await import("@vxrn/compiler");
|
|
1276
|
+
mark?.("compiler-import", "end");
|
|
1137
1277
|
}
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1278
|
+
const props = {
|
|
1279
|
+
id,
|
|
1280
|
+
code,
|
|
1141
1281
|
projectRoot,
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1282
|
+
development: dev,
|
|
1283
|
+
environment: platform === "android" ? "android" : "ios",
|
|
1284
|
+
reactForRNVersion: "19"
|
|
1285
|
+
};
|
|
1286
|
+
mark?.("options", "start");
|
|
1287
|
+
let babelOptions = compiler.getBabelOptions(props);
|
|
1288
|
+
mark?.("options", "end");
|
|
1289
|
+
let curCode = code;
|
|
1290
|
+
const intermediateMaps = [];
|
|
1291
|
+
const isWorkletPlugin = (entry) => {
|
|
1292
|
+
if (!entry) return false;
|
|
1293
|
+
const name = typeof entry === "string" ? entry : Array.isArray(entry) ? entry[0] : null;
|
|
1294
|
+
return typeof name === "string" && (name.includes("react-native-worklets") || name.includes("react-native-reanimated"));
|
|
1295
|
+
};
|
|
1296
|
+
const workletEntry = babelOptions?.plugins?.find(isWorkletPlugin);
|
|
1297
|
+
const workletPluginOptions = Array.isArray(workletEntry) ? workletEntry[1] : void 0;
|
|
1298
|
+
const useWorklets = compiler.isNativeWorkletsEnabled() && (Boolean(workletEntry) || compiler.shouldTransformWorklets({
|
|
1299
|
+
id,
|
|
1300
|
+
code
|
|
1301
|
+
}));
|
|
1302
|
+
const compilerPluginIndex = babelOptions?.plugins?.findIndex((x) => Array.isArray(x) && x[0] === "babel-plugin-react-compiler") ?? -1;
|
|
1303
|
+
if (compilerPluginIndex !== -1) {
|
|
1304
|
+
if (useWorklets) {
|
|
1305
|
+
mark?.("worklets-prepare", "start");
|
|
1306
|
+
const prepared = compiler.prepareWorkletsForReactCompiler(id, curCode, sourceMaps);
|
|
1307
|
+
mark?.("worklets-prepare", "end");
|
|
1308
|
+
if (prepared) {
|
|
1309
|
+
curCode = prepared.code;
|
|
1310
|
+
if (prepared.map) intermediateMaps.push(prepared.map);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
const compilerPluginOptions = babelOptions.plugins[compilerPluginIndex][1] || {};
|
|
1314
|
+
if (!(compilerPluginOptions.compiler === "babel" || process.env.ONE_REACT_COMPILER === "babel" || process.env.VXRN_REACT_COMPILER === "babel")) {
|
|
1315
|
+
mark?.("oxc-react-compiler", "start");
|
|
1316
|
+
const compilerOut = await compiler.transformOxcReactCompiler(id, curCode, compilerPluginOptions, sourceMaps);
|
|
1317
|
+
mark?.("oxc-react-compiler", "end");
|
|
1318
|
+
if (compilerOut?.code) {
|
|
1319
|
+
curCode = compilerOut.code;
|
|
1320
|
+
if (sourceMaps && compilerOut.map) intermediateMaps.push(compilerOut.map);
|
|
1321
|
+
}
|
|
1322
|
+
babelOptions.plugins.splice(compilerPluginIndex, 1);
|
|
1323
|
+
if (babelOptions.plugins.length === 0 && !babelOptions.configFile && !babelOptions.babelrc) babelOptions = null;
|
|
1324
|
+
}
|
|
1151
1325
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1326
|
+
if (useWorklets) {
|
|
1327
|
+
mark?.("worklets", "start");
|
|
1328
|
+
const workletOut = await compiler.transformWorklets(id, curCode, sourceMaps, {
|
|
1329
|
+
projectRoot,
|
|
1330
|
+
...workletPluginOptions
|
|
1331
|
+
});
|
|
1332
|
+
mark?.("worklets", "end");
|
|
1333
|
+
if (workletOut?.code) {
|
|
1334
|
+
curCode = workletOut.code;
|
|
1335
|
+
if (sourceMaps && workletOut.map) intermediateMaps.push(workletOut.map);
|
|
1336
|
+
}
|
|
1337
|
+
if (babelOptions?.plugins) {
|
|
1338
|
+
babelOptions.plugins = babelOptions.plugins.filter((entry) => !isWorkletPlugin(entry));
|
|
1339
|
+
if (babelOptions.plugins.length === 0 && !babelOptions.configFile && !babelOptions.babelrc) babelOptions = null;
|
|
1160
1340
|
}
|
|
1161
|
-
return {
|
|
1162
|
-
code: curCode,
|
|
1163
|
-
map: finalMap
|
|
1164
|
-
};
|
|
1165
1341
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
if (sourceMaps && babelOptions) {
|
|
1169
|
-
babelOptions = {
|
|
1170
|
-
...babelOptions,
|
|
1171
|
-
sourceMaps: true,
|
|
1172
|
-
sourceFileName: id
|
|
1173
|
-
};
|
|
1174
|
-
delete babelOptions.inputSourceMap;
|
|
1175
|
-
}
|
|
1176
|
-
if (babelOptions) {
|
|
1177
|
-
const result = await compiler.transformBabel(id, curCode, babelOptions);
|
|
1178
|
-
if (result?.code) {
|
|
1179
|
-
curCode = result.code;
|
|
1180
|
-
if (sourceMaps && result.map) intermediateMaps.push(result.map);
|
|
1181
|
-
if (!needsRefresh) {
|
|
1342
|
+
if (!babelOptions && !needsRefresh) {
|
|
1343
|
+
if (curCode !== code) {
|
|
1182
1344
|
let finalMap = void 0;
|
|
1183
1345
|
if (sourceMaps && intermediateMaps.length > 0) if (intermediateMaps.length === 1) finalMap = intermediateMaps[0];
|
|
1184
1346
|
else {
|
|
@@ -1190,26 +1352,59 @@ function vxrnCompilerPlugin(platform, dev, projectRoot = process.cwd(), sourceMa
|
|
|
1190
1352
|
map: finalMap
|
|
1191
1353
|
};
|
|
1192
1354
|
}
|
|
1355
|
+
return;
|
|
1193
1356
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1357
|
+
if (sourceMaps && babelOptions) {
|
|
1358
|
+
babelOptions = {
|
|
1359
|
+
...babelOptions,
|
|
1360
|
+
sourceMaps: true,
|
|
1361
|
+
sourceFileName: id
|
|
1362
|
+
};
|
|
1363
|
+
delete babelOptions.inputSourceMap;
|
|
1364
|
+
}
|
|
1365
|
+
if (babelOptions) {
|
|
1366
|
+
mark?.("babel", "start");
|
|
1367
|
+
const result = await compiler.transformBabel(id, curCode, babelOptions);
|
|
1368
|
+
mark?.("babel", "end");
|
|
1369
|
+
if (result?.code) {
|
|
1370
|
+
curCode = result.code;
|
|
1371
|
+
if (sourceMaps && result.map) intermediateMaps.push(result.map);
|
|
1372
|
+
if (!needsRefresh) {
|
|
1373
|
+
let finalMap = void 0;
|
|
1374
|
+
if (sourceMaps && intermediateMaps.length > 0) if (intermediateMaps.length === 1) finalMap = intermediateMaps[0];
|
|
1375
|
+
else {
|
|
1376
|
+
const remapping = (await import("@jridgewell/remapping")).default;
|
|
1377
|
+
finalMap = remapping(intermediateMaps.slice().reverse(), () => null);
|
|
1378
|
+
}
|
|
1379
|
+
return {
|
|
1380
|
+
code: curCode,
|
|
1381
|
+
map: finalMap
|
|
1382
|
+
};
|
|
1206
1383
|
}
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
if (needsRefresh) {
|
|
1387
|
+
mark?.("refresh-import", "start");
|
|
1388
|
+
const { transformSync } = await import("oxc-transform-react");
|
|
1389
|
+
mark?.("refresh-import", "end");
|
|
1390
|
+
const jsxImportSource = compiler.configuration?.enableNativewind && !id.includes("node_modules") ? "nativewind" : "react";
|
|
1391
|
+
mark?.("refresh", "start");
|
|
1392
|
+
const res = transformSync(id, curCode, {
|
|
1393
|
+
jsx: {
|
|
1394
|
+
development: dev,
|
|
1395
|
+
runtime: "automatic",
|
|
1396
|
+
importSource: jsxImportSource,
|
|
1397
|
+
refresh: {
|
|
1398
|
+
refreshReg: "__vxrnRefreshReg",
|
|
1399
|
+
refreshSig: "__vxrnRefreshSig"
|
|
1400
|
+
}
|
|
1401
|
+
},
|
|
1402
|
+
reactCompiler: false,
|
|
1403
|
+
sourcemap: sourceMaps
|
|
1404
|
+
});
|
|
1405
|
+
if (res.fatal) throw new Error(`[vxrn:compiler] oxc react transform failed on ${id}: ${(res.errors ?? []).map((e) => e.message ?? String(e)).join(", ")}`);
|
|
1406
|
+
mark?.("refresh", "end");
|
|
1407
|
+
const header = `var __prevRefreshReg = globalThis.$RefreshReg$;
|
|
1213
1408
|
var __prevRefreshSig = globalThis.$RefreshSig$;
|
|
1214
1409
|
if (globalThis.__ReactRefresh) {
|
|
1215
1410
|
globalThis.$RefreshReg$ = function(type, id) {
|
|
@@ -1222,7 +1417,7 @@ var __vxrnRefreshReg = globalThis.$RefreshReg$;
|
|
|
1222
1417
|
var __vxrnRefreshSig = globalThis.$RefreshSig$;
|
|
1223
1418
|
|
|
1224
1419
|
`;
|
|
1225
|
-
|
|
1420
|
+
const footer = `
|
|
1226
1421
|
|
|
1227
1422
|
globalThis.$RefreshReg$ = __prevRefreshReg;
|
|
1228
1423
|
globalThis.$RefreshSig$ = __prevRefreshSig;
|
|
@@ -1234,29 +1429,36 @@ if (import.meta.hot) {
|
|
|
1234
1429
|
});
|
|
1235
1430
|
}
|
|
1236
1431
|
`;
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1432
|
+
let out;
|
|
1433
|
+
let finalMap = void 0;
|
|
1434
|
+
if (sourceMaps) {
|
|
1435
|
+
const MagicString = (await import("magic-string")).default;
|
|
1436
|
+
const ms = new MagicString(res.code);
|
|
1437
|
+
ms.prepend(header);
|
|
1438
|
+
ms.append(footer);
|
|
1439
|
+
out = ms.toString();
|
|
1440
|
+
const allMaps = [
|
|
1441
|
+
ms.generateMap({
|
|
1442
|
+
source: id,
|
|
1443
|
+
hires: true
|
|
1444
|
+
}),
|
|
1445
|
+
res.map,
|
|
1446
|
+
...intermediateMaps.slice().reverse()
|
|
1447
|
+
].filter(Boolean);
|
|
1448
|
+
const remapping = (await import("@jridgewell/remapping")).default;
|
|
1449
|
+
finalMap = remapping(allMaps, () => null);
|
|
1450
|
+
} else out = header + res.code + footer;
|
|
1451
|
+
return {
|
|
1452
|
+
code: out,
|
|
1453
|
+
map: finalMap
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
} catch (error) {
|
|
1457
|
+
failed = true;
|
|
1458
|
+
if (active !== "transform") mark?.(active, "error");
|
|
1459
|
+
throw error;
|
|
1460
|
+
} finally {
|
|
1461
|
+
mark?.("transform", failed ? "error" : "end");
|
|
1260
1462
|
}
|
|
1261
1463
|
}
|
|
1262
1464
|
};
|
|
@@ -1751,9 +1953,9 @@ class ReactNativeDevRuntime extends BaseDevRuntime {
|
|
|
1751
1953
|
}
|
|
1752
1954
|
}
|
|
1753
1955
|
|
|
1754
|
-
|
|
1956
|
+
${NATIVE_DEV_RUNTIME_END}
|
|
1755
1957
|
`;
|
|
1756
1958
|
}
|
|
1757
1959
|
|
|
1758
|
-
export { buildNativeBundle, createNativeDevAssetRegistry, createNativeDevEngine, getHermesSWCIncludes, getHmrRuntimeSource, getNativeAssetData, getNativeTransformConfig, hermesCompatPlugin, hermesCompatSWCPlugin, hermesLoopsPlugin, hmrClientNoopPlugin, nativeAnimatedGuardPlugin, normalizeNativeCommonJSInterop, postProcessNativeBundle, vxrnCompilerPlugin, wrapNativeBundleModuleScope };
|
|
1960
|
+
export { NATIVE_DEV_RUNTIME_END, NATIVE_MODULE_SCOPE_MARKER, buildNativeBundle, createNativeDevAssetRegistry, createNativeDevEngine, getHermesSWCIncludes, getHmrRuntimeSource, getNativeAssetData, getNativeTransformConfig, hermesCompatPlugin, hermesCompatSWCPlugin, hermesLoopsPlugin, hmrClientNoopPlugin, nativeAnimatedGuardPlugin, normalizeNativeCommonJSInterop, postProcessNativeBundle, vxrnCompilerPlugin, wrapNativeBundleModuleScope };
|
|
1759
1961
|
//# sourceMappingURL=createNativeDevEngine.mjs.map
|