Skip to content

Commit c37509b

Browse files
robhoganfacebook-github-bot
authored andcommitted
Enable $SHBuiltin.moduleFactory optimisation via custom transform option
Summary: When the custom transform option `unstable_staticHermesOptimizedRequire` is truthy, wrap module factories in ```javascript $SHBuiltin.moduleFactory(moduleId, factory) ``` This enables a Static Hermes-only optimisation for experimentation. Changelog: ```javascript - **[Experimental]**: Opt-in SHBuiltin module factory optimisation ``` Reviewed By: motiz88 Differential Revision: D73510634 fbshipit-source-id: 2ac94b08d13e453d87abdaae33d9ea0403a7b9e5
1 parent e0714b6 commit c37509b

File tree

2 files changed

+60
-10
lines changed

2 files changed

+60
-10
lines changed

packages/metro-transform-worker/src/index.js

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export type JsTransformOptions = $ReadOnly<{
129129
unstable_disableES6Transforms?: boolean,
130130
unstable_memoizeInlineRequires?: boolean,
131131
unstable_nonMemoizedInlineRequires?: $ReadOnlyArray<string>,
132+
unstable_staticHermesOptimizedRequire?: boolean,
132133
unstable_transformProfile: TransformProfile,
133134
}>;
134135

@@ -429,6 +430,12 @@ async function transformJS(
429430
// release. It should be made non-optional in ConfigT or removed in
430431
// future.
431432
config.unstable_renameRequire === false,
433+
{
434+
unstable_useStaticHermesModuleFactory: Boolean(
435+
options.customTransformOptions
436+
?.unstable_staticHermesOptimizedRequire,
437+
),
438+
},
432439
));
433440
}
434441
}
@@ -572,7 +579,14 @@ async function transformJSON(
572579
let code =
573580
config.unstable_disableModuleWrapping === true
574581
? JsFileWrapping.jsonToCommonJS(file.code)
575-
: JsFileWrapping.wrapJson(file.code, config.globalPrefix);
582+
: JsFileWrapping.wrapJson(
583+
file.code,
584+
config.globalPrefix,
585+
Boolean(
586+
options.customTransformOptions
587+
?.unstable_staticHermesOptimizedRequire,
588+
),
589+
);
576590
let map: Array<MetroSourceMapSegmentTuple> = [];
577591

578592
// TODO: When we can reuse transformJS for JSON, we should not derive `minify` separately.
@@ -654,13 +668,22 @@ module.exports = {
654668
};
655669
const sourceCode = data.toString('utf8');
656670

657-
const {unstable_dependencyMapReservedName} = config;
658-
if (unstable_dependencyMapReservedName != null) {
659-
const position = sourceCode.indexOf(unstable_dependencyMapReservedName);
671+
const reservedStrings = [];
672+
if (
673+
options.customTransformOptions?.unstable_staticHermesOptimizedRequire ==
674+
true
675+
) {
676+
reservedStrings.push('_$$_METRO_MODULE_ID');
677+
}
678+
if (config.unstable_dependencyMapReservedName != null) {
679+
reservedStrings.push(config.unstable_dependencyMapReservedName);
680+
}
681+
for (const reservedString of reservedStrings) {
682+
const position = sourceCode.indexOf(reservedString);
660683
if (position > -1) {
661684
throw new SyntaxError(
662685
'Source code contains the reserved string `' +
663-
unstable_dependencyMapReservedName +
686+
reservedString +
664687
'` at character offset ' +
665688
position,
666689
);

packages/metro/src/ModuleGraph/worker/JsFileWrapping.js

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ function wrapModule(
3333
dependencyMapName: string,
3434
globalPrefix: string,
3535
skipRequireRename: boolean,
36+
{
37+
unstable_useStaticHermesModuleFactory = false,
38+
}: $ReadOnly<{unstable_useStaticHermesModuleFactory?: boolean}> = {},
3639
): {
3740
ast: BabelNodeFile,
3841
requireName: string,
@@ -43,7 +46,19 @@ function wrapModule(
4346
dependencyMapName,
4447
);
4548
const factory = functionFromProgram(fileAst.program, params);
46-
const def = t.callExpression(t.identifier(`${globalPrefix}__d`), [factory]);
49+
50+
const def = t.callExpression(t.identifier(`${globalPrefix}__d`), [
51+
unstable_useStaticHermesModuleFactory
52+
? t.callExpression(
53+
t.memberExpression(
54+
t.identifier('$SHBuiltin'),
55+
t.identifier('moduleFactory'),
56+
),
57+
[t.identifier('_$$_METRO_MODULE_ID'), factory],
58+
)
59+
: factory,
60+
]);
61+
4762
const ast = t.file(t.program([t.expressionStatement(def)]));
4863

4964
// `require` doesn't need to be scoped when Metro serializes to iife because the local function
@@ -64,19 +79,31 @@ function jsonToCommonJS(source: string): string {
6479
return `module.exports = ${source};`;
6580
}
6681

67-
function wrapJson(source: string, globalPrefix: string): string {
82+
function wrapJson(
83+
source: string,
84+
globalPrefix: string,
85+
unstable_useStaticHermesModuleFactory?: boolean = false,
86+
): string {
6887
// Unused parameters; remember that's wrapping JSON.
6988
const moduleFactoryParameters = buildParameters(
7089
'_importDefaultUnused',
7190
'_importAllUnused',
7291
'_dependencyMapUnused',
7392
);
7493

75-
return [
76-
`${globalPrefix}__d(function(${moduleFactoryParameters.join(', ')}) {`,
94+
const factory = [
95+
`function(${moduleFactoryParameters.join(', ')}) {`,
7796
` ${jsonToCommonJS(source)}`,
78-
'});',
97+
'}',
7998
].join('\n');
99+
100+
return (
101+
`${globalPrefix}__d(` +
102+
(unstable_useStaticHermesModuleFactory
103+
? '$SHBuiltin.moduleFactory(_$$_METRO_MODULE_ID, ' + factory + ')'
104+
: factory) +
105+
');'
106+
);
80107
}
81108

82109
function functionFromProgram(

0 commit comments

Comments
 (0)