Skip to content

Commit

Permalink
* only render final resolutions for cross-chunk dynamic imports
Browse files Browse the repository at this point in the history
* do not create facades for inlined dynamic imports
  • Loading branch information
lukastaegert committed Feb 16, 2019
1 parent 180835a commit 671c74d
Show file tree
Hide file tree
Showing 40 changed files with 228 additions and 54 deletions.
11 changes: 7 additions & 4 deletions src/Chunk.ts
Expand Up @@ -135,7 +135,7 @@ export default class Chunk {
private renderedSource: MagicStringBundle | null = null;
private renderedSourceLength: number = undefined;

constructor(graph: Graph, orderedModules: Module[], inlineDynamicImports: boolean) {
constructor(graph: Graph, orderedModules: Module[]) {
this.graph = graph;
this.orderedModules = orderedModules;
this.execIndex = orderedModules.length > 0 ? orderedModules[0].execIndex : Infinity;
Expand All @@ -149,7 +149,10 @@ export default class Chunk {
this.isManualChunk = true;
}
module.chunk = this;
if (module.isEntryPoint || (module.isDynamicEntryPoint && !inlineDynamicImports)) {
if (
module.isEntryPoint ||
module.dynamicallyImportedBy.some(module => orderedModules.indexOf(module) === -1)
) {
this.entryModules.push(module);
}
}
Expand Down Expand Up @@ -378,8 +381,8 @@ export default class Chunk {
for (const { node, resolution } of module.dynamicImports) {
if (!resolution) continue;
if (resolution instanceof Module) {
const resolutionChunk = resolution.facadeChunk || resolution.chunk;
if (resolutionChunk && resolutionChunk !== this && resolutionChunk.id) {
if (resolution.isIncluded() && resolution.chunk !== this) {
const resolutionChunk = resolution.facadeChunk || resolution.chunk;
let relPath = normalize(relative(dirname(this.id), resolutionChunk.id));
if (!relPath.startsWith('../')) relPath = './' + relPath;
node.renderFinalResolution(code, `'${relPath}'`);
Expand Down
6 changes: 3 additions & 3 deletions src/Graph.ts
Expand Up @@ -413,7 +413,7 @@ export default class Graph {
let chunks: Chunk[] = [];
if (this.preserveModules) {
for (const module of orderedModules) {
const chunk = new Chunk(this, [module], inlineDynamicImports);
const chunk = new Chunk(this, [module]);
if (module.isEntryPoint || !chunk.isEmpty) {
chunk.entryModules = [module];
}
Expand All @@ -434,7 +434,7 @@ export default class Graph {
for (const entryHashSum in chunkModules) {
const chunkModulesOrdered = chunkModules[entryHashSum];
sortByExecutionOrder(chunkModulesOrdered);
const chunk = new Chunk(this, chunkModulesOrdered, inlineDynamicImports);
const chunk = new Chunk(this, chunkModulesOrdered);
chunks.push(chunk);
}
}
Expand Down Expand Up @@ -463,7 +463,7 @@ export default class Graph {
for (const chunk of chunks) {
for (const entryModule of chunk.entryModules) {
if (chunk.facadeModule !== entryModule) {
const entryPointFacade = new Chunk(this, [], inlineDynamicImports);
const entryPointFacade = new Chunk(this, []);
entryPointFacade.turnIntoFacade(entryModule);
facades.push(entryPointFacade);
}
Expand Down
4 changes: 2 additions & 2 deletions src/Module.ts
Expand Up @@ -160,6 +160,7 @@ export default class Module {
comments: CommentDescription[] = [];
customTransformCache: boolean;
dependencies: (Module | ExternalModule)[] = [];
dynamicallyImportedBy: Module[] = [];
dynamicDependencies: (Module | ExternalModule)[] = [];
dynamicImports: {
node: Import;
Expand All @@ -179,7 +180,6 @@ export default class Module {
importDescriptions: { [name: string]: ImportDescription } = Object.create(null);
importMetas: MetaProperty[] = [];
imports = new Set<Variable>();
isDynamicEntryPoint: boolean = false;
isEntryPoint: boolean = false;
isExecuted: boolean = false;
isExternal: false;
Expand Down Expand Up @@ -621,7 +621,7 @@ export default class Module {
const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node)
.resolution;
if (resolution instanceof Module) {
resolution.isDynamicEntryPoint = true;
resolution.dynamicallyImportedBy.push(this);
resolution.includeAllExports();
}
}
Expand Down
6 changes: 1 addition & 5 deletions src/ast/nodes/Import.ts
Expand Up @@ -47,7 +47,6 @@ export default class Import extends NodeBase {

private resolutionNamespace: string;
private resolutionInterop: boolean;
private replaced: boolean;

include() {
this.included = true;
Expand All @@ -56,14 +55,13 @@ export default class Import extends NodeBase {

initialise() {
this.included = false;
this.replaced = false;
this.resolutionNamespace = undefined;
this.resolutionInterop = false;
this.context.addDynamicImport(this);
}

renderFinalResolution(code: MagicString, resolution: string) {
if (this.included && !this.replaced) {
if (this.included) {
code.overwrite(this.parent.arguments[0].start, this.parent.arguments[0].end, resolution);
}
}
Expand All @@ -77,8 +75,6 @@ export default class Import extends NodeBase {
this.parent.end,
`Promise.resolve().then(function${_}()${_}{${_}return ${this.resolutionNamespace}${s}${_}})`
);

this.replaced = true;
return;
}

Expand Down
3 changes: 2 additions & 1 deletion src/rollup/index.ts
Expand Up @@ -215,7 +215,8 @@ export default function rollup(rawInputOptions: GenericConfigObject): Promise<Ro
facadeModuleId: facadeModule && facadeModule.id,
fileName: chunk.id,
imports: chunk.getImportIds(),
isDynamicEntry: facadeModule !== null && facadeModule.isDynamicEntryPoint,
isDynamicEntry:
facadeModule !== null && facadeModule.dynamicallyImportedBy.length > 0,
isEntry: facadeModule !== null && facadeModule.isEntryPoint,
map: undefined,
modules: chunk.renderedModules,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/chunkColouring.ts
Expand Up @@ -33,7 +33,7 @@ export function assignChunkColouringHashes(
for (const { resolution } of module.dynamicImports) {
if (
resolution instanceof Module &&
resolution.isDynamicEntryPoint &&
resolution.dynamicallyImportedBy.length > 0 &&
!resolution.chunkAlias
) {
dynamicImports.push(resolution);
Expand Down
@@ -0,0 +1,7 @@
module.exports = {
description:
'handles dynamic imports of previously statically imported chunks that are also dynamically imported by other chunks',
options: {
input: ['main.js', 'main2.js']
}
};
@@ -0,0 +1,20 @@
define(['require', 'exports'], function (require, exports) { 'use strict';

function foo() {
return 'dep2';
}

Promise.resolve().then(function () { return dep1; }).then(({ bar }) => console.log(bar()));

function bar() {
return foo();
}

var dep1 = /*#__PURE__*/Object.freeze({
bar: bar
});

exports.foo = foo;
exports.bar = bar;

});
@@ -0,0 +1,7 @@
define(['exports', './generated-chunk.js'], function (exports, dep1_js) { 'use strict';



exports.bar = dep1_js.bar;

});
@@ -1,5 +1,5 @@
define(['./generated-chunk.js'], function (dep1_js) { 'use strict';


console.log(dep1_js.foo(), dep1_js.bar());

});
@@ -0,0 +1,5 @@
define(['require'], function (require) { 'use strict';

new Promise(function (resolve, reject) { require(['./generated-chunk2.js'], resolve, reject) }).then(({ bar }) => console.log(bar()));

});
@@ -0,0 +1,18 @@
'use strict';

function foo() {
return 'dep2';
}

Promise.resolve().then(function () { return dep1; }).then(({ bar }) => console.log(bar()));

function bar() {
return foo();
}

var dep1 = /*#__PURE__*/Object.freeze({
bar: bar
});

exports.foo = foo;
exports.bar = bar;
@@ -0,0 +1,7 @@
'use strict';

var dep1_js = require('./generated-chunk.js');



exports.bar = dep1_js.bar;
@@ -0,0 +1,5 @@
'use strict';

var dep1_js = require('./generated-chunk.js');

console.log(dep1_js.foo(), dep1_js.bar());
@@ -0,0 +1,3 @@
'use strict';

Promise.resolve(require('./generated-chunk2.js')).then(({ bar }) => console.log(bar()));
@@ -0,0 +1,15 @@
function foo() {
return 'dep2';
}

Promise.resolve().then(function () { return dep1; }).then(({ bar }) => console.log(bar()));

function bar() {
return foo();
}

var dep1 = /*#__PURE__*/Object.freeze({
bar: bar
});

export { foo as a, bar as b };
@@ -0,0 +1 @@
export { b as bar } from './generated-chunk.js';
@@ -0,0 +1,3 @@
import { a as foo, b as bar } from './generated-chunk.js';

console.log(foo(), bar());
@@ -0,0 +1 @@
import('./generated-chunk2.js').then(({ bar }) => console.log(bar()));
@@ -0,0 +1,27 @@
System.register([], function (exports, module) {
'use strict';
return {
execute: function () {

exports({
a: foo,
b: bar
});

function foo() {
return 'dep2';
}

Promise.resolve().then(function () { return dep1; }).then(({ bar }) => console.log(bar()));

function bar() {
return foo();
}

var dep1 = /*#__PURE__*/Object.freeze({
bar: bar
});

}
};
});
@@ -1,7 +1,9 @@
System.register(['./generated-chunk.js'], function (exports, module) {
'use strict';
return {
setters: [function () {}],
setters: [function (module) {
exports('bar', module.b);
}],
execute: function () {


Expand Down
@@ -0,0 +1,15 @@
System.register(['./generated-chunk.js'], function (exports, module) {
'use strict';
var foo, bar;
return {
setters: [function (module) {
foo = module.a;
bar = module.b;
}],
execute: function () {

console.log(foo(), bar());

}
};
});
@@ -0,0 +1,10 @@
System.register([], function (exports, module) {
'use strict';
return {
execute: function () {

module.import('./generated-chunk2.js').then(({ bar }) => console.log(bar()));

}
};
});
@@ -0,0 +1,5 @@
import {foo} from './dep2.js';

export function bar() {
return foo();
}
@@ -0,0 +1,5 @@
export function foo() {
return 'dep2';
}

import('./dep1.js').then(({ bar }) => console.log(bar()));
@@ -0,0 +1,4 @@
import { bar } from './dep1.js';
import { foo } from './dep2.js';

console.log(foo(), bar());
@@ -0,0 +1 @@
import('./dep1.js').then(({ bar }) => console.log(bar()));
@@ -1,17 +1,20 @@
define(['require', 'exports'], function (require, exports) { 'use strict';

function foo() {
console.log('dep2');
return 'dep2';
}

Promise.resolve().then(function () { return dep1; });

Promise.resolve().then(function () { return dep1; }).then(({ bar }) => console.log(bar()));

function bar() {
return foo();
}

var dep1 = /*#__PURE__*/Object.freeze({

bar: bar
});

exports.foo = foo;
exports.bar = bar;

});
@@ -1,5 +1,5 @@
define(['./generated-chunk.js'], function (dep1_js) { 'use strict';
define(['./generated-chunk.js'], function (__chunk_1) { 'use strict';

dep1_js.foo();
console.log(__chunk_1.foo(), __chunk_1.bar());

});
@@ -1,15 +1,18 @@
'use strict';

function foo() {
console.log('dep2');
return 'dep2';
}

Promise.resolve().then(function () { return dep1; });

Promise.resolve().then(function () { return dep1; }).then(({ bar }) => console.log(bar()));

function bar() {
return foo();
}

var dep1 = /*#__PURE__*/Object.freeze({

bar: bar
});

exports.foo = foo;
exports.bar = bar;

This file was deleted.

0 comments on commit 671c74d

Please sign in to comment.