diff --git a/src/Chunk.ts b/src/Chunk.ts index 630d3134c92..6e883772567 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -7,7 +7,6 @@ import FunctionDeclaration from './ast/nodes/FunctionDeclaration'; import { UNDEFINED_EXPRESSION } from './ast/values'; import ExportDefaultVariable from './ast/variables/ExportDefaultVariable'; import ExportShimVariable from './ast/variables/ExportShimVariable'; -import GlobalVariable from './ast/variables/GlobalVariable'; import LocalVariable from './ast/variables/LocalVariable'; import NamespaceVariable from './ast/variables/NamespaceVariable'; import Variable from './ast/variables/Variable'; @@ -367,11 +366,10 @@ export default class Chunk { getRenderedHash(outputPluginDriver: PluginDriver): string { if (this.renderedHash) return this.renderedHash; - if (!this.renderedSource) return ''; const hash = createHash(); const hashAugmentation = this.calculateHashAugmentation(outputPluginDriver); hash.update(hashAugmentation); - hash.update(this.renderedSource.toString()); + hash.update(this.renderedSource!.toString()); hash.update( this.getExportNames() .map(exportName => { @@ -549,7 +547,7 @@ export default class Chunk { this.facadeModule !== null ) { for (const dep of this.dependencies) { - if (dep instanceof Chunk) this.inlineChunkDependencies(dep, true); + if (dep instanceof Chunk) this.inlineChunkDependencies(dep); } } const sortedDependencies = [...this.dependencies]; @@ -1012,16 +1010,12 @@ export default class Chunk { break; } } - } else if (variable instanceof GlobalVariable) { - hoisted = true; } - const localName = variable.getName(); - exports.push({ - exported: exportName === '*' ? localName : exportName, + exported: exportName, hoisted, - local: localName, + local: variable.getName(), uninitialized }); } @@ -1043,14 +1037,17 @@ export default class Chunk { return relativePath.startsWith('../') ? relativePath : './' + relativePath; } - private inlineChunkDependencies(chunk: Chunk, deep: boolean) { + private inlineChunkDependencies(chunk: Chunk) { for (const dep of chunk.dependencies) { if (dep instanceof ExternalModule) { this.dependencies.add(dep); } else { - if (dep === this) continue; + // At the moment, circular dependencies between chunks are not possible; this will + // change if we ever add logic to ensure correct execution order or open up the + // chunking to plugins + // if (dep === this) continue; this.dependencies.add(dep); - if (deep) this.inlineChunkDependencies(dep, true); + this.inlineChunkDependencies(dep); } } } diff --git a/src/Module.ts b/src/Module.ts index 62d49e835f0..83501d71bc0 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -587,12 +587,7 @@ export default class Module { linkDependencies() { for (const source of this.sources) { - const id = this.resolvedIds[source].id; - - if (id) { - const module = this.graph.moduleById.get(id)!; - this.dependencies.add(module); - } + this.dependencies.add(this.graph.moduleById.get(this.resolvedIds[source].id)!); } for (const { resolution } of this.dynamicImports) { if (resolution instanceof Module || resolution instanceof ExternalModule) { diff --git a/src/utils/chunkAssignment.ts b/src/utils/chunkAssignment.ts index 53d5f2c41b6..c0eaff596ab 100644 --- a/src/utils/chunkAssignment.ts +++ b/src/utils/chunkAssignment.ts @@ -65,11 +65,9 @@ export function getChunkAssignments( return true; } - if (manualChunkModules) { - for (const chunkName of Object.keys(manualChunkModules)) { - for (const entry of manualChunkModules[chunkName]) { - assignEntryToStaticDependencies(entry, null, chunkName); - } + for (const chunkName of Object.keys(manualChunkModules)) { + for (const entry of manualChunkModules[chunkName]) { + assignEntryToStaticDependencies(entry, null, chunkName); } } diff --git a/src/utils/executionOrder.ts b/src/utils/executionOrder.ts index 4f8997174f1..4ef4e7fde39 100644 --- a/src/utils/executionOrder.ts +++ b/src/utils/executionOrder.ts @@ -22,8 +22,6 @@ export function analyseModuleExecution(entryModules: Module[]) { const orderedModules: Module[] = []; const analyseModule = (module: Module | ExternalModule) => { - if (analysedModules.has(module)) return; - if (module instanceof Module) { for (const dependency of module.dependencies) { if (parents.has(dependency)) { @@ -74,7 +72,6 @@ function getCyclePath( while (nextModule !== module) { path.push(relativeId(nextModule.id)); nextModule = parents.get(nextModule)!; - if (!nextModule) break; } path.push(path[0]); path.reverse(); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_config.js new file mode 100644 index 00000000000..e3fdb18ef33 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: + 'avoids empty imports if they do not have side-effects when preserving modules (#3359)', + options: { + preserveModules: true + } +}; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/a.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/a.js new file mode 100644 index 00000000000..a0ee4d5c962 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/a.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + const a = 1; + + exports.a = a; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/b.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/b.js new file mode 100644 index 00000000000..71d3b650e8d --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/b.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + const b = 2; + + exports.b = b; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/main.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/main.js new file mode 100644 index 00000000000..854a7e8dca1 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/main.js @@ -0,0 +1,5 @@ +define(['./a', './one'], function (a, one) { 'use strict'; + + console.log(a.a + one.d); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/one.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/one.js new file mode 100644 index 00000000000..2d8ca9bd394 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/one.js @@ -0,0 +1,9 @@ +define(['exports', './b'], function (exports, b) { 'use strict'; + + const d = b.b + 4; + + exports.d = d; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/a.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/a.js new file mode 100644 index 00000000000..97007408241 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/a.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const a = 1; + +exports.a = a; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/b.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/b.js new file mode 100644 index 00000000000..3c417e8458a --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/b.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const b = 2; + +exports.b = b; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/main.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/main.js new file mode 100644 index 00000000000..c691c0d47e9 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/main.js @@ -0,0 +1,6 @@ +'use strict'; + +var a = require('./a.js'); +var one = require('./one.js'); + +console.log(a.a + one.d); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/one.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/one.js new file mode 100644 index 00000000000..9eea4c87a9f --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/one.js @@ -0,0 +1,9 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var b = require('./b.js'); + +const d = b.b + 4; + +exports.d = d; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/a.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/a.js new file mode 100644 index 00000000000..089815c5bdd --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/a.js @@ -0,0 +1,3 @@ +const a = 1; + +export { a }; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/b.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/b.js new file mode 100644 index 00000000000..27b49eddabb --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/b.js @@ -0,0 +1,3 @@ +const b = 2; + +export { b }; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/main.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/main.js new file mode 100644 index 00000000000..0b42cf037c6 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/main.js @@ -0,0 +1,4 @@ +import { a } from './a.js'; +import { d } from './one.js'; + +console.log(a + d); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/one.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/one.js new file mode 100644 index 00000000000..d9291f1bff3 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/one.js @@ -0,0 +1,5 @@ +import { b } from './b.js'; + +const d = b + 4; + +export { d }; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/a.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/a.js new file mode 100644 index 00000000000..50f0d7760ca --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/a.js @@ -0,0 +1,10 @@ +System.register([], function (exports) { + 'use strict'; + return { + execute: function () { + + const a = exports('a', 1); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/b.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/b.js new file mode 100644 index 00000000000..baa28369184 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/b.js @@ -0,0 +1,10 @@ +System.register([], function (exports) { + 'use strict'; + return { + execute: function () { + + const b = exports('b', 2); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/main.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/main.js new file mode 100644 index 00000000000..306aa2895cd --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/main.js @@ -0,0 +1,16 @@ +System.register(['./a.js', './one.js'], function () { + 'use strict'; + var a, d; + return { + setters: [function (module) { + a = module.a; + }, function (module) { + d = module.d; + }], + execute: function () { + + console.log(a + d); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/one.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/one.js new file mode 100644 index 00000000000..dac01a3453c --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/one.js @@ -0,0 +1,14 @@ +System.register(['./b.js'], function (exports) { + 'use strict'; + var b; + return { + setters: [function (module) { + b = module.b; + }], + execute: function () { + + const d = exports('d', b + 4); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/a.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/a.js new file mode 100644 index 00000000000..cc798ff50da --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/a.js @@ -0,0 +1 @@ +export const a = 1; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/b.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/b.js new file mode 100644 index 00000000000..202103085ce --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/b.js @@ -0,0 +1 @@ +export const b = 2; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/c.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/c.js new file mode 100644 index 00000000000..5f0cabef84f --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/c.js @@ -0,0 +1 @@ +export const c = 3; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/index.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/index.js new file mode 100644 index 00000000000..c2357812df9 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/index.js @@ -0,0 +1,3 @@ +export { a } from './a'; +export { b } from './b'; +export { c } from './c'; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/main.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/main.js new file mode 100644 index 00000000000..6279273d11d --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/main.js @@ -0,0 +1,3 @@ +import { a } from './index'; +import { d } from './one'; +console.log(a + d); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/one.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/one.js new file mode 100644 index 00000000000..8a9f8689a62 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/one.js @@ -0,0 +1,2 @@ +import { b } from './index'; +export const d = b + 4;