Skip to content

Commit

Permalink
Pass full path and query params to asyncRequire
Browse files Browse the repository at this point in the history
Summary:
Changelog:
 * **[Experimental]**: Pass full path and query params to `asyncRequire` for lazy bundles.

Moves the responsibility for setting query params on lazy bundle requests from the runtime to the serializer. This is a breaking change to any `asyncRequire` implementations currently relying on the experimental second parameter.

See the [lazy bundling RFC](react-native-community/discussions-and-proposals#605) for more context. Note that replacing `asyncRequire` using `asyncRequireModulePath` will itself be deprecated with the introduction of the `__loadBundleAsync` runtime hook.

Reviewed By: robhogan

Differential Revision: D43597023

fbshipit-source-id: 8943cfee04abd5f7e23b5cbb2047d401c728fe14
  • Loading branch information
motiz88 authored and facebook-github-bot committed Apr 4, 2023
1 parent 8887836 commit 61a30b7
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ function baseJSBundle(
includeAsyncPaths: options.includeAsyncPaths,
projectRoot: options.projectRoot,
serverRoot: options.serverRoot,
sourceUrl: options.sourceUrl,
};

// Do not prepend polyfills or the require runtime when only modules are requested
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ describe('wrapModule()', () => {
includeAsyncPaths: false,
projectRoot: '/root',
serverRoot: '/root',
sourceUrl: null,
}),
),
).toMatchInlineSnapshot(`__d(function() { console.log("foo") },0,[1,2]);`);
Expand All @@ -82,6 +83,7 @@ describe('wrapModule()', () => {
includeAsyncPaths: false,
projectRoot: '/root',
serverRoot: '/root',
sourceUrl: null,
}),
),
).toMatchInlineSnapshot(
Expand All @@ -100,6 +102,7 @@ describe('wrapModule()', () => {
includeAsyncPaths: false,
projectRoot: '/root',
serverRoot: '/root',
sourceUrl: null,
}),
),
).toMatchInlineSnapshot(`__d(function() { console.log("foo") });`);
Expand All @@ -115,6 +118,7 @@ describe('wrapModule()', () => {
includeAsyncPaths: false,
projectRoot: '/root',
serverRoot: '/root',
sourceUrl: null,
}),
),
).toMatchInlineSnapshot(
Expand All @@ -136,10 +140,11 @@ describe('wrapModule()', () => {
includeAsyncPaths: true,
projectRoot: '/root',
serverRoot: '/root',
sourceUrl: 'http://localhost/Main.bundle?param1=true&param2=1234',
}),
),
).toMatchInlineSnapshot(
`__d(function() { console.log("foo") },0,{"0":1,"1":2,"paths":{"1":"../bar"}});`,
`__d(function() { console.log("foo") },0,{"0":1,"1":2,"paths":{"1":"/../bar.bundle?param1=true&param2=1234&modulesOnly=true&runModule=false"}});`,
);
});

Expand All @@ -157,10 +162,34 @@ describe('wrapModule()', () => {
includeAsyncPaths: true,
projectRoot: '/root',
serverRoot: '/',
sourceUrl: 'http://localhost/Main.bundle?param1=true&param2=1234',
}),
),
).toMatchInlineSnapshot(
`__d(function() { console.log("foo") },0,{"0":1,"1":2,"paths":{"1":"bar"}});`,
`__d(function() { console.log("foo") },0,{"0":1,"1":2,"paths":{"1":"/bar.bundle?param1=true&param2=1234&modulesOnly=true&runModule=false"}});`,
);
});

it('async bundle paths override modulesOnly and runModule', () => {
const dep = nullthrows(myModule.dependencies.get('bar'));
myModule.dependencies.set('bar', {
...dep,
data: {...dep.data, data: {...dep.data.data, asyncType: 'async'}},
});
expect(
raw(
wrapModule(myModule, {
createModuleId: createModuleIdFactory(),
dev: false,
includeAsyncPaths: true,
projectRoot: '/root',
serverRoot: '/root',
sourceUrl:
'http://localhost/Main.bundle?modulesOnly=false&runModule=true',
}),
),
).toMatchInlineSnapshot(
`__d(function() { console.log("foo") },0,{"0":1,"1":2,"paths":{"1":"/../bar.bundle?modulesOnly=true&runModule=false"}});`,
);
});
});
30 changes: 24 additions & 6 deletions packages/metro/src/DeltaBundler/Serializers/helpers/js.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type Options = $ReadOnly<{
includeAsyncPaths: boolean,
projectRoot: string,
serverRoot: string,
sourceUrl: ?string,
...
}>;

Expand All @@ -48,16 +49,33 @@ function getModuleParams(module: Module<>, options: Options): Array<mixed> {
const id = options.createModuleId(dependency.absolutePath);
if (options.includeAsyncPaths && dependency.data.data.asyncType != null) {
hasPaths = true;
invariant(
options.sourceUrl != null,
'sourceUrl is required when includeAsyncPaths is true',
);

// TODO: Only include path if the target is not in the bundle

// Construct a server-relative URL for the split bundle, propagating
// most parameters from the main bundle's URL.

const {searchParams} = new URL(options.sourceUrl);
searchParams.set('modulesOnly', 'true');
searchParams.set('runModule', 'false');

const bundlePath = path.relative(
options.serverRoot,
dependency.absolutePath,
);
// TODO: Eventually this slicing should be asyncRequire's responsibility
// Strip the file extension
paths[id] = path.join(
path.dirname(bundlePath),
path.basename(bundlePath, path.extname(bundlePath)),
);
paths[id] =
'/' +
path.join(
path.dirname(bundlePath),
// Strip the file extension
path.basename(bundlePath, path.extname(bundlePath)),
) +
'.bundle?' +
searchParams.toString();
}
return id;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ function processModules(
includeAsyncPaths,
projectRoot,
serverRoot,
sourceUrl,
}: $ReadOnly<{
filter?: (module: Module<>) => boolean,
createModuleId: string => number,
dev: boolean,
includeAsyncPaths: boolean,
projectRoot: string,
serverRoot: string,
sourceUrl: ?string,
}>,
): $ReadOnlyArray<[Module<>, string]> {
return [...modules]
Expand All @@ -44,6 +46,7 @@ function processModules(
includeAsyncPaths,
projectRoot,
serverRoot,
sourceUrl,
}),
]);
}
Expand Down
1 change: 1 addition & 0 deletions packages/metro/src/DeltaBundler/Serializers/hmrJSBundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ function prepareModule(
): string {
const code = wrapModule(module, {
...options,
sourceUrl: url.format(options.clientUrl),
dev: true,
});

Expand Down
1 change: 0 additions & 1 deletion packages/metro/src/shared/types.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ export type BundleOptions = {
sourceUrl: ?string,
createModuleIdFactory?: () => (path: string) => number,
+unstable_transformProfile: TransformProfile,
...
};

export type ResolverInputOptions = $ReadOnly<{
Expand Down

0 comments on commit 61a30b7

Please sign in to comment.