@vxrn/vite-plugin-metro 1.26.0 → 1.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/babel-plugins/import-meta-env-plugin.cjs +14 -25
- package/dist/cjs/babel-plugins/import-meta-env-plugin.native.js +14 -25
- package/dist/cjs/babel-plugins/import-meta-env-plugin.native.js.map +1 -1
- package/dist/cjs/transformer/metroNativeWorker.native.js.map +1 -1
- package/dist/cjs/transformer/metroNativeWorker.test.native.js.map +1 -1
- package/dist/esm/babel-plugins/import-meta-env-plugin.mjs +1 -1
- package/dist/esm/babel-plugins/import-meta-env-plugin.mjs.map +1 -1
- package/dist/esm/babel-plugins/import-meta-env-plugin.native.js +1 -1
- package/dist/esm/babel-plugins/import-meta-env-plugin.native.js.map +1 -1
- package/dist/esm/transformer/metroNativeWorker.mjs.map +1 -1
- package/dist/esm/transformer/metroNativeWorker.native.js.map +1 -1
- package/package.json +4 -5
- package/src/babel-plugins/import-meta-env-plugin.ts +1 -2
- package/src/transformer/metroNativeWorker.test.ts +150 -87
- package/src/transformer/metroNativeWorker.ts +241 -62
- package/types/babel-plugins/import-meta-env-plugin.d.ts +1 -1
- package/types/babel-plugins/import-meta-env-plugin.d.ts.map +1 -1
- package/types/transformer/metroNativeWorker.d.ts.map +1 -1
|
@@ -80,28 +80,45 @@ function assertZeroBabelCalls() {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
describe('metroNativeWorker', () => {
|
|
83
|
-
it.each([
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
83
|
+
it.each([
|
|
84
|
+
['data.json', true],
|
|
85
|
+
['data.json', false],
|
|
86
|
+
['data.js', false],
|
|
87
|
+
] as const)(
|
|
88
|
+
'minifies %s with source maps enabled=%s without stale mappings',
|
|
89
|
+
async (filename, sourceMap) => {
|
|
90
|
+
const result = await transform(
|
|
91
|
+
{
|
|
92
|
+
minifierPath: createRequire(import.meta.url).resolve('metro-minify-terser'),
|
|
93
|
+
minifierConfig: { sourceMap },
|
|
94
|
+
},
|
|
95
|
+
'/project',
|
|
96
|
+
filename,
|
|
97
|
+
Buffer.from(
|
|
98
|
+
filename.endsWith('.json') ? '{"answer":42}' : 'module.exports = { answer: 42 }'
|
|
99
|
+
),
|
|
100
|
+
{ dev: false, minify: true, platform: 'ios', type: 'module' }
|
|
101
|
+
)
|
|
102
|
+
const module = { exports: {} as any }
|
|
103
|
+
const { code, map } = result.output[0].data
|
|
104
|
+
vm.runInNewContext(code, {
|
|
105
|
+
__d(factory: any) {
|
|
106
|
+
factory(
|
|
107
|
+
{},
|
|
108
|
+
() => {},
|
|
109
|
+
() => {},
|
|
110
|
+
() => {},
|
|
111
|
+
module,
|
|
112
|
+
module.exports,
|
|
113
|
+
[]
|
|
114
|
+
)
|
|
115
|
+
},
|
|
116
|
+
})
|
|
117
|
+
expect(module.exports.answer).toBe(42)
|
|
118
|
+
expect(map.every((entry) => entry.length === 2)).toBe(true)
|
|
119
|
+
assertZeroBabelCalls()
|
|
120
|
+
}
|
|
121
|
+
)
|
|
105
122
|
|
|
106
123
|
it('minifies production modules with executable output and original source locations', async () => {
|
|
107
124
|
const source = 'exports.answer = function answer(value) {\n return value + 42\n}\n'
|
|
@@ -119,7 +136,15 @@ describe('metroNativeWorker', () => {
|
|
|
119
136
|
const module = { exports: {} as any }
|
|
120
137
|
vm.runInNewContext(code, {
|
|
121
138
|
__d(factory: any) {
|
|
122
|
-
factory(
|
|
139
|
+
factory(
|
|
140
|
+
{},
|
|
141
|
+
() => {},
|
|
142
|
+
() => {},
|
|
143
|
+
() => {},
|
|
144
|
+
module,
|
|
145
|
+
module.exports,
|
|
146
|
+
[]
|
|
147
|
+
)
|
|
123
148
|
},
|
|
124
149
|
})
|
|
125
150
|
expect(module.exports.answer(8)).toBe(50)
|
|
@@ -207,10 +232,14 @@ describe('metroNativeWorker', () => {
|
|
|
207
232
|
`
|
|
208
233
|
|
|
209
234
|
const off = extractDependencies(code, 'setup.js')
|
|
210
|
-
expect(
|
|
235
|
+
expect(
|
|
236
|
+
off.find((d) => d.name === 'react-native-worklets-core')!.data.isOptional
|
|
237
|
+
).toBeUndefined()
|
|
211
238
|
|
|
212
239
|
const on = extractDependencies(code, 'setup.js', { allowOptionalDependencies: true })
|
|
213
|
-
expect(on.find((d) => d.name === 'react-native-worklets-core')!.data.isOptional).toBe(
|
|
240
|
+
expect(on.find((d) => d.name === 'react-native-worklets-core')!.data.isOptional).toBe(
|
|
241
|
+
true
|
|
242
|
+
)
|
|
214
243
|
expect(on.find((d) => d.name === './always-there')!.data.isOptional).toBeUndefined()
|
|
215
244
|
|
|
216
245
|
const excluded = extractDependencies(code, 'setup.js', {
|
|
@@ -361,7 +390,9 @@ describe('metroNativeWorker', () => {
|
|
|
361
390
|
expect(result.dependencies).toEqual([])
|
|
362
391
|
expect(result.output).toHaveLength(1)
|
|
363
392
|
expect(result.output[0].type).toBe('js/module')
|
|
364
|
-
expect(result.output[0].data.code).toContain(
|
|
393
|
+
expect(result.output[0].data.code).toContain(
|
|
394
|
+
'module.exports = {"name":"my-package","version":"1.0.0"}'
|
|
395
|
+
)
|
|
365
396
|
expect(result.output[0].data.code).toContain('__d(function (global, require')
|
|
366
397
|
})
|
|
367
398
|
|
|
@@ -409,8 +440,14 @@ describe('metroNativeWorker', () => {
|
|
|
409
440
|
})
|
|
410
441
|
|
|
411
442
|
it('generates a deterministic cache key without Babel', () => {
|
|
412
|
-
const key1 = getCacheKey(
|
|
413
|
-
|
|
443
|
+
const key1 = getCacheKey(
|
|
444
|
+
{ globalPrefix: '__one_', minifierPath: 'terser' },
|
|
445
|
+
{ projectRoot: '/app' }
|
|
446
|
+
)
|
|
447
|
+
const key2 = getCacheKey(
|
|
448
|
+
{ globalPrefix: '__one_', minifierPath: 'terser' },
|
|
449
|
+
{ projectRoot: '/app' }
|
|
450
|
+
)
|
|
414
451
|
const key3 = getCacheKey({ globalPrefix: '__other_' }, { projectRoot: '/app' })
|
|
415
452
|
|
|
416
453
|
assertZeroBabelCalls()
|
|
@@ -460,7 +497,8 @@ describe('metroNativeWorker', () => {
|
|
|
460
497
|
// Module 2 (dep.js): exports a value
|
|
461
498
|
// Module 1 (a.js): requires dep.js using Metro dependency ABI and exports computed result
|
|
462
499
|
const depSource = 'exports.value = 42;'
|
|
463
|
-
const aSource =
|
|
500
|
+
const aSource =
|
|
501
|
+
'const dep = require("./dep"); module.exports = { doubled: dep.value * 2 };'
|
|
464
502
|
|
|
465
503
|
// Transform dep.js (Module 2)
|
|
466
504
|
const depRes = await transform(
|
|
@@ -478,19 +516,13 @@ describe('metroNativeWorker', () => {
|
|
|
478
516
|
)
|
|
479
517
|
|
|
480
518
|
// Transform a.js (Module 1) which depends on dep.js (dependency slot 0 -> moduleId 2)
|
|
481
|
-
const aRes = await transform(
|
|
482
|
-
|
|
483
|
-
'
|
|
484
|
-
'
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
platform: 'ios',
|
|
489
|
-
type: 'module',
|
|
490
|
-
moduleId: 1,
|
|
491
|
-
dependencyIds: [2],
|
|
492
|
-
} as any
|
|
493
|
-
)
|
|
519
|
+
const aRes = await transform({}, '/project', 'a.js', Buffer.from(aSource, 'utf8'), {
|
|
520
|
+
dev: false,
|
|
521
|
+
platform: 'ios',
|
|
522
|
+
type: 'module',
|
|
523
|
+
moduleId: 1,
|
|
524
|
+
dependencyIds: [2],
|
|
525
|
+
} as any)
|
|
494
526
|
|
|
495
527
|
assertZeroBabelCalls()
|
|
496
528
|
|
|
@@ -526,7 +558,8 @@ describe('metroNativeWorker', () => {
|
|
|
526
558
|
|
|
527
559
|
it('transforms and executes a 2-module Metro bundle with ESM imports in dev mode', async () => {
|
|
528
560
|
const depSource = 'export const greeting = "Hello Metro Native";'
|
|
529
|
-
const aSource =
|
|
561
|
+
const aSource =
|
|
562
|
+
'import { greeting } from "./dep"; export const message = greeting.toUpperCase();'
|
|
530
563
|
|
|
531
564
|
// Transform dep.js (Module 2)
|
|
532
565
|
const depRes = await transform(
|
|
@@ -544,19 +577,13 @@ describe('metroNativeWorker', () => {
|
|
|
544
577
|
)
|
|
545
578
|
|
|
546
579
|
// Transform a.js (Module 1) depending on dep.js (dependency slot 0 -> moduleId 2)
|
|
547
|
-
const aRes = await transform(
|
|
548
|
-
|
|
549
|
-
'
|
|
550
|
-
'
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
platform: 'ios',
|
|
555
|
-
type: 'module',
|
|
556
|
-
moduleId: 1,
|
|
557
|
-
dependencyIds: [2],
|
|
558
|
-
} as any
|
|
559
|
-
)
|
|
580
|
+
const aRes = await transform({}, '/project', 'a.js', Buffer.from(aSource, 'utf8'), {
|
|
581
|
+
dev: true,
|
|
582
|
+
platform: 'ios',
|
|
583
|
+
type: 'module',
|
|
584
|
+
moduleId: 1,
|
|
585
|
+
dependencyIds: [2],
|
|
586
|
+
} as any)
|
|
560
587
|
|
|
561
588
|
assertZeroBabelCalls()
|
|
562
589
|
|
|
@@ -583,7 +610,8 @@ describe('metroNativeWorker', () => {
|
|
|
583
610
|
// Exact probe from Astra:
|
|
584
611
|
// function f(require){return require("./local")}; module.exports=f(x=>x);
|
|
585
612
|
// require is shadowed by parameter: must NOT extract ./local, and must NOT rewrite require
|
|
586
|
-
const input =
|
|
613
|
+
const input =
|
|
614
|
+
'function f(require){return require("./local")}; module.exports=f(x=>x);'
|
|
587
615
|
|
|
588
616
|
const res = await transform(
|
|
589
617
|
{},
|
|
@@ -635,13 +663,11 @@ describe('metroNativeWorker', () => {
|
|
|
635
663
|
const c = await import('./dep');
|
|
636
664
|
}
|
|
637
665
|
`
|
|
638
|
-
const res = await transform(
|
|
639
|
-
|
|
640
|
-
'
|
|
641
|
-
'
|
|
642
|
-
|
|
643
|
-
{ dev: false, platform: 'ios', type: 'module' }
|
|
644
|
-
)
|
|
666
|
+
const res = await transform({}, '/project', 'index.js', Buffer.from(code, 'utf8'), {
|
|
667
|
+
dev: false,
|
|
668
|
+
platform: 'ios',
|
|
669
|
+
type: 'module',
|
|
670
|
+
})
|
|
645
671
|
|
|
646
672
|
assertZeroBabelCalls()
|
|
647
673
|
|
|
@@ -649,8 +675,12 @@ describe('metroNativeWorker', () => {
|
|
|
649
675
|
const depNames = res.dependencies.map((d) => d.name)
|
|
650
676
|
expect(depNames).toContain('./dep')
|
|
651
677
|
|
|
652
|
-
const syncDep = res.dependencies.find(
|
|
653
|
-
|
|
678
|
+
const syncDep = res.dependencies.find(
|
|
679
|
+
(d) => d.name === './dep' && d.data.asyncType === null
|
|
680
|
+
)!
|
|
681
|
+
const asyncDep = res.dependencies.find(
|
|
682
|
+
(d) => d.name === './dep' && d.data.asyncType === 'async'
|
|
683
|
+
)!
|
|
654
684
|
expect(syncDep).toBeDefined()
|
|
655
685
|
expect(asyncDep).toBeDefined()
|
|
656
686
|
expect(syncDep.data.index).not.toEqual(asyncDep.data.index)
|
|
@@ -721,7 +751,8 @@ describe('metroNativeWorker', () => {
|
|
|
721
751
|
// Exact probe from Astra:
|
|
722
752
|
// function f(){const x=require("./local"); function require(x){return x}; return x} module.exports=f();
|
|
723
753
|
// function require is hoisted to f's function scope, so require("./local") is a local call and needs no module.
|
|
724
|
-
const input =
|
|
754
|
+
const input =
|
|
755
|
+
'function f(){const x=require("./local"); function require(x){return x}; return x} module.exports=f();'
|
|
725
756
|
|
|
726
757
|
const res = await transform(
|
|
727
758
|
{},
|
|
@@ -823,7 +854,10 @@ describe('metroNativeWorker', () => {
|
|
|
823
854
|
const polyfillCode = fs.readFileSync(polyfillPath, 'utf8')
|
|
824
855
|
const asyncRequirePath = require.resolve('metro-runtime/src/modules/asyncRequire.js')
|
|
825
856
|
const asyncRequireSource = fs.readFileSync(asyncRequirePath, 'utf8')
|
|
826
|
-
const wrappedAsyncRequire = wrapModule(asyncRequireSource, {
|
|
857
|
+
const wrappedAsyncRequire = wrapModule(asyncRequireSource, {
|
|
858
|
+
moduleId: 1,
|
|
859
|
+
dependencyIds: [],
|
|
860
|
+
})
|
|
827
861
|
|
|
828
862
|
for (const isDev of [true, false]) {
|
|
829
863
|
const contextObj = {
|
|
@@ -844,7 +878,9 @@ describe('metroNativeWorker', () => {
|
|
|
844
878
|
expect(typeof mainFn).toBe('function')
|
|
845
879
|
|
|
846
880
|
const promise = mainFn()
|
|
847
|
-
expect(
|
|
881
|
+
expect(
|
|
882
|
+
promise instanceof Promise || (promise && typeof promise.then === 'function')
|
|
883
|
+
).toBe(true)
|
|
848
884
|
|
|
849
885
|
const resolved = await promise
|
|
850
886
|
expect(resolved.message).toBe('hello dynamic')
|
|
@@ -945,11 +981,17 @@ describe('metroNativeWorker', () => {
|
|
|
945
981
|
export const ctx = require.context(routeRoot, true, /\\.tsx$/)
|
|
946
982
|
`
|
|
947
983
|
|
|
948
|
-
const result = await transform(
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
984
|
+
const result = await transform(
|
|
985
|
+
{},
|
|
986
|
+
'/project',
|
|
987
|
+
'entry.js',
|
|
988
|
+
Buffer.from(sourceCode, 'utf8'),
|
|
989
|
+
{
|
|
990
|
+
dev: true,
|
|
991
|
+
platform: 'ios',
|
|
992
|
+
type: 'module',
|
|
993
|
+
}
|
|
994
|
+
)
|
|
953
995
|
|
|
954
996
|
const contextDep = result.dependencies.find((d) => d.data.contextParams != null)
|
|
955
997
|
expect(contextDep?.name).toBe('./app')
|
|
@@ -967,7 +1009,15 @@ describe('metroNativeWorker', () => {
|
|
|
967
1009
|
req.context = () => {
|
|
968
1010
|
throw new Error('fallbackRequireContext reached')
|
|
969
1011
|
}
|
|
970
|
-
factory(
|
|
1012
|
+
factory(
|
|
1013
|
+
{},
|
|
1014
|
+
req,
|
|
1015
|
+
() => ({}),
|
|
1016
|
+
() => ({}),
|
|
1017
|
+
module,
|
|
1018
|
+
module.exports,
|
|
1019
|
+
['./app']
|
|
1020
|
+
)
|
|
971
1021
|
ctx = module.exports.ctx
|
|
972
1022
|
},
|
|
973
1023
|
}
|
|
@@ -989,11 +1039,17 @@ describe('metroNativeWorker', () => {
|
|
|
989
1039
|
}
|
|
990
1040
|
`
|
|
991
1041
|
|
|
992
|
-
const result = await transform(
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1042
|
+
const result = await transform(
|
|
1043
|
+
{},
|
|
1044
|
+
'/project',
|
|
1045
|
+
'loops.ts',
|
|
1046
|
+
Buffer.from(sourceCode, 'utf8'),
|
|
1047
|
+
{
|
|
1048
|
+
dev: true,
|
|
1049
|
+
platform: 'ios',
|
|
1050
|
+
type: 'module',
|
|
1051
|
+
}
|
|
1052
|
+
)
|
|
997
1053
|
|
|
998
1054
|
const code = result.output[0].data.code
|
|
999
1055
|
|
|
@@ -1002,16 +1058,21 @@ describe('metroNativeWorker', () => {
|
|
|
1002
1058
|
// Rewriting the heads that way reproduces Hermes on a runtime that is
|
|
1003
1059
|
// otherwise spec-correct, which is what makes this assertion meaningful:
|
|
1004
1060
|
// the untransformed source returns 2,2,b,b,y,y under it.
|
|
1005
|
-
const asHermesWouldSeeIt = code.replace(
|
|
1006
|
-
/\bfor\s*\(\s*(let|const)\b/g,
|
|
1007
|
-
'for (var'
|
|
1008
|
-
)
|
|
1061
|
+
const asHermesWouldSeeIt = code.replace(/\bfor\s*\(\s*(let|const)\b/g, 'for (var')
|
|
1009
1062
|
|
|
1010
1063
|
let collect: any
|
|
1011
1064
|
const sandbox: any = {
|
|
1012
1065
|
__d: (factory: any) => {
|
|
1013
1066
|
const module = { exports: {} as any }
|
|
1014
|
-
factory(
|
|
1067
|
+
factory(
|
|
1068
|
+
{},
|
|
1069
|
+
() => ({}),
|
|
1070
|
+
() => ({}),
|
|
1071
|
+
() => ({}),
|
|
1072
|
+
module,
|
|
1073
|
+
module.exports,
|
|
1074
|
+
[]
|
|
1075
|
+
)
|
|
1015
1076
|
collect = module.exports.collect
|
|
1016
1077
|
},
|
|
1017
1078
|
}
|
|
@@ -1095,7 +1156,9 @@ export const all = { ...import.meta.env };`,
|
|
|
1095
1156
|
|
|
1096
1157
|
it('folds a ternary and keeps a branch it cannot resolve', () => {
|
|
1097
1158
|
expect(
|
|
1098
|
-
applyInlineEnvVars('const a = import.meta.env.DEV ? x : y;', 'a.ts', true, {
|
|
1159
|
+
applyInlineEnvVars('const a = import.meta.env.DEV ? x : y;', 'a.ts', true, {
|
|
1160
|
+
DEV: false,
|
|
1161
|
+
})
|
|
1099
1162
|
).toContain('const a = y;')
|
|
1100
1163
|
const dynamic = 'const a = flag ? x : y;'
|
|
1101
1164
|
expect(applyInlineEnvVars(dynamic, 'a.ts', true, { DEV: false })).toBe(dynamic)
|
|
@@ -1181,7 +1244,7 @@ export const all = { ...import.meta.env };`,
|
|
|
1181
1244
|
expect(parsed.program.body.map((n: any) => n.type)).toContain('ThrowStatement')
|
|
1182
1245
|
})
|
|
1183
1246
|
|
|
1184
|
-
it(
|
|
1247
|
+
it("reads the router root off one's remove-server-code plugin entry", () => {
|
|
1185
1248
|
const options: any = {
|
|
1186
1249
|
customTransformOptions: {
|
|
1187
1250
|
vite: {
|