mirror of https://github.com/status-im/metro.git
[react-packager] Introduce bundle IDs and keep track of parent/child
Summary: Since JS doesn't have the guarantee that once a bundle is loaded it will stay in memory (and this is something we actually don't want to enforce to keep memmory usage low), we need to keep track of parent/child relationships on the packager to pass it down to native. As part of this diff, we also introduced an ID for each bundle. The ID for a child bundle is shynthetized as the bundleID of the parent module + an index which gets incremented every time a new bundle is created. For instance given this tree: a,b c f d e g the ID for `d` will be `bundle.0.1.2`, the one for e will be `bundle.0.1.3` and the one for `g` will be `bundle.0.5.6`. This information will be useful to figure out which bundles need to be loaded when a `require.ensure` is re-written.
This commit is contained in:
parent
54a8fe9156
commit
06eb63b54d
|
@ -29,8 +29,15 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPolyfill() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function dep(path) {
|
function dep(path) {
|
||||||
return {path};
|
return {
|
||||||
|
path: path,
|
||||||
|
isPolyfill: isPolyfill,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pit('should bundle sync dependencies', () => {
|
pit('should bundle sync dependencies', () => {
|
||||||
|
@ -52,9 +59,11 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(bundles).toEqual([
|
expect(bundles).toEqual({
|
||||||
[dep('/root/index.js'), dep('/root/a.js')],
|
id: 'bundle.0',
|
||||||
])
|
modules: [dep('/root/index.js'), dep('/root/a.js')],
|
||||||
|
children: [],
|
||||||
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -77,10 +86,15 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(bundles).toEqual([
|
expect(bundles).toEqual({
|
||||||
[dep('/root/index.js')],
|
id: 'bundle.0',
|
||||||
[dep('/root/a.js')],
|
modules: [dep('/root/index.js')],
|
||||||
])
|
children: [{
|
||||||
|
id:'bundle.0.1',
|
||||||
|
modules: [dep('/root/a.js')],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,11 +122,19 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(bundles).toEqual([
|
expect(bundles).toEqual({
|
||||||
[dep('/root/index.js')],
|
id: 'bundle.0',
|
||||||
[dep('/root/a.js')],
|
modules: [dep('/root/index.js')],
|
||||||
[dep('/root/b.js')],
|
children: [{
|
||||||
])
|
id: 'bundle.0.1',
|
||||||
|
modules: [dep('/root/a.js')],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1.2',
|
||||||
|
modules: [dep('/root/b.js')],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -140,10 +162,15 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(bundles).toEqual([
|
expect(bundles).toEqual({
|
||||||
[dep('/root/index.js')],
|
id: 'bundle.0',
|
||||||
[dep('/root/a.js'), dep('/root/b.js')],
|
modules: [dep('/root/index.js')],
|
||||||
])
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: [dep('/root/a.js'), dep('/root/b.js')],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -171,10 +198,15 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(
|
||||||
bundles => expect(bundles).toEqual([
|
bundles => expect(bundles).toEqual({
|
||||||
[dep('/root/index.js'), dep('/root/a.js')],
|
id: 'bundle.0',
|
||||||
[dep('/root/b.js')],
|
modules: [dep('/root/index.js'), dep('/root/a.js')],
|
||||||
])
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: [dep('/root/b.js')],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -184,7 +216,7 @@ describe('BundlesLayout', () => {
|
||||||
case '/root/index.js':
|
case '/root/index.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
dependencies: [dep('/root/index.js'), dep('/root/a.js')],
|
dependencies: [dep('/root/index.js'), dep('/root/a.js')],
|
||||||
asyncDependencies: [['/root/b.js']],
|
asyncDependencies: [['/root/b.js'], ['/root/c.js']],
|
||||||
});
|
});
|
||||||
case '/root/a.js':
|
case '/root/a.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
|
@ -194,13 +226,18 @@ describe('BundlesLayout', () => {
|
||||||
case '/root/b.js':
|
case '/root/b.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
dependencies: [dep('/root/b.js')],
|
dependencies: [dep('/root/b.js')],
|
||||||
asyncDependencies: [['/root/c.js']],
|
asyncDependencies: [['/root/d.js']],
|
||||||
});
|
});
|
||||||
case '/root/c.js':
|
case '/root/c.js':
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
dependencies: [dep('/root/c.js')],
|
dependencies: [dep('/root/c.js')],
|
||||||
asyncDependencies: [],
|
asyncDependencies: [],
|
||||||
});
|
});
|
||||||
|
case '/root/d.js':
|
||||||
|
return Promise.resolve({
|
||||||
|
dependencies: [dep('/root/d.js')],
|
||||||
|
asyncDependencies: [],
|
||||||
|
});
|
||||||
default:
|
default:
|
||||||
throw 'Undefined path: ' + path;
|
throw 'Undefined path: ' + path;
|
||||||
}
|
}
|
||||||
|
@ -208,10 +245,11 @@ describe('BundlesLayout', () => {
|
||||||
|
|
||||||
var layout = newBundlesLayout();
|
var layout = newBundlesLayout();
|
||||||
return layout.generateLayout(['/root/index.js']).then(() => {
|
return layout.generateLayout(['/root/index.js']).then(() => {
|
||||||
expect(layout.getBundleIDForModule('/root/index.js')).toBe(0);
|
expect(layout.getBundleIDForModule('/root/index.js')).toBe('bundle.0');
|
||||||
expect(layout.getBundleIDForModule('/root/a.js')).toBe(0);
|
expect(layout.getBundleIDForModule('/root/a.js')).toBe('bundle.0');
|
||||||
expect(layout.getBundleIDForModule('/root/b.js')).toBe(1);
|
expect(layout.getBundleIDForModule('/root/b.js')).toBe('bundle.0.1');
|
||||||
expect(layout.getBundleIDForModule('/root/c.js')).toBe(2);
|
expect(layout.getBundleIDForModule('/root/c.js')).toBe('bundle.0.2');
|
||||||
|
expect(layout.getBundleIDForModule('/root/d.js')).toBe('bundle.0.1.3');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -78,15 +78,37 @@ describe('BundlesLayout', () => {
|
||||||
return new BundlesLayout({dependencyResolver: resolver});
|
return new BundlesLayout({dependencyResolver: resolver});
|
||||||
}
|
}
|
||||||
|
|
||||||
function modulePaths(bundles) {
|
function stripPolyfills(bundle) {
|
||||||
if (!bundles) {
|
return Promise
|
||||||
return null;
|
.all([
|
||||||
}
|
Promise.all(
|
||||||
|
bundle.modules.map(module => module
|
||||||
|
.getName()
|
||||||
|
.then(name => [module, name])
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Promise.all(
|
||||||
|
bundle.children.map(childModule => stripPolyfills(childModule)),
|
||||||
|
),
|
||||||
|
])
|
||||||
|
.then(([modules, children]) => {
|
||||||
|
modules = modules
|
||||||
|
.filter(([module, name]) => { // filter polyfills
|
||||||
|
for (let p of polyfills) {
|
||||||
|
if (name.indexOf(p) !== -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map(([module, name]) => module.path);
|
||||||
|
|
||||||
return bundles.map(
|
return {
|
||||||
bundle => bundle.filter(module => !module.isPolyfill())
|
id: bundle.id,
|
||||||
.map(module => module.path)
|
modules: modules,
|
||||||
);
|
children: children,
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setMockFilesystem(mockFs) {
|
function setMockFilesystem(mockFs) {
|
||||||
|
@ -104,10 +126,12 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
modulePaths(bundles).then(paths =>
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
expect(paths).toEqual([
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/index.js'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [],
|
||||||
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -128,9 +152,13 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js', '/root/a.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
])
|
id: 'bundle.0',
|
||||||
|
modules: ['/root/index.js', '/root/a.js'],
|
||||||
|
children: [],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -150,10 +178,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -178,11 +213,23 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js'],
|
id: 'bundle.0',
|
||||||
['/root/b.js'],
|
modules: ['/root/index.js'],
|
||||||
])
|
children: [
|
||||||
|
{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js'],
|
||||||
|
children: [],
|
||||||
|
}, {
|
||||||
|
id: 'bundle.0.2',
|
||||||
|
modules: ['/root/b.js'],
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -206,10 +253,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js', '/root/b.js'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js', '/root/b.js'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -234,10 +288,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js', '/root/a.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/b.js'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js', '/root/a.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/b.js'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -267,10 +328,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js', '/root/b.js', '/root/c.js'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js', '/root/b.js', '/root/c.js'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -301,11 +369,24 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js', '/root/c.js'],
|
id: 'bundle.0',
|
||||||
['/root/b.js', '/root/c.js'],
|
modules: ['/root/index.js'],
|
||||||
])
|
children: [
|
||||||
|
{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js', '/root/c.js'],
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'bundle.0.2',
|
||||||
|
modules: ['/root/b.js', '/root/c.js'],
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -335,11 +416,23 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js'],
|
id: 'bundle.0',
|
||||||
['/root/b.js', '/root/c.js'],
|
modules: ['/root/index.js'],
|
||||||
])
|
children: [
|
||||||
|
{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1.2',
|
||||||
|
modules: ['/root/b.js', '/root/c.js'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -369,10 +462,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js', '/root/c.js', '/root/b.js'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js', '/root/c.js', '/root/b.js'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -394,10 +494,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js', '/root/img.png'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js', '/root/img.png'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -425,11 +532,24 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js', '/root/img.png'],
|
id: 'bundle.0',
|
||||||
['/root/b.js', '/root/img.png'],
|
modules: ['/root/index.js'],
|
||||||
])
|
children: [
|
||||||
|
{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js', '/root/img.png'],
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'bundle.0.2',
|
||||||
|
modules: ['/root/b.js', '/root/img.png'],
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -446,10 +566,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/img.png'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/img.png'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -471,10 +598,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/a.js', '/root/img.png'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/a.js', '/root/img.png'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -491,10 +625,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/img.png'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/img.png'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -521,10 +662,17 @@ describe('BundlesLayout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
return newBundlesLayout().generateLayout(['/root/index.js']).then(bundles =>
|
||||||
expect(modulePaths(bundles)).toEqual([
|
stripPolyfills(bundles).then(resolvedBundles =>
|
||||||
['/root/index.js'],
|
expect(resolvedBundles).toEqual({
|
||||||
['/root/aPackage/client.js'],
|
id: 'bundle.0',
|
||||||
])
|
modules: ['/root/index.js'],
|
||||||
|
children: [{
|
||||||
|
id: 'bundle.0.1',
|
||||||
|
modules: ['/root/aPackage/client.js'],
|
||||||
|
children: [],
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,6 +18,8 @@ const validateOpts = declareOpts({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const BUNDLE_PREFIX = 'bundle';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that takes care of separating the graph of dependencies into
|
* Class that takes care of separating the graph of dependencies into
|
||||||
* separate bundles
|
* separate bundles
|
||||||
|
@ -31,16 +33,23 @@ class BundlesLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
generateLayout(entryPaths, isDev) {
|
generateLayout(entryPaths, isDev) {
|
||||||
const bundles = [];
|
var currentBundleID = 0;
|
||||||
var pending = [entryPaths];
|
const rootBundle = {
|
||||||
|
id: BUNDLE_PREFIX + '.' + currentBundleID++,
|
||||||
|
modules: [],
|
||||||
|
children: [],
|
||||||
|
};
|
||||||
|
var pending = [{paths: entryPaths, bundle: rootBundle}];
|
||||||
|
|
||||||
return promiseWhile(
|
return promiseWhile(
|
||||||
() => pending.length > 0,
|
() => pending.length > 0,
|
||||||
() => bundles,
|
() => rootBundle,
|
||||||
() => {
|
() => {
|
||||||
|
const {paths, bundle} = pending.shift();
|
||||||
|
|
||||||
// pending sync dependencies we still need to explore for the current
|
// pending sync dependencies we still need to explore for the current
|
||||||
// pending dependency
|
// pending dependency
|
||||||
let pendingSyncDeps = pending.shift();
|
const pendingSyncDeps = paths;
|
||||||
|
|
||||||
// accum variable for sync dependencies of the current pending
|
// accum variable for sync dependencies of the current pending
|
||||||
// dependency we're processing
|
// dependency we're processing
|
||||||
|
@ -51,22 +60,31 @@ class BundlesLayout {
|
||||||
() => {
|
() => {
|
||||||
const dependencies = _.values(syncDependencies);
|
const dependencies = _.values(syncDependencies);
|
||||||
if (dependencies.length > 0) {
|
if (dependencies.length > 0) {
|
||||||
bundles.push(dependencies);
|
bundle.modules = dependencies;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
() => {
|
index => {
|
||||||
const pendingSyncDep = pendingSyncDeps.shift();
|
const pendingSyncDep = pendingSyncDeps.shift();
|
||||||
return this._resolver
|
return this._resolver
|
||||||
.getDependencies(pendingSyncDep, {dev: isDev})
|
.getDependencies(pendingSyncDep, {dev: isDev})
|
||||||
.then(deps => {
|
.then(deps => {
|
||||||
deps.dependencies.forEach(dep => {
|
deps.dependencies.forEach(dep => {
|
||||||
if (dep.path !== pendingSyncDep && !dep.isPolyfill) {
|
if (dep.path !== pendingSyncDep && !dep.isPolyfill()) {
|
||||||
pendingSyncDeps.push(dep.path);
|
pendingSyncDeps.push(dep.path);
|
||||||
}
|
}
|
||||||
syncDependencies[dep.path] = dep;
|
syncDependencies[dep.path] = dep;
|
||||||
this._moduleToBundle[dep.path] = bundles.length;
|
this._moduleToBundle[dep.path] = bundle.id;
|
||||||
|
});
|
||||||
|
deps.asyncDependencies.forEach(asyncDeps => {
|
||||||
|
const childBundle = {
|
||||||
|
id: bundle.id + '.' + currentBundleID++,
|
||||||
|
modules: [],
|
||||||
|
children: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
bundle.children.push(childBundle);
|
||||||
|
pending.push({paths: asyncDeps, bundle: childBundle});
|
||||||
});
|
});
|
||||||
pending = pending.concat(deps.asyncDependencies);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -83,11 +101,17 @@ class BundlesLayout {
|
||||||
// Once it's not satisfied anymore, it returns what the results callback
|
// Once it's not satisfied anymore, it returns what the results callback
|
||||||
// indicates
|
// indicates
|
||||||
function promiseWhile(condition, result, body) {
|
function promiseWhile(condition, result, body) {
|
||||||
|
return _promiseWhile(condition, result, body, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _promiseWhile(condition, result, body, index) {
|
||||||
if (!condition()) {
|
if (!condition()) {
|
||||||
return Promise.resolve(result());
|
return Promise.resolve(result());
|
||||||
}
|
}
|
||||||
|
|
||||||
return body().then(() => promiseWhile(condition, result, body));
|
return body(index).then(() =>
|
||||||
|
_promiseWhile(condition, result, body, index + 1)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = BundlesLayout;
|
module.exports = BundlesLayout;
|
||||||
|
|
Loading…
Reference in New Issue