mirror of https://github.com/status-im/metro.git
[react-packager] Move async dependencies to `System.import`
Summary: We've decided to move the syntax for asynchronously requiring async dependencies. The new syntax works better with promises and therefore withe async/await as well. The new syntax looks like this: `System.import('moduleA').then(moduleA => {...});` or if you're using async/await you could simply do: let moduleA = await System.import('moduleA'); new moduleA().someFunction(); If you need to require multiple dependencies just do: Promise .all([System.import('moduleA'), System.import('moduleB')]) .then((moduleA, moduleB) => {...}) or the equivalent using async/await
This commit is contained in:
parent
ef7dc94907
commit
51e1a1f6a2
|
@ -169,7 +169,7 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["a"]);`,
|
System.import("a");`,
|
||||||
'a.js': `
|
'a.js': `
|
||||||
/**,
|
/**,
|
||||||
* @providesModule a
|
* @providesModule a
|
||||||
|
@ -199,8 +199,8 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["a"]);
|
System.import("a");
|
||||||
require.ensure(["b"]);`,
|
System.import("b");`,
|
||||||
'a.js': `
|
'a.js': `
|
||||||
/**,
|
/**,
|
||||||
* @providesModule a
|
* @providesModule a
|
||||||
|
@ -233,40 +233,6 @@ describe('BundlesLayout', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
pit('should put related async dependencies into the same bundle', () => {
|
|
||||||
setMockFilesystem({
|
|
||||||
'root': {
|
|
||||||
'index.js': `
|
|
||||||
/**
|
|
||||||
* @providesModule index
|
|
||||||
*/
|
|
||||||
require.ensure(["a", "b"]);`,
|
|
||||||
'a.js': `
|
|
||||||
/**,
|
|
||||||
* @providesModule a
|
|
||||||
*/`,
|
|
||||||
'b.js': `
|
|
||||||
/**
|
|
||||||
* @providesModule b
|
|
||||||
*/`,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
|
||||||
stripPolyfills(bundles).then(resolvedBundles =>
|
|
||||||
expect(resolvedBundles).toEqual({
|
|
||||||
id: 'bundle.0',
|
|
||||||
modules: ['/root/index.js'],
|
|
||||||
children: [{
|
|
||||||
id: 'bundle.0.1',
|
|
||||||
modules: ['/root/a.js', '/root/b.js'],
|
|
||||||
children: [],
|
|
||||||
}],
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
pit('should fully traverse sync dependencies', () => {
|
pit('should fully traverse sync dependencies', () => {
|
||||||
setMockFilesystem({
|
setMockFilesystem({
|
||||||
'root': {
|
'root': {
|
||||||
|
@ -275,7 +241,7 @@ describe('BundlesLayout', () => {
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require("a");
|
require("a");
|
||||||
require.ensure(["b"]);`,
|
System.import("b");`,
|
||||||
'a.js': `
|
'a.js': `
|
||||||
/**,
|
/**,
|
||||||
* @providesModule a
|
* @providesModule a
|
||||||
|
@ -309,7 +275,7 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["a"]);`,
|
System.import("a");`,
|
||||||
'a.js': `
|
'a.js': `
|
||||||
/**,
|
/**,
|
||||||
* @providesModule a
|
* @providesModule a
|
||||||
|
@ -349,8 +315,8 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["a"]);
|
System.import("a");
|
||||||
require.ensure(["b"]);`,
|
System.import("b");`,
|
||||||
'a.js': `
|
'a.js': `
|
||||||
/**,
|
/**,
|
||||||
* @providesModule a
|
* @providesModule a
|
||||||
|
@ -397,12 +363,12 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["a"]);`,
|
System.import("a");`,
|
||||||
'a.js': `
|
'a.js': `
|
||||||
/**,
|
/**,
|
||||||
* @providesModule a
|
* @providesModule a
|
||||||
*/,
|
*/,
|
||||||
require.ensure(["b"]);`,
|
System.import("b");`,
|
||||||
'b.js': `
|
'b.js': `
|
||||||
/**
|
/**
|
||||||
* @providesModule b
|
* @providesModule b
|
||||||
|
@ -436,46 +402,6 @@ describe('BundlesLayout', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
pit('should dedup same async bundle duplicated dependencies', () => {
|
|
||||||
setMockFilesystem({
|
|
||||||
'root': {
|
|
||||||
'index.js': `
|
|
||||||
/**
|
|
||||||
* @providesModule index
|
|
||||||
*/
|
|
||||||
require.ensure(["a", "b"]);`,
|
|
||||||
'a.js': `
|
|
||||||
/**,
|
|
||||||
* @providesModule a
|
|
||||||
*/,
|
|
||||||
require("c");`,
|
|
||||||
'b.js': `
|
|
||||||
/**
|
|
||||||
* @providesModule b
|
|
||||||
*/
|
|
||||||
require("c");`,
|
|
||||||
'c.js': `
|
|
||||||
/**
|
|
||||||
* @providesModule c
|
|
||||||
*/`,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
|
||||||
stripPolyfills(bundles).then(resolvedBundles =>
|
|
||||||
expect(resolvedBundles).toEqual({
|
|
||||||
id: 'bundle.0',
|
|
||||||
modules: ['/root/index.js'],
|
|
||||||
children: [{
|
|
||||||
id: 'bundle.0.1',
|
|
||||||
modules: ['/root/a.js', '/root/c.js', '/root/b.js'],
|
|
||||||
children: [],
|
|
||||||
}],
|
|
||||||
})
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
pit('should put image dependencies into separate bundles', () => {
|
pit('should put image dependencies into separate bundles', () => {
|
||||||
setMockFilesystem({
|
setMockFilesystem({
|
||||||
'root': {
|
'root': {
|
||||||
|
@ -483,7 +409,7 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["a"]);`,
|
System.import("a");`,
|
||||||
'a.js':`
|
'a.js':`
|
||||||
/**,
|
/**,
|
||||||
* @providesModule a
|
* @providesModule a
|
||||||
|
@ -515,8 +441,8 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["a"]);
|
System.import("a");
|
||||||
require.ensure(["b"]);`,
|
System.import("b");`,
|
||||||
'a.js':`
|
'a.js':`
|
||||||
/**,
|
/**,
|
||||||
* @providesModule a
|
* @providesModule a
|
||||||
|
@ -560,7 +486,7 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["./img.png"]);`,
|
System.import("./img.png");`,
|
||||||
'img.png': '',
|
'img.png': '',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -587,7 +513,7 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["a"]);`,
|
System.import("a");`,
|
||||||
'a.js':`
|
'a.js':`
|
||||||
/**,
|
/**,
|
||||||
* @providesModule a
|
* @providesModule a
|
||||||
|
@ -619,7 +545,7 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["image!img"]);`,
|
System.import("image!img");`,
|
||||||
'img.png': '',
|
'img.png': '',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -646,7 +572,7 @@ describe('BundlesLayout', () => {
|
||||||
/**
|
/**
|
||||||
* @providesModule index
|
* @providesModule index
|
||||||
*/
|
*/
|
||||||
require.ensure(["aPackage"]);`,
|
System.import("aPackage");`,
|
||||||
'aPackage': {
|
'aPackage': {
|
||||||
'package.json': JSON.stringify({
|
'package.json': JSON.stringify({
|
||||||
name: 'aPackage',
|
name: 'aPackage',
|
||||||
|
|
|
@ -135,9 +135,6 @@ class Module {
|
||||||
*/
|
*/
|
||||||
const blockCommentRe = /\/\*(.|\n)*?\*\//g;
|
const blockCommentRe = /\/\*(.|\n)*?\*\//g;
|
||||||
const lineCommentRe = /\/\/.+(\n|$)/g;
|
const lineCommentRe = /\/\/.+(\n|$)/g;
|
||||||
const trailingCommaRe = /,\s*$/g;
|
|
||||||
const removeSpacesRe = /\s/g;
|
|
||||||
const quotesRe = /'/g;
|
|
||||||
function extractRequires(code /*: string*/) /*: Array<string>*/ {
|
function extractRequires(code /*: string*/) /*: Array<string>*/ {
|
||||||
var deps = {
|
var deps = {
|
||||||
sync: [],
|
sync: [],
|
||||||
|
@ -163,40 +160,11 @@ function extractRequires(code /*: string*/) /*: Array<string>*/ {
|
||||||
// Parse async dependencies this module has. As opposed to what happens
|
// Parse async dependencies this module has. As opposed to what happens
|
||||||
// with sync dependencies, when the module is required, it's async
|
// with sync dependencies, when the module is required, it's async
|
||||||
// dependencies won't be loaded into memory. This is deferred till the
|
// dependencies won't be loaded into memory. This is deferred till the
|
||||||
// code path gets to a `require.ensure` statement. The syntax is similar
|
// code path gets to the import statement:
|
||||||
// to webpack's one:
|
// System.import('dep1')
|
||||||
// require.ensure(['dep1', 'dep2'], () => {
|
.replace(replacePatterns.SYSTEM_IMPORT_RE, (match, pre, quot, dep, post) => {
|
||||||
// var dep1 = require('dep1');
|
deps.async.push([dep]);
|
||||||
// var dep2 = require('dep2');
|
return match;
|
||||||
// // do something with dep1 and dep2
|
|
||||||
// });
|
|
||||||
.replace(replacePatterns.REQUIRE_ENSURE_RE, (match, dep, post) => {
|
|
||||||
dep = dep
|
|
||||||
.replace(blockCommentRe, '')
|
|
||||||
.replace(lineCommentRe, '')
|
|
||||||
.replace(trailingCommaRe, '')
|
|
||||||
.replace(removeSpacesRe, '')
|
|
||||||
.replace(quotesRe, '"');
|
|
||||||
|
|
||||||
if (dep) {
|
|
||||||
try {
|
|
||||||
dep = JSON.parse('[' + dep + ']');
|
|
||||||
} catch(e) {
|
|
||||||
throw 'Error processing `require.ensure` while attemping to parse ' +
|
|
||||||
'dependencies `[' + dep + ']`: ' + e;
|
|
||||||
}
|
|
||||||
|
|
||||||
dep.forEach(d => {
|
|
||||||
if (typeof d !== 'string') {
|
|
||||||
throw 'Error processing `require.ensure`: dependencies `[' +
|
|
||||||
d + ']` must be string literals';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: throw error if there are duplicate dependencies
|
|
||||||
|
|
||||||
deps.async.push(dep);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return deps;
|
return deps;
|
||||||
|
|
|
@ -57,7 +57,7 @@ describe('Module', () => {
|
||||||
pit('should recognize single dependency', () => {
|
pit('should recognize single dependency', () => {
|
||||||
fs.__setMockFilesystem({
|
fs.__setMockFilesystem({
|
||||||
'root': {
|
'root': {
|
||||||
'index.js': 'require.ensure(["dep1"], function() {});',
|
'index.js': 'System.import("dep1")',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -67,67 +67,37 @@ describe('Module', () => {
|
||||||
pit('should parse single quoted dependencies', () => {
|
pit('should parse single quoted dependencies', () => {
|
||||||
fs.__setMockFilesystem({
|
fs.__setMockFilesystem({
|
||||||
'root': {
|
'root': {
|
||||||
'index.js': 'require.ensure([\'dep1\'], function() {});',
|
'index.js': 'System.import(\'dep1\')',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return expectAsyncDependenciesToEqual([['dep1']]);
|
return expectAsyncDependenciesToEqual([['dep1']]);
|
||||||
});
|
});
|
||||||
|
|
||||||
pit('should recognize multiple dependencies on the same statement', () => {
|
pit('should parse multiple async dependencies on the same module', () => {
|
||||||
fs.__setMockFilesystem({
|
|
||||||
'root': {
|
|
||||||
'index.js': 'require.ensure(["dep1", "dep2"], function() {});',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return expectAsyncDependenciesToEqual([['dep1', 'dep2']]);
|
|
||||||
});
|
|
||||||
|
|
||||||
pit('should group async dependencies', () => {
|
|
||||||
fs.__setMockFilesystem({
|
fs.__setMockFilesystem({
|
||||||
'root': {
|
'root': {
|
||||||
'index.js': [
|
'index.js': [
|
||||||
'require.ensure(["dep1", "dep2"], function() {});',
|
'System.import("dep1")',
|
||||||
'require.ensure(["dep3", "dep4"], function() {});',
|
'System.import("dep2")',
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return expectAsyncDependenciesToEqual([
|
return expectAsyncDependenciesToEqual([
|
||||||
['dep1', 'dep2'],
|
['dep1'],
|
||||||
['dep3', 'dep4']
|
['dep2'],
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
pit('shouldn\'t throw with ES6 arrow functions', () => {
|
|
||||||
fs.__setMockFilesystem({
|
|
||||||
'root': {
|
|
||||||
'index.js': 'require.ensure(["dep1", "dep2"], () => {});',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return expectAsyncDependenciesToEqual([['dep1', 'dep2']]);
|
|
||||||
});
|
|
||||||
|
|
||||||
pit('parse fine new lines', () => {
|
pit('parse fine new lines', () => {
|
||||||
fs.__setMockFilesystem({
|
fs.__setMockFilesystem({
|
||||||
'root': {
|
'root': {
|
||||||
'index.js': 'require.ensure(["dep1", \n"dep2"], () => {});',
|
'index.js': 'System.import(\n"dep1"\n)',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return expectAsyncDependenciesToEqual([['dep1', 'dep2']]);
|
return expectAsyncDependenciesToEqual([['dep1']]);
|
||||||
});
|
|
||||||
|
|
||||||
pit('ignore comments', () => {
|
|
||||||
fs.__setMockFilesystem({
|
|
||||||
'root': {
|
|
||||||
'index.js': 'require.ensure(["dep1", /*comment*/"dep2"], () => {});',
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return expectAsyncDependenciesToEqual([['dep1', 'dep2']]);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,4 +11,5 @@
|
||||||
|
|
||||||
exports.IMPORT_RE = /(\bimport\s+?(?:.+\s+?from\s+?)?)(['"])([^'"]+)(\2)/g;
|
exports.IMPORT_RE = /(\bimport\s+?(?:.+\s+?from\s+?)?)(['"])([^'"]+)(\2)/g;
|
||||||
exports.REQUIRE_RE = /(\brequire\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g;
|
exports.REQUIRE_RE = /(\brequire\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g;
|
||||||
exports.REQUIRE_ENSURE_RE = /\brequire\.ensure\s*\(\s*(?:\[([^\]]+)\])?/g;
|
exports.SYSTEM_IMPORT_RE = /(\bSystem\.import\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue