mirror of https://github.com/status-im/metro.git
metro-bundler: ModuleGraph: add support for require.async() when collecting dependencies
Summary: This is the last step remaining before enabling the `import()` syntax to use `require.async()` (for now that function is just doing a simple `require()` in behind). Reviewed By: davidaurelio Differential Revision: D6147030 fbshipit-source-id: 5cd8ee6cc550816ae3cdea0b457dc2419c99e7a7
This commit is contained in:
parent
d74685fd1d
commit
d01f514fa0
|
@ -37,6 +37,20 @@ describe('dependency collection from ASTs:', () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it('collects asynchronous dependencies', () => {
|
||||
const ast = astFromCode(`
|
||||
const a = require('b/lib/a');
|
||||
if (!something) {
|
||||
require.async("some/async/module").then(foo => {});
|
||||
}
|
||||
`);
|
||||
|
||||
expect(collectDependencies(ast).dependencies).toEqual([
|
||||
'b/lib/a',
|
||||
'some/async/module',
|
||||
]);
|
||||
});
|
||||
|
||||
it('supports template literals as arguments', () => {
|
||||
const ast = astFromCode('require(`left-pad`)');
|
||||
|
||||
|
@ -101,11 +115,12 @@ describe('Dependency collection from optimized ASTs:', () => {
|
|||
ast = astFromCode(`
|
||||
const a = require(${dependencyMapName}[0], 'b/lib/a');
|
||||
exports.do = () => require(${dependencyMapName}[1], "do");
|
||||
require.async(${dependencyMapName}[2], 'some/async/module').then(foo => {});
|
||||
if (!something) {
|
||||
require(${dependencyMapName}[2], "setup/something");
|
||||
require(${dependencyMapName}[3], "setup/something");
|
||||
}
|
||||
`);
|
||||
names = ['b/lib/a', 'do', 'setup/something'];
|
||||
names = ['b/lib/a', 'do', 'some/async/module', 'setup/something'];
|
||||
});
|
||||
|
||||
it('passes the `dependencyMapName` through', () => {
|
||||
|
@ -130,8 +145,9 @@ describe('Dependency collection from optimized ASTs:', () => {
|
|||
comparableCode(`
|
||||
const a = require(${dependencyMapName}[0]);
|
||||
exports.do = () => require(${dependencyMapName}[1]);
|
||||
require.async(${dependencyMapName}[2]).then(foo => {});
|
||||
if (!something) {
|
||||
require(${dependencyMapName}[2]);
|
||||
require(${dependencyMapName}[3]);
|
||||
}
|
||||
`),
|
||||
);
|
||||
|
|
|
@ -132,6 +132,16 @@ function createMapLookup(dependencyMapIdentifier, propertyIdentifier) {
|
|||
function collectDependencies(ast, replacement, dependencyMapIdentifier) {
|
||||
const visited = new WeakSet();
|
||||
const traversalState = {dependencyMapIdentifier};
|
||||
function processRequireCall(node, state, isAsync) {
|
||||
const arg = replacement.getRequireCallArg(node);
|
||||
const index = replacement.getIndex(arg);
|
||||
node.arguments = replacement.makeArgs(
|
||||
types.numericLiteral(index),
|
||||
arg,
|
||||
state.dependencyMapIdentifier,
|
||||
);
|
||||
visited.add(node);
|
||||
}
|
||||
traverse(
|
||||
ast,
|
||||
{
|
||||
|
@ -148,14 +158,9 @@ function collectDependencies(ast, replacement, dependencyMapIdentifier) {
|
|||
return;
|
||||
}
|
||||
if (isRequireCall(node.callee)) {
|
||||
const arg = replacement.getRequireCallArg(node);
|
||||
const index = replacement.getIndex(arg);
|
||||
node.arguments = replacement.makeArgs(
|
||||
types.numericLiteral(index),
|
||||
arg,
|
||||
state.dependencyMapIdentifier,
|
||||
);
|
||||
visited.add(node);
|
||||
processRequireCall(node, state, false);
|
||||
} else if (isAsyncRequireCall(node.callee)) {
|
||||
processRequireCall(node, state, true);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -180,6 +185,15 @@ function isRequireCall(callee) {
|
|||
return callee.type === 'Identifier' && callee.name === 'require';
|
||||
}
|
||||
|
||||
function isAsyncRequireCall(callee) {
|
||||
return (
|
||||
callee.type === 'MemberExpression' &&
|
||||
!callee.computed &&
|
||||
callee.property.name === 'async' &&
|
||||
isRequireCall(callee.object)
|
||||
);
|
||||
}
|
||||
|
||||
class InvalidRequireCallError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
|
|
Loading…
Reference in New Issue