metro-transform-worker 0.63.0 → 0.64.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/package.json +13 -12
- package/src/index.js +33 -14
- package/src/index.js.flow +14 -11
- package/src/utils/assetTransformer.js +4 -0
- package/src/utils/assetTransformer.js.flow +2 -2
- package/src.real/__mocks__/index.js +1 -2
- package/src.real/index.js +557 -438
- package/src.real/index.js.flow +517 -0
- package/src.real/utils/assetTransformer.js +69 -31
- package/src.real/utils/assetTransformer.js.flow +50 -0
- package/src.real/utils/getMinifier.js +4 -7
- package/src.real/utils/getMinifier.js.flow +32 -0
- package/src.real/__tests__/__snapshots__/index-test.js.snap +0 -306
- package/src.real/__tests__/index-test.js +0 -380
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const HermesCompiler = require('metro-hermes-compiler');
|
|
14
|
+
const JsFileWrapping = require('metro/src/ModuleGraph/worker/JsFileWrapping');
|
|
15
|
+
|
|
16
|
+
const assetTransformer = require('./utils/assetTransformer');
|
|
17
|
+
const babylon = require('@babel/parser');
|
|
18
|
+
const collectDependencies = require('metro/src/ModuleGraph/worker/collectDependencies');
|
|
19
|
+
const generateImportNames = require('metro/src/ModuleGraph/worker/generateImportNames');
|
|
20
|
+
const nullthrows = require('nullthrows');
|
|
21
|
+
const generate = require('@babel/generator').default;
|
|
22
|
+
const getCacheKey = require('metro-cache-key');
|
|
23
|
+
const getMinifier = require('./utils/getMinifier');
|
|
24
|
+
const {
|
|
25
|
+
constantFoldingPlugin,
|
|
26
|
+
getTransformPluginCacheKeyFiles,
|
|
27
|
+
importExportPlugin,
|
|
28
|
+
inlinePlugin,
|
|
29
|
+
normalizePseudoGlobals,
|
|
30
|
+
} = require('metro-transform-plugins');
|
|
31
|
+
const inlineRequiresPlugin = require('babel-preset-fbjs/plugins/inline-requires');
|
|
32
|
+
const {transformFromAstSync} = require('@babel/core');
|
|
33
|
+
const {stableHash} = require('metro-cache');
|
|
34
|
+
const types = require('@babel/types');
|
|
35
|
+
const countLines = require('metro/src/lib/countLines');
|
|
36
|
+
|
|
37
|
+
const {
|
|
38
|
+
fromRawMappings,
|
|
39
|
+
toBabelSegments,
|
|
40
|
+
toSegmentTuple,
|
|
41
|
+
} = require('metro-source-map');
|
|
42
|
+
import type {TransformResultDependency} from 'metro/src/DeltaBundler';
|
|
43
|
+
import type {AllowOptionalDependencies} from 'metro/src/DeltaBundler/types.flow.js';
|
|
44
|
+
import type {DynamicRequiresBehavior} from 'metro/src/ModuleGraph/worker/collectDependencies';
|
|
45
|
+
import type {
|
|
46
|
+
BasicSourceMap,
|
|
47
|
+
FBSourceFunctionMap,
|
|
48
|
+
MetroSourceMapSegmentTuple,
|
|
49
|
+
} from 'metro-source-map';
|
|
50
|
+
import type {
|
|
51
|
+
HermesCompilerResult,
|
|
52
|
+
Options as HermesCompilerOptions,
|
|
53
|
+
} from 'metro-hermes-compiler';
|
|
54
|
+
import type {
|
|
55
|
+
CustomTransformOptions,
|
|
56
|
+
TransformProfile,
|
|
57
|
+
} from 'metro-babel-transformer';
|
|
58
|
+
|
|
59
|
+
type MinifierConfig = $ReadOnly<{[string]: mixed, ...}>;
|
|
60
|
+
|
|
61
|
+
export type MinifierOptions = {
|
|
62
|
+
code: string,
|
|
63
|
+
map: ?BasicSourceMap,
|
|
64
|
+
filename: string,
|
|
65
|
+
reserved: $ReadOnlyArray<string>,
|
|
66
|
+
config: MinifierConfig,
|
|
67
|
+
...
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type MinifierResult = {
|
|
71
|
+
code: string,
|
|
72
|
+
map?: BasicSourceMap,
|
|
73
|
+
...
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export type Minifier = MinifierOptions => MinifierResult;
|
|
77
|
+
|
|
78
|
+
export type Type = 'script' | 'module' | 'asset';
|
|
79
|
+
|
|
80
|
+
export type JsTransformerConfig = $ReadOnly<{|
|
|
81
|
+
assetPlugins: $ReadOnlyArray<string>,
|
|
82
|
+
assetRegistryPath: string,
|
|
83
|
+
asyncRequireModulePath: string,
|
|
84
|
+
babelTransformerPath: string,
|
|
85
|
+
dynamicDepsInPackages: DynamicRequiresBehavior,
|
|
86
|
+
enableBabelRCLookup: boolean,
|
|
87
|
+
enableBabelRuntime: boolean,
|
|
88
|
+
experimentalImportBundleSupport: boolean,
|
|
89
|
+
globalPrefix: string,
|
|
90
|
+
minifierConfig: MinifierConfig,
|
|
91
|
+
minifierPath: string,
|
|
92
|
+
optimizationSizeLimit: number,
|
|
93
|
+
publicPath: string,
|
|
94
|
+
allowOptionalDependencies: AllowOptionalDependencies,
|
|
95
|
+
|}>;
|
|
96
|
+
|
|
97
|
+
export type {CustomTransformOptions} from 'metro-babel-transformer';
|
|
98
|
+
|
|
99
|
+
export type JsTransformOptions = $ReadOnly<{|
|
|
100
|
+
customTransformOptions?: CustomTransformOptions,
|
|
101
|
+
dev: boolean,
|
|
102
|
+
experimentalImportSupport?: boolean,
|
|
103
|
+
hot: boolean,
|
|
104
|
+
inlinePlatform: boolean,
|
|
105
|
+
inlineRequires: boolean,
|
|
106
|
+
minify: boolean,
|
|
107
|
+
nonInlinedRequires?: $ReadOnlyArray<string>,
|
|
108
|
+
platform: ?string,
|
|
109
|
+
runtimeBytecodeVersion: ?number,
|
|
110
|
+
type: Type,
|
|
111
|
+
unstable_disableES6Transforms?: boolean,
|
|
112
|
+
unstable_transformProfile: TransformProfile,
|
|
113
|
+
|}>;
|
|
114
|
+
|
|
115
|
+
export type JsOutput = $ReadOnly<{|
|
|
116
|
+
data: $ReadOnly<{|
|
|
117
|
+
code: string,
|
|
118
|
+
lineCount: number,
|
|
119
|
+
map: Array<MetroSourceMapSegmentTuple>,
|
|
120
|
+
functionMap: ?FBSourceFunctionMap,
|
|
121
|
+
|}>,
|
|
122
|
+
type: string,
|
|
123
|
+
|}>;
|
|
124
|
+
|
|
125
|
+
export type BytecodeOutput = $ReadOnly<{|
|
|
126
|
+
data: HermesCompilerResult,
|
|
127
|
+
type: 'bytecode/module' | 'bytecode/module/asset' | 'bytecode/script',
|
|
128
|
+
|}>;
|
|
129
|
+
|
|
130
|
+
type Result = {|
|
|
131
|
+
dependencies: $ReadOnlyArray<TransformResultDependency>,
|
|
132
|
+
output: $ReadOnlyArray<JsOutput | BytecodeOutput>,
|
|
133
|
+
|};
|
|
134
|
+
|
|
135
|
+
function getDynamicDepsBehavior(
|
|
136
|
+
inPackages: DynamicRequiresBehavior,
|
|
137
|
+
filename: string,
|
|
138
|
+
): DynamicRequiresBehavior {
|
|
139
|
+
switch (inPackages) {
|
|
140
|
+
case 'reject':
|
|
141
|
+
return 'reject';
|
|
142
|
+
case 'throwAtRuntime':
|
|
143
|
+
const isPackage = /(?:^|[/\\])node_modules[/\\]/.test(filename);
|
|
144
|
+
return isPackage ? inPackages : 'reject';
|
|
145
|
+
default:
|
|
146
|
+
(inPackages: empty);
|
|
147
|
+
throw new Error(
|
|
148
|
+
`invalid value for dynamic deps behavior: \`${inPackages}\``,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const minifyCode = async (
|
|
154
|
+
config: JsTransformerConfig,
|
|
155
|
+
projectRoot: string,
|
|
156
|
+
filename: string,
|
|
157
|
+
code: string,
|
|
158
|
+
source: string,
|
|
159
|
+
map: Array<MetroSourceMapSegmentTuple>,
|
|
160
|
+
reserved?: $ReadOnlyArray<string> = [],
|
|
161
|
+
): Promise<{
|
|
162
|
+
code: string,
|
|
163
|
+
map: Array<MetroSourceMapSegmentTuple>,
|
|
164
|
+
...
|
|
165
|
+
}> => {
|
|
166
|
+
const sourceMap = fromRawMappings([
|
|
167
|
+
{code, source, map, functionMap: null, path: filename},
|
|
168
|
+
]).toMap(undefined, {});
|
|
169
|
+
|
|
170
|
+
const minify = getMinifier(config.minifierPath);
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
const minified = minify({
|
|
174
|
+
code,
|
|
175
|
+
map: sourceMap,
|
|
176
|
+
filename,
|
|
177
|
+
reserved,
|
|
178
|
+
config: config.minifierConfig,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
code: minified.code,
|
|
183
|
+
map: minified.map
|
|
184
|
+
? toBabelSegments(minified.map).map(toSegmentTuple)
|
|
185
|
+
: [],
|
|
186
|
+
};
|
|
187
|
+
} catch (error) {
|
|
188
|
+
if (error.constructor.name === 'JS_Parse_Error') {
|
|
189
|
+
throw new Error(
|
|
190
|
+
`${error.message} in file ${filename} at ${error.line}:${error.col}`,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const compileToBytecode = (
|
|
199
|
+
code: string,
|
|
200
|
+
type: string,
|
|
201
|
+
options: HermesCompilerOptions,
|
|
202
|
+
): HermesCompilerResult => {
|
|
203
|
+
if (type.startsWith('js/module')) {
|
|
204
|
+
const index = code.lastIndexOf(')');
|
|
205
|
+
code =
|
|
206
|
+
code.slice(0, index) +
|
|
207
|
+
',$$METRO_D[0],$$METRO_D[1],$$METRO_D[2]' +
|
|
208
|
+
code.slice(index);
|
|
209
|
+
}
|
|
210
|
+
return HermesCompiler.compile(code, options);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
class InvalidRequireCallError extends Error {
|
|
214
|
+
innerError: collectDependencies.InvalidRequireCallError;
|
|
215
|
+
filename: string;
|
|
216
|
+
|
|
217
|
+
constructor(
|
|
218
|
+
innerError: collectDependencies.InvalidRequireCallError,
|
|
219
|
+
filename: string,
|
|
220
|
+
) {
|
|
221
|
+
super(`${filename}:${innerError.message}`);
|
|
222
|
+
this.innerError = innerError;
|
|
223
|
+
this.filename = filename;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
module.exports = {
|
|
228
|
+
transform: async (
|
|
229
|
+
config: JsTransformerConfig,
|
|
230
|
+
projectRoot: string,
|
|
231
|
+
filename: string,
|
|
232
|
+
data: Buffer,
|
|
233
|
+
options: JsTransformOptions,
|
|
234
|
+
): Promise<Result> => {
|
|
235
|
+
const sourceCode = data.toString('utf8');
|
|
236
|
+
let type = 'js/module';
|
|
237
|
+
let bytecodeType = 'bytecode/module';
|
|
238
|
+
|
|
239
|
+
if (options.type === 'asset') {
|
|
240
|
+
type = 'js/module/asset';
|
|
241
|
+
bytecodeType = 'bytecode/module/asset';
|
|
242
|
+
}
|
|
243
|
+
if (options.type === 'script') {
|
|
244
|
+
type = 'js/script';
|
|
245
|
+
bytecodeType = 'bytecode/script';
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (filename.endsWith('.json')) {
|
|
249
|
+
let code = JsFileWrapping.wrapJson(sourceCode, config.globalPrefix);
|
|
250
|
+
let map = [];
|
|
251
|
+
|
|
252
|
+
if (options.minify) {
|
|
253
|
+
({map, code} = await minifyCode(
|
|
254
|
+
config,
|
|
255
|
+
projectRoot,
|
|
256
|
+
filename,
|
|
257
|
+
code,
|
|
258
|
+
sourceCode,
|
|
259
|
+
map,
|
|
260
|
+
));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const output = [
|
|
264
|
+
{
|
|
265
|
+
data: {code, lineCount: countLines(code), map, functionMap: null},
|
|
266
|
+
type,
|
|
267
|
+
},
|
|
268
|
+
];
|
|
269
|
+
if (options.runtimeBytecodeVersion) {
|
|
270
|
+
output.push({
|
|
271
|
+
data: (compileToBytecode(code, type, {
|
|
272
|
+
sourceURL: filename,
|
|
273
|
+
sourceMap: fromRawMappings([
|
|
274
|
+
{
|
|
275
|
+
code,
|
|
276
|
+
source: sourceCode,
|
|
277
|
+
map,
|
|
278
|
+
functionMap: null,
|
|
279
|
+
path: filename,
|
|
280
|
+
},
|
|
281
|
+
]).toString(),
|
|
282
|
+
}): HermesCompilerResult),
|
|
283
|
+
type: bytecodeType,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return {
|
|
288
|
+
dependencies: [],
|
|
289
|
+
output,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// $FlowFixMe TODO t26372934 Plugin system
|
|
294
|
+
const transformer: Transformer<*> = require(config.babelTransformerPath);
|
|
295
|
+
|
|
296
|
+
const transformerArgs = {
|
|
297
|
+
filename,
|
|
298
|
+
options: {
|
|
299
|
+
...options,
|
|
300
|
+
enableBabelRCLookup: config.enableBabelRCLookup,
|
|
301
|
+
enableBabelRuntime: config.enableBabelRuntime,
|
|
302
|
+
globalPrefix: config.globalPrefix,
|
|
303
|
+
// Inline requires are now performed at a secondary step. We cannot
|
|
304
|
+
// unfortunately remove it from the internal transformer, since this one
|
|
305
|
+
// is used by other tooling, and this would affect it.
|
|
306
|
+
inlineRequires: false,
|
|
307
|
+
nonInlinedRequires: [],
|
|
308
|
+
projectRoot,
|
|
309
|
+
publicPath: config.publicPath,
|
|
310
|
+
},
|
|
311
|
+
plugins: [],
|
|
312
|
+
src: sourceCode,
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const transformResult =
|
|
316
|
+
type === 'js/module/asset'
|
|
317
|
+
? {
|
|
318
|
+
...(await assetTransformer.transform(
|
|
319
|
+
transformerArgs,
|
|
320
|
+
config.assetRegistryPath,
|
|
321
|
+
config.assetPlugins,
|
|
322
|
+
)),
|
|
323
|
+
functionMap: null,
|
|
324
|
+
}
|
|
325
|
+
: await transformer.transform(transformerArgs);
|
|
326
|
+
|
|
327
|
+
// Transformers can ouptut null ASTs (if they ignore the file). In that case
|
|
328
|
+
// we need to parse the module source code to get their AST.
|
|
329
|
+
let ast =
|
|
330
|
+
transformResult.ast ||
|
|
331
|
+
babylon.parse(sourceCode, {sourceType: 'unambiguous'});
|
|
332
|
+
|
|
333
|
+
const {importDefault, importAll} = generateImportNames(ast);
|
|
334
|
+
|
|
335
|
+
// Add "use strict" if the file was parsed as a module, and the directive did
|
|
336
|
+
// not exist yet.
|
|
337
|
+
const {directives} = ast.program;
|
|
338
|
+
|
|
339
|
+
if (
|
|
340
|
+
ast.program.sourceType === 'module' &&
|
|
341
|
+
directives.findIndex(d => d.value.value === 'use strict') === -1
|
|
342
|
+
) {
|
|
343
|
+
directives.push(types.directive(types.directiveLiteral('use strict')));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Perform the import-export transform (in case it's still needed), then
|
|
347
|
+
// fold requires and perform constant folding (if in dev).
|
|
348
|
+
const plugins = [];
|
|
349
|
+
const opts = {
|
|
350
|
+
...options,
|
|
351
|
+
inlineableCalls: [importDefault, importAll],
|
|
352
|
+
importDefault,
|
|
353
|
+
importAll,
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
if (options.experimentalImportSupport) {
|
|
357
|
+
plugins.push([importExportPlugin, opts]);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (options.inlineRequires) {
|
|
361
|
+
plugins.push([
|
|
362
|
+
inlineRequiresPlugin,
|
|
363
|
+
{
|
|
364
|
+
...opts,
|
|
365
|
+
ignoredRequires: options.nonInlinedRequires,
|
|
366
|
+
},
|
|
367
|
+
]);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (!options.dev) {
|
|
371
|
+
plugins.push([constantFoldingPlugin, opts]);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
plugins.push([inlinePlugin, opts]);
|
|
375
|
+
|
|
376
|
+
ast = nullthrows(
|
|
377
|
+
transformFromAstSync(ast, '', {
|
|
378
|
+
ast: true,
|
|
379
|
+
babelrc: false,
|
|
380
|
+
code: false,
|
|
381
|
+
configFile: false,
|
|
382
|
+
comments: false,
|
|
383
|
+
compact: false,
|
|
384
|
+
filename,
|
|
385
|
+
plugins,
|
|
386
|
+
sourceMaps: false,
|
|
387
|
+
}).ast,
|
|
388
|
+
);
|
|
389
|
+
|
|
390
|
+
let dependencyMapName = '';
|
|
391
|
+
let dependencies;
|
|
392
|
+
let wrappedAst;
|
|
393
|
+
|
|
394
|
+
// If the module to transform is a script (meaning that is not part of the
|
|
395
|
+
// dependency graph and it code will just be prepended to the bundle modules),
|
|
396
|
+
// we need to wrap it differently than a commonJS module (also, scripts do
|
|
397
|
+
// not have dependencies).
|
|
398
|
+
if (type === 'js/script') {
|
|
399
|
+
dependencies = [];
|
|
400
|
+
wrappedAst = JsFileWrapping.wrapPolyfill(ast);
|
|
401
|
+
} else {
|
|
402
|
+
try {
|
|
403
|
+
const opts = {
|
|
404
|
+
asyncRequireModulePath: config.asyncRequireModulePath,
|
|
405
|
+
dynamicRequires: getDynamicDepsBehavior(
|
|
406
|
+
config.dynamicDepsInPackages,
|
|
407
|
+
filename,
|
|
408
|
+
),
|
|
409
|
+
inlineableCalls: [importDefault, importAll],
|
|
410
|
+
keepRequireNames: options.dev,
|
|
411
|
+
allowOptionalDependencies: config.allowOptionalDependencies,
|
|
412
|
+
};
|
|
413
|
+
({ast, dependencies, dependencyMapName} = collectDependencies(
|
|
414
|
+
ast,
|
|
415
|
+
opts,
|
|
416
|
+
));
|
|
417
|
+
} catch (error) {
|
|
418
|
+
if (error instanceof collectDependencies.InvalidRequireCallError) {
|
|
419
|
+
throw new InvalidRequireCallError(error, filename);
|
|
420
|
+
}
|
|
421
|
+
throw error;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
({ast: wrappedAst} = JsFileWrapping.wrapModule(
|
|
425
|
+
ast,
|
|
426
|
+
importDefault,
|
|
427
|
+
importAll,
|
|
428
|
+
dependencyMapName,
|
|
429
|
+
config.globalPrefix,
|
|
430
|
+
));
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const reserved =
|
|
434
|
+
options.minify && data.length <= config.optimizationSizeLimit
|
|
435
|
+
? normalizePseudoGlobals(wrappedAst)
|
|
436
|
+
: [];
|
|
437
|
+
|
|
438
|
+
const result = generate(
|
|
439
|
+
wrappedAst,
|
|
440
|
+
{
|
|
441
|
+
comments: false,
|
|
442
|
+
compact: false,
|
|
443
|
+
filename,
|
|
444
|
+
retainLines: false,
|
|
445
|
+
sourceFileName: filename,
|
|
446
|
+
sourceMaps: true,
|
|
447
|
+
},
|
|
448
|
+
sourceCode,
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
let map = result.rawMappings ? result.rawMappings.map(toSegmentTuple) : [];
|
|
452
|
+
let code = result.code;
|
|
453
|
+
|
|
454
|
+
if (options.minify) {
|
|
455
|
+
({map, code} = await minifyCode(
|
|
456
|
+
config,
|
|
457
|
+
projectRoot,
|
|
458
|
+
filename,
|
|
459
|
+
result.code,
|
|
460
|
+
sourceCode,
|
|
461
|
+
map,
|
|
462
|
+
reserved,
|
|
463
|
+
));
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const output = [
|
|
467
|
+
{
|
|
468
|
+
data: {
|
|
469
|
+
code,
|
|
470
|
+
lineCount: countLines(code),
|
|
471
|
+
map,
|
|
472
|
+
functionMap: transformResult.functionMap,
|
|
473
|
+
},
|
|
474
|
+
type,
|
|
475
|
+
},
|
|
476
|
+
];
|
|
477
|
+
|
|
478
|
+
if (options.runtimeBytecodeVersion) {
|
|
479
|
+
output.push({
|
|
480
|
+
data: (compileToBytecode(code, type, {
|
|
481
|
+
sourceURL: filename,
|
|
482
|
+
sourceMap: fromRawMappings([
|
|
483
|
+
{code, source: sourceCode, map, functionMap: null, path: filename},
|
|
484
|
+
]).toString(),
|
|
485
|
+
}): HermesCompilerResult),
|
|
486
|
+
type: bytecodeType,
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return {
|
|
491
|
+
dependencies,
|
|
492
|
+
output,
|
|
493
|
+
};
|
|
494
|
+
},
|
|
495
|
+
|
|
496
|
+
getCacheKey: (config: JsTransformerConfig): string => {
|
|
497
|
+
const {babelTransformerPath, minifierPath, ...remainingConfig} = config;
|
|
498
|
+
|
|
499
|
+
const filesKey = getCacheKey([
|
|
500
|
+
require.resolve(babelTransformerPath),
|
|
501
|
+
require.resolve(minifierPath),
|
|
502
|
+
require.resolve('./utils/getMinifier'),
|
|
503
|
+
require.resolve('./utils/assetTransformer'),
|
|
504
|
+
require.resolve('metro/src/ModuleGraph/worker/collectDependencies'),
|
|
505
|
+
require.resolve('metro/src/ModuleGraph/worker/generateImportNames'),
|
|
506
|
+
require.resolve('metro/src/ModuleGraph/worker/JsFileWrapping'),
|
|
507
|
+
...getTransformPluginCacheKeyFiles(),
|
|
508
|
+
]);
|
|
509
|
+
|
|
510
|
+
const babelTransformer = require(babelTransformerPath);
|
|
511
|
+
return [
|
|
512
|
+
filesKey,
|
|
513
|
+
stableHash(remainingConfig).toString('hex'),
|
|
514
|
+
babelTransformer.getCacheKey ? babelTransformer.getCacheKey() : '',
|
|
515
|
+
].join('$');
|
|
516
|
+
},
|
|
517
|
+
};
|
|
@@ -4,47 +4,85 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
|
+
"use strict";
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
13
|
+
try {
|
|
14
|
+
var info = gen[key](arg);
|
|
15
|
+
var value = info.value;
|
|
16
|
+
} catch (error) {
|
|
17
|
+
reject(error);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (info.done) {
|
|
21
|
+
resolve(value);
|
|
22
|
+
} else {
|
|
23
|
+
Promise.resolve(value).then(_next, _throw);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
14
26
|
|
|
15
|
-
|
|
16
|
-
|
|
27
|
+
function _asyncToGenerator(fn) {
|
|
28
|
+
return function() {
|
|
29
|
+
var self = this,
|
|
30
|
+
args = arguments;
|
|
31
|
+
return new Promise(function(resolve, reject) {
|
|
32
|
+
var gen = fn.apply(self, args);
|
|
33
|
+
function _next(value) {
|
|
34
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
35
|
+
}
|
|
36
|
+
function _throw(err) {
|
|
37
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
38
|
+
}
|
|
39
|
+
_next(undefined);
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
}
|
|
17
43
|
|
|
18
|
-
|
|
19
|
-
import type {BabelTransformerArgs} from 'metro-babel-transformer';
|
|
44
|
+
const path = require("path");
|
|
20
45
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
assetRegistryPath: string,
|
|
24
|
-
assetDataPlugins: $ReadOnlyArray<string>,
|
|
25
|
-
): Promise<{ast: Ast, ...}> {
|
|
26
|
-
options = options || {
|
|
27
|
-
platform: '',
|
|
28
|
-
projectRoot: '',
|
|
29
|
-
inlineRequires: false,
|
|
30
|
-
minify: false,
|
|
31
|
-
};
|
|
46
|
+
const _require = require("metro/src/Assets"),
|
|
47
|
+
getAssetData = _require.getAssetData;
|
|
32
48
|
|
|
33
|
-
|
|
49
|
+
const _require2 = require("metro/src/Bundler/util"),
|
|
50
|
+
generateAssetCodeFileAst = _require2.generateAssetCodeFileAst;
|
|
34
51
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
assetDataPlugins,
|
|
39
|
-
options.platform,
|
|
40
|
-
options.publicPath,
|
|
41
|
-
);
|
|
52
|
+
function transform(_x, _x2, _x3) {
|
|
53
|
+
return _transform.apply(this, arguments);
|
|
54
|
+
}
|
|
42
55
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
56
|
+
function _transform() {
|
|
57
|
+
_transform = _asyncToGenerator(function*(
|
|
58
|
+
_ref,
|
|
59
|
+
assetRegistryPath,
|
|
60
|
+
assetDataPlugins
|
|
61
|
+
) {
|
|
62
|
+
let filename = _ref.filename,
|
|
63
|
+
options = _ref.options,
|
|
64
|
+
src = _ref.src;
|
|
65
|
+
options = options || {
|
|
66
|
+
platform: "",
|
|
67
|
+
projectRoot: "",
|
|
68
|
+
inlineRequires: false,
|
|
69
|
+
minify: false
|
|
70
|
+
};
|
|
71
|
+
const absolutePath = path.resolve(options.projectRoot, filename);
|
|
72
|
+
const data = yield getAssetData(
|
|
73
|
+
absolutePath,
|
|
74
|
+
filename,
|
|
75
|
+
assetDataPlugins,
|
|
76
|
+
options.platform,
|
|
77
|
+
options.publicPath
|
|
78
|
+
);
|
|
79
|
+
return {
|
|
80
|
+
ast: generateAssetCodeFileAst(assetRegistryPath, data)
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
return _transform.apply(this, arguments);
|
|
46
84
|
}
|
|
47
85
|
|
|
48
86
|
module.exports = {
|
|
49
|
-
transform
|
|
87
|
+
transform
|
|
50
88
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @flow
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const path = require('path');
|
|
14
|
+
|
|
15
|
+
const {getAssetData} = require('metro/src/Assets');
|
|
16
|
+
const {generateAssetCodeFileAst} = require('metro/src/Bundler/util');
|
|
17
|
+
|
|
18
|
+
import type {File} from '@babel/types';
|
|
19
|
+
import type {BabelTransformerArgs} from 'metro-babel-transformer';
|
|
20
|
+
|
|
21
|
+
async function transform(
|
|
22
|
+
{filename, options, src}: BabelTransformerArgs,
|
|
23
|
+
assetRegistryPath: string,
|
|
24
|
+
assetDataPlugins: $ReadOnlyArray<string>,
|
|
25
|
+
): Promise<{ast: File, ...}> {
|
|
26
|
+
options = options || {
|
|
27
|
+
platform: '',
|
|
28
|
+
projectRoot: '',
|
|
29
|
+
inlineRequires: false,
|
|
30
|
+
minify: false,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const absolutePath = path.resolve(options.projectRoot, filename);
|
|
34
|
+
|
|
35
|
+
const data = await getAssetData(
|
|
36
|
+
absolutePath,
|
|
37
|
+
filename,
|
|
38
|
+
assetDataPlugins,
|
|
39
|
+
options.platform,
|
|
40
|
+
options.publicPath,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
ast: generateAssetCodeFileAst(assetRegistryPath, data),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
transform,
|
|
50
|
+
};
|
|
@@ -4,15 +4,12 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
|
+
"use strict";
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import type {Minifier} from '../index.js';
|
|
14
|
-
|
|
15
|
-
function getMinifier(minifierPath: string): Minifier {
|
|
12
|
+
function getMinifier(minifierPath) {
|
|
16
13
|
// Note: minifierPath should be an absolute path OR a module name here!
|
|
17
14
|
// The options allow relative paths but they HAVE to be normalized at
|
|
18
15
|
// any entry point that accepts them...
|
|
@@ -24,7 +21,7 @@ function getMinifier(minifierPath: string): Minifier {
|
|
|
24
21
|
'A problem occurred while trying to fetch the minifier. Path: "' +
|
|
25
22
|
minifierPath +
|
|
26
23
|
'", error message: ' +
|
|
27
|
-
e.message
|
|
24
|
+
e.message
|
|
28
25
|
);
|
|
29
26
|
}
|
|
30
27
|
}
|