From 156b9c0cb205cf807db5d32d89e1114573baac8b Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Thu, 30 Jan 2020 15:48:34 +0100 Subject: [PATCH 1/9] Respect moduleSideEffects when inlining empty imports --- src/Chunk.ts | 21 ++++++++--- src/Module.ts | 35 +++++++++++-------- src/utils/chunkColouring.ts | 4 +-- .../_config.js | 9 +++++ .../_expected/amd/main1.js | 7 ++++ .../_expected/amd/main2.js | 5 +++ .../_expected/cjs/main1.js | 5 +++ .../_expected/cjs/main2.js | 3 ++ .../_expected/es/main1.js | 3 ++ .../_expected/es/main2.js | 1 + .../_expected/system/main1.js | 12 +++++++ .../_expected/system/main2.js | 10 ++++++ .../module-side-effects-empty-imports/dep.js | 1 + .../main1.js | 2 ++ .../main2.js | 2 ++ 15 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_config.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main1.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main2.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main1.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main2.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main1.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main2.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main1.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main2.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/dep.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/main1.js create mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/main2.js diff --git a/src/Chunk.ts b/src/Chunk.ts index e4e28ffbad9..4d95329a480 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -408,10 +408,11 @@ export default class Chunk { link() { const dependencies: Set = new Set(); const dynamicDependencies: Set = new Set(); + // TODO Lukas turn dependencies into sets for (const module of this.orderedModules) { - this.addDependenciesToChunk(module.getTransitiveDependencies(), dependencies); + this.addDependenciesToChunk(module.getDependenciesToBeIncluded(), dependencies); this.addDependenciesToChunk(module.dynamicDependencies, dynamicDependencies); - this.setUpChunkImportsAndExportsForModule(module); + this.setUpChunkImportsAndExportsForModule(module, dependencies); } this.dependencies = Array.from(dependencies); this.dynamicDependencies = Array.from(dynamicDependencies); @@ -804,7 +805,7 @@ export default class Chunk { } private addDependenciesToChunk( - moduleDependencies: (Module | ExternalModule)[], + moduleDependencies: Set, chunkDependencies: Set ) { for (const depModule of moduleDependencies) { @@ -1165,7 +1166,10 @@ export default class Chunk { ); } - private setUpChunkImportsAndExportsForModule(module: Module) { + private setUpChunkImportsAndExportsForModule( + module: Module, + chunkDependencies: Set + ) { for (const variable of module.imports) { if ((variable.module as Module).chunk !== this) { this.imports.add(variable); @@ -1179,8 +1183,17 @@ export default class Chunk { module.dynamicallyImportedBy.some(importer => importer.chunk !== this) ) { const map = module.getExportNamesByVariable(); + // TODO Lukas in the end, sort dependencies by execution order? for (const exportedVariable of map.keys()) { this.exports.add(exportedVariable); + const exportSourceModule = exportedVariable.module!; + const exportChunk = + exportSourceModule instanceof ExternalModule + ? exportSourceModule + : exportSourceModule.chunk!; + if (exportChunk !== this) { + chunkDependencies.add(exportChunk); + } const exportingModule = exportedVariable.module; if (exportingModule && exportingModule.chunk && exportingModule.chunk !== this) { exportingModule.chunk.exports.add(exportedVariable); diff --git a/src/Module.ts b/src/Module.ts index 2e194f552e9..3c8d459aac8 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -194,9 +194,9 @@ export default class Module { code!: string; comments: CommentDescription[] = []; customTransformCache!: boolean; - dependencies: (Module | ExternalModule)[] = []; + dependencies = new Set(); dynamicallyImportedBy: Module[] = []; - dynamicDependencies: (Module | ExternalModule)[] = []; + dynamicDependencies = new Set(); dynamicImports: { node: ImportExpression; resolution: Module | ExternalModule | string | null; @@ -240,6 +240,7 @@ export default class Module { private graph: Graph; private magicString!: MagicString; private namespaceVariable: NamespaceVariable | null = null; + private relevantDependencies: Set | null = null; private syntheticExports = new Map(); private transformDependencies: string[] = []; private transitiveReexports: string[] | null = null; @@ -341,6 +342,20 @@ export default class Module { return this.defaultExport; } + getDependenciesToBeIncluded(): Set { + if (this.relevantDependencies) return this.relevantDependencies; + const relevantDependencies = new Set(); + for (const variable of this.imports) { + relevantDependencies.add(variable.module!); + } + for (const dependency of this.dependencies) { + if (dependency.moduleSideEffects) { + relevantDependencies.add(dependency); + } + } + return (this.relevantDependencies = relevantDependencies); + } + getDynamicImportExpressions(): (string | Node)[] { return this.dynamicImports.map(({ node }) => { const importArgument = node.source; @@ -424,14 +439,6 @@ export default class Module { return { renderedExports, removedExports }; } - getTransitiveDependencies() { - return this.dependencies.concat( - this.getReexports() - .concat(this.getExports()) - .map((exportName: string) => this.getVariableForExportName(exportName).module as Module) - ); - } - getVariableForExportName( name: string, isExportAllSearch?: boolean, @@ -560,13 +567,13 @@ export default class Module { const id = this.resolvedIds[source].id; if (id) { - const module = this.graph.moduleById.get(id); - this.dependencies.push(module as Module); + const module = this.graph.moduleById.get(id)!; + this.dependencies.add(module); } } for (const { resolution } of this.dynamicImports) { if (resolution instanceof Module || resolution instanceof ExternalModule) { - this.dynamicDependencies.push(resolution); + this.dynamicDependencies.add(resolution); } } @@ -697,7 +704,7 @@ export default class Module { ast: this.esTreeAst, code: this.code, customTransformCache: this.customTransformCache, - dependencies: this.dependencies.map(module => module.id), + dependencies: Array.from(this.dependencies).map(module => module.id), id: this.id, moduleSideEffects: this.moduleSideEffects, originalCode: this.originalCode, diff --git a/src/utils/chunkColouring.ts b/src/utils/chunkColouring.ts index 1f4873ff169..1c35b4afa31 100644 --- a/src/utils/chunkColouring.ts +++ b/src/utils/chunkColouring.ts @@ -39,7 +39,7 @@ export function assignChunkColouringHashes( } else { Uint8ArrayXor(module.entryPointsHash, colour); } - for (const dependency of module.dependencies) { + for (const dependency of module.getDependenciesToBeIncluded()) { if (!(dependency instanceof ExternalModule || dependency.manualChunkAlias)) { modulesToHandle.add(dependency); } @@ -106,7 +106,7 @@ function analyzeModuleGraph( const modulesToHandle = new Set([currentEntry]); for (const module of modulesToHandle) { getDependentModules(dependentEntryPointsByModule, module).add(currentEntry); - for (const dependency of module.dependencies) { + for (const dependency of module.getDependenciesToBeIncluded()) { if (!(dependency instanceof ExternalModule)) { modulesToHandle.add(dependency); } diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_config.js b/test/chunking-form/samples/module-side-effects-empty-imports/_config.js new file mode 100644 index 00000000000..615562a76d9 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/_config.js @@ -0,0 +1,9 @@ +module.exports = { + description: 'avoids empty imports if moduleSideEffects are false', + options: { + input: ['main1', 'main2'], + treeshake: { + moduleSideEffects: false + } + } +}; diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main1.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main1.js new file mode 100644 index 00000000000..46da3a11689 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main1.js @@ -0,0 +1,7 @@ +define(function () { 'use strict'; + + var dep = 42; + + console.log('main1', dep); + +}); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main2.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main2.js new file mode 100644 index 00000000000..b58286ca58e --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main2.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + console.log('main2'); + +}); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main1.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main1.js new file mode 100644 index 00000000000..b058f5de697 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main1.js @@ -0,0 +1,5 @@ +'use strict'; + +var dep = 42; + +console.log('main1', dep); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main2.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main2.js new file mode 100644 index 00000000000..33fe6f320c2 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main2.js @@ -0,0 +1,3 @@ +'use strict'; + +console.log('main2'); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main1.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main1.js new file mode 100644 index 00000000000..b68d1df59ab --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main1.js @@ -0,0 +1,3 @@ +var dep = 42; + +console.log('main1', dep); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main2.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main2.js new file mode 100644 index 00000000000..ac653633351 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main2.js @@ -0,0 +1 @@ +console.log('main2'); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main1.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main1.js new file mode 100644 index 00000000000..514a1366350 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main1.js @@ -0,0 +1,12 @@ +System.register([], function () { + 'use strict'; + return { + execute: function () { + + var dep = 42; + + console.log('main1', dep); + + } + }; +}); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main2.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main2.js new file mode 100644 index 00000000000..a272843f834 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main2.js @@ -0,0 +1,10 @@ +System.register([], function () { + 'use strict'; + return { + execute: function () { + + console.log('main2'); + + } + }; +}); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/dep.js b/test/chunking-form/samples/module-side-effects-empty-imports/dep.js new file mode 100644 index 00000000000..7a4e8a723a4 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/dep.js @@ -0,0 +1 @@ +export default 42; diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/main1.js b/test/chunking-form/samples/module-side-effects-empty-imports/main1.js new file mode 100644 index 00000000000..5f3346008f7 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/main1.js @@ -0,0 +1,2 @@ +import dep from './dep.js'; +console.log('main1', dep); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/main2.js b/test/chunking-form/samples/module-side-effects-empty-imports/main2.js new file mode 100644 index 00000000000..5abd0ce7185 --- /dev/null +++ b/test/chunking-form/samples/module-side-effects-empty-imports/main2.js @@ -0,0 +1,2 @@ +import dep from './dep.js'; +console.log('main2'); From 9d0ed8a4d426cdcd6e873dc0ecd7777eba7fb73b Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Thu, 30 Jan 2020 20:21:28 +0100 Subject: [PATCH 2/9] Make dependencies a Set --- src/Chunk.ts | 175 +++++++++++++++++------------------ src/utils/deconflictChunk.ts | 8 +- test/watch/index.js | 3 +- 3 files changed, 88 insertions(+), 98 deletions(-) diff --git a/src/Chunk.ts b/src/Chunk.ts index 4d95329a480..e2524e069b5 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -130,8 +130,7 @@ export default class Chunk { if (!facadedModule.facadeChunk) { facadedModule.facadeChunk = chunk; } - chunk.dependencies = [facadedModule.chunk!]; - chunk.dynamicDependencies = []; + chunk.dependencies.add(facadedModule.chunk!); chunk.facadeModule = facadedModule; for (const exportName of facadedModule.getAllExportNames()) { const tracedVariable = facadedModule.getVariableForExportName(exportName); @@ -157,18 +156,19 @@ export default class Chunk { usedModules: Module[] = undefined as any; variableName = 'chunk'; - private dependencies: (ExternalModule | Chunk)[] = undefined as any; - private dynamicDependencies: (ExternalModule | Chunk)[] = undefined as any; + private dependencies = new Set(); + private dynamicDependencies = new Set(); private exportNames: { [name: string]: Variable } = Object.create(null); private exports = new Set(); private fileName: string | null = null; private imports = new Set(); private name: string | null = null; private needsExportsShim = false; - private renderedDeclarations: { - dependencies: ChunkDependencies; - exports: ChunkExports; - } = undefined as any; + private renderedDependencies: Map< + ExternalModule | Chunk, + ModuleDeclarationDependency + > | null = null; + private renderedExports: ChunkExports | null = null; private renderedHash: string = undefined as any; private renderedModuleSources = new Map(); private renderedSource: MagicStringBundle | null = null; @@ -357,7 +357,9 @@ export default class Chunk { } getDynamicImportIds(): string[] { - return this.dynamicDependencies.map(chunk => chunk.id).filter(Boolean) as string[]; + return Array.from(this.dynamicDependencies) + .map(chunk => chunk.id) + .filter(Boolean) as string[]; } getExportNames(): string[] { @@ -367,7 +369,9 @@ export default class Chunk { } getImportIds(): string[] { - return this.dependencies.map(chunk => chunk.id).filter(Boolean) as string[]; + return Array.from(this.dependencies) + .map(chunk => chunk.id) + .filter(Boolean) as string[]; } getRenderedHash(outputPluginDriver: PluginDriver): string { @@ -406,16 +410,11 @@ export default class Chunk { } link() { - const dependencies: Set = new Set(); - const dynamicDependencies: Set = new Set(); - // TODO Lukas turn dependencies into sets for (const module of this.orderedModules) { - this.addDependenciesToChunk(module.getDependenciesToBeIncluded(), dependencies); - this.addDependenciesToChunk(module.dynamicDependencies, dynamicDependencies); - this.setUpChunkImportsAndExportsForModule(module, dependencies); + this.addDependenciesToChunk(module.getDependenciesToBeIncluded(), this.dependencies); + this.addDependenciesToChunk(module.dynamicDependencies, this.dynamicDependencies); + this.setUpChunkImportsAndExportsForModule(module); } - this.dependencies = Array.from(dependencies); - this.dynamicDependencies = Array.from(dynamicDependencies); } /* @@ -498,26 +497,33 @@ export default class Chunk { // also update their import and reexport names in the process for (const c of chunkList) { let includedDeclaration: ModuleDeclarationDependency = undefined as any; - for (let i = 0; i < c.dependencies.length; i++) { - const dep = c.dependencies[i]; + const dependencies = Array.from(c.dependencies); + const renderedDependencies = dependencies.map(dep => c.renderedDependencies!.get(dep)); + for (let i = 0; i < dependencies.length; i++) { + const dep = dependencies[i]; if ((dep === chunk || dep === this) && includedDeclaration) { - const duplicateDeclaration = c.renderedDeclarations.dependencies[i]; + const duplicateDeclaration = renderedDependencies[i]!; updateRenderedDeclaration( duplicateDeclaration, dep === chunk ? chunk.exportNames : thisOldExportNames ); mergeRenderedDeclaration(includedDeclaration, duplicateDeclaration); - c.renderedDeclarations.dependencies.splice(i, 1); - c.dependencies.splice(i--, 1); + renderedDependencies.splice(i, 1); + dependencies.splice(i--, 1); } else if (dep === chunk) { - c.dependencies[i] = this; - includedDeclaration = c.renderedDeclarations.dependencies[i]; + dependencies[i] = this; + includedDeclaration = renderedDependencies[i]!; updateRenderedDeclaration(includedDeclaration, chunk.exportNames); } else if (dep === this) { - includedDeclaration = c.renderedDeclarations.dependencies[i]; + includedDeclaration = renderedDependencies[i]!; updateRenderedDeclaration(includedDeclaration, thisOldExportNames); } } + c.dependencies = new Set(dependencies); + c.renderedDependencies = new Map(); + for (let i = 0; i < dependencies.length; i++) { + c.renderedDependencies.set(dependencies[i], renderedDependencies[i]!); + } } // re-render the merged chunk @@ -545,15 +551,6 @@ export default class Chunk { varOrConst: options.preferConst ? 'const' : 'var' }; - // Make sure the direct dependencies of a chunk are present to maintain execution order - for (const { module } of this.imports) { - const chunkOrExternal = (module instanceof Module ? module.chunk : module) as - | Chunk - | ExternalModule; - if (this.dependencies.indexOf(chunkOrExternal) === -1) { - this.dependencies.push(chunkOrExternal); - } - } // for static and dynamic entry points, inline the execution list to avoid loading latency if ( options.hoistTransitiveImports !== false && @@ -565,14 +562,16 @@ export default class Chunk { } } // prune empty dependency chunks, inlining their side-effect dependencies - for (let i = 0; i < this.dependencies.length; i++) { - const dep = this.dependencies[i]; - if (dep instanceof Chunk && dep.isEmpty) { - this.dependencies.splice(i--, 1); - this.inlineChunkDependencies(dep, false); + for (const dependency of this.dependencies) { + if (dependency instanceof Chunk && dependency.isEmpty) { + this.dependencies.delete(dependency); + this.inlineChunkDependencies(dependency, false); } } - sortByExecutionOrder(this.dependencies); + // TODO Lukas filtering and sorting dependencies, could this be done earlier? + const sortedDependencies = Array.from(this.dependencies); + sortByExecutionOrder(sortedDependencies); + this.dependencies = new Set(sortedDependencies); this.prepareDynamicImports(); this.setIdentifierRenderResolutions(options); @@ -624,7 +623,7 @@ export default class Chunk { this.renderedSourceLength = undefined as any; this.renderedHash = undefined as any; - if (this.isEmpty && this.getExportNames().length === 0 && this.dependencies.length === 0) { + if (this.isEmpty && this.getExportNames().length === 0 && this.dependencies.size === 0) { const chunkName = this.getChunkName(); this.graph.warn({ chunkName, @@ -635,10 +634,8 @@ export default class Chunk { this.setExternalRenderPaths(options, inputBase); - this.renderedDeclarations = { - dependencies: this.getChunkDependencyDeclarations(options), - exports: this.exportMode === 'none' ? [] : this.getChunkExportDeclarations() - }; + this.renderedDependencies = this.getChunkDependencyDeclarations(options); + this.renderedExports = this.exportMode === 'none' ? [] : this.getChunkExportDeclarations(); timeEnd('render modules', 3); } @@ -662,13 +659,12 @@ export default class Chunk { // populate ids in the rendered declarations only here // as chunk ids known only after prerender - for (let i = 0; i < this.dependencies.length; i++) { - const dep = this.dependencies[i]; - if (dep instanceof ExternalModule && !dep.renormalizeRenderPath) continue; - - const renderedDependency = this.renderedDeclarations.dependencies[i]; - const depId = dep instanceof ExternalModule ? renderedDependency.id : dep.id!; - if (dep instanceof Chunk) renderedDependency.namedExportsMode = dep.exportMode !== 'default'; + for (const dependency of this.dependencies) { + if (dependency instanceof ExternalModule && !dependency.renormalizeRenderPath) continue; + const renderedDependency = this.renderedDependencies!.get(dependency)!; + const depId = dependency instanceof ExternalModule ? renderedDependency.id : dependency.id!; + if (dependency instanceof Chunk) + renderedDependency.namedExportsMode = dependency.exportMode !== 'default'; renderedDependency.id = this.getRelativePath(depId); } @@ -676,8 +672,8 @@ export default class Chunk { this.finaliseImportMetas(format, outputPluginDriver); const hasExports = - this.renderedDeclarations.exports.length !== 0 || - this.renderedDeclarations.dependencies.some( + this.renderedExports!.length !== 0 || + Array.from(this.renderedDependencies!.values()).some( dep => (dep.reexports && dep.reexports.length !== 0)! ); @@ -708,8 +704,8 @@ export default class Chunk { this.renderedSource!, { accessedGlobals, - dependencies: this.renderedDeclarations.dependencies, - exports: this.renderedDeclarations.exports, + dependencies: Array.from(this.renderedDependencies!.values()), + exports: this.renderedExports!, hasExports, indentString: this.indentString, intro: addons.intro!, @@ -772,21 +768,6 @@ export default class Chunk { }); } - visitDependencies(handleDependency: (dependency: Chunk | ExternalModule) => void) { - const toBeVisited: (Chunk | ExternalModule)[] = [this]; - const visited: Set = new Set(); - for (const current of toBeVisited) { - handleDependency(current); - if (current instanceof ExternalModule) continue; - for (const dependency of current.dependencies.concat(current.dynamicDependencies)) { - if (!visited.has(dependency)) { - visited.add(dependency); - toBeVisited.push(dependency); - } - } - } - } - visitStaticDependenciesUntilCondition( isConditionSatisfied: (dep: Chunk | ExternalModule) => any ): boolean { @@ -874,15 +855,22 @@ export default class Chunk { [addons.intro, addons.outro, addons.banner, addons.footer].map(addon => addon || '').join(':') ); hash.update(options.format as string); - this.visitDependencies(dep => { - if (dep instanceof ExternalModule) { - hash.update(':' + dep.renderPath); + const dependenciesForHashing = new Set([this]); + for (const current of dependenciesForHashing) { + if (current instanceof ExternalModule) { + hash.update(':' + current.renderPath); } else { - hash.update(dep.getRenderedHash(outputPluginDriver)); - hash.update(dep.generateId(addons, options, existingNames, false, outputPluginDriver)); + hash.update(current.getRenderedHash(outputPluginDriver)); + hash.update(current.generateId(addons, options, existingNames, false, outputPluginDriver)); } - }); - + if (current instanceof ExternalModule) continue; + for (const dependency of current.dependencies) { + dependenciesForHashing.add(dependency); + } + for (const dependency of current.dynamicDependencies) { + dependenciesForHashing.add(dependency); + } + } return hash.digest('hex').substr(0, 8); } @@ -924,7 +912,9 @@ export default class Chunk { } } - private getChunkDependencyDeclarations(options: OutputOptions): ChunkDependencies { + private getChunkDependencyDeclarations( + options: OutputOptions + ): Map { const reexportDeclarations = new Map(); for (let exportName of this.getExportNames()) { @@ -956,7 +946,7 @@ export default class Chunk { } const renderedImports = new Set(); - const dependencies: ChunkDependencies = []; + const dependencies = new Map(); for (const dep of this.dependencies) { const imports: ImportSpecifier[] = []; @@ -1007,7 +997,7 @@ export default class Chunk { } } - dependencies.push({ + dependencies.set(dep, { exportsDefault, exportsNames, globalName, @@ -1082,10 +1072,10 @@ export default class Chunk { private inlineChunkDependencies(chunk: Chunk, deep: boolean) { for (const dep of chunk.dependencies) { if (dep instanceof ExternalModule) { - if (this.dependencies.indexOf(dep) === -1) this.dependencies.push(dep); + this.dependencies.add(dep); } else { - if (dep === this || this.dependencies.indexOf(dep) !== -1) continue; - if (!dep.isEmpty) this.dependencies.push(dep); + if (dep === this) continue; + if (!dep.isEmpty) this.dependencies.add(dep); if (deep) this.inlineChunkDependencies(dep, true); } } @@ -1110,7 +1100,12 @@ export default class Chunk { } private setExternalRenderPaths(options: OutputOptions, inputBase: string) { - for (const dependency of this.dependencies.concat(this.dynamicDependencies)) { + for (const dependency of this.dependencies) { + if (dependency instanceof ExternalModule) { + dependency.setRenderPath(options, inputBase); + } + } + for (const dependency of this.dynamicDependencies) { if (dependency instanceof ExternalModule) { dependency.setRenderPath(options, inputBase); } @@ -1166,10 +1161,7 @@ export default class Chunk { ); } - private setUpChunkImportsAndExportsForModule( - module: Module, - chunkDependencies: Set - ) { + private setUpChunkImportsAndExportsForModule(module: Module) { for (const variable of module.imports) { if ((variable.module as Module).chunk !== this) { this.imports.add(variable); @@ -1183,7 +1175,6 @@ export default class Chunk { module.dynamicallyImportedBy.some(importer => importer.chunk !== this) ) { const map = module.getExportNamesByVariable(); - // TODO Lukas in the end, sort dependencies by execution order? for (const exportedVariable of map.keys()) { this.exports.add(exportedVariable); const exportSourceModule = exportedVariable.module!; @@ -1192,7 +1183,7 @@ export default class Chunk { ? exportSourceModule : exportSourceModule.chunk!; if (exportChunk !== this) { - chunkDependencies.add(exportChunk); + this.dependencies.add(exportChunk); } const exportingModule = exportedVariable.module; if (exportingModule && exportingModule.chunk && exportingModule.chunk !== this) { diff --git a/src/utils/deconflictChunk.ts b/src/utils/deconflictChunk.ts index 1d2431d98af..6f0d78c0667 100644 --- a/src/utils/deconflictChunk.ts +++ b/src/utils/deconflictChunk.ts @@ -9,7 +9,7 @@ const DECONFLICT_IMPORTED_VARIABLES_BY_FORMAT: { [format: string]: ( usedNames: Set, imports: Set, - dependencies: (ExternalModule | Chunk)[], + dependencies: Set, interop: boolean, preserveModules: boolean ) => void; @@ -24,7 +24,7 @@ const DECONFLICT_IMPORTED_VARIABLES_BY_FORMAT: { export function deconflictChunk( modules: Module[], - dependencies: (ExternalModule | Chunk)[], + dependencies: Set, imports: Set, usedNames: Set, format: string, @@ -51,7 +51,7 @@ export function deconflictChunk( function deconflictImportsEsm( usedNames: Set, imports: Set, - _dependencies: (ExternalModule | Chunk)[], + _dependencies: Set, interop: boolean ) { for (const variable of imports) { @@ -74,7 +74,7 @@ function deconflictImportsEsm( function deconflictImportsOther( usedNames: Set, imports: Set, - dependencies: (ExternalModule | Chunk)[], + dependencies: Set, interop: boolean, preserveModules: boolean ) { diff --git a/test/watch/index.js b/test/watch/index.js index cdb540e2928..c573f90f2bd 100644 --- a/test/watch/index.js +++ b/test/watch/index.js @@ -867,8 +867,7 @@ describe('rollup.watch', () => { format: 'cjs', entryFileNames: '[name].[hash].js', chunkFileNames: '[name].[hash].js' - }, - experimentalCodeSplitting: true + } }); return sequence(watcher, [ From 12155fd00398932a6592b491f4edc831df3b88be Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Fri, 31 Jan 2020 15:43:34 +0100 Subject: [PATCH 3/9] Also handle side-effect free reexports correctly without generating separate chunks --- src/Module.ts | 11 +++++++++++ .../_expected/amd/main1.js | 7 ------- .../_expected/cjs/main1.js | 5 ----- .../_expected/es/main1.js | 3 --- .../samples/module-side-effects-empty-imports/dep.js | 1 - .../module-side-effects-empty-imports/main1.js | 2 -- .../module-side-effects-empty-imports/main2.js | 2 -- .../module-side-effects-empty-imports/_config.js | 1 + .../_expected/amd/main1.js | 8 ++++++++ .../_expected/amd/main2.js | 0 .../_expected/cjs/main1.js | 6 ++++++ .../_expected/cjs/main2.js | 0 .../_expected/es/main1.js | 4 ++++ .../_expected/es/main2.js | 0 .../_expected/system/main1.js | 5 +++-- .../_expected/system/main2.js | 0 .../module-side-effects-empty-imports/dep.js | 2 ++ .../module-side-effects-empty-imports/main1.js | 2 ++ .../module-side-effects-empty-imports/main2.js | 2 ++ .../module-side-effects-reexports-1/_config.js | 8 ++++++++ .../_expected/amd/main.js | 9 +++++++++ .../_expected/cjs/main.js | 7 +++++++ .../_expected/es/main.js | 3 +++ .../_expected/system/main.js | 10 ++++++++++ .../module-side-effects-reexports-1/dep1.js | 1 + .../module-side-effects-reexports-1/dep2.js | 1 + .../module-side-effects-reexports-1/main.js | 1 + .../module-side-effects-reexports-2/_config.js | 8 ++++++++ .../_expected/amd/main.js | 9 +++++++++ .../_expected/cjs/main.js | 7 +++++++ .../_expected/es/main.js | 3 +++ .../_expected/system/main.js | 10 ++++++++++ .../module-side-effects-reexports-2/dep1.js | 1 + .../module-side-effects-reexports-2/dep2.js | 1 + .../module-side-effects-reexports-2/main.js | 2 ++ .../module-side-effects-reexports-3/_config.js | 8 ++++++++ .../_expected/amd/main.js | 9 +++++++++ .../_expected/cjs/main.js | 7 +++++++ .../_expected/es/main.js | 3 +++ .../_expected/system/main.js | 10 ++++++++++ .../module-side-effects-reexports-3/dep1.js | 1 + .../module-side-effects-reexports-3/dep2.js | 1 + .../module-side-effects-reexports-3/main.js | 1 + 43 files changed, 160 insertions(+), 22 deletions(-) delete mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main1.js delete mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main1.js delete mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main1.js delete mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/dep.js delete mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/main1.js delete mode 100644 test/chunking-form/samples/module-side-effects-empty-imports/main2.js rename test/chunking-form/samples/{ => side-effect-free-dependencies}/module-side-effects-empty-imports/_config.js (67%) create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/amd/main1.js rename test/chunking-form/samples/{ => side-effect-free-dependencies}/module-side-effects-empty-imports/_expected/amd/main2.js (100%) create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/cjs/main1.js rename test/chunking-form/samples/{ => side-effect-free-dependencies}/module-side-effects-empty-imports/_expected/cjs/main2.js (100%) create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/es/main1.js rename test/chunking-form/samples/{ => side-effect-free-dependencies}/module-side-effects-empty-imports/_expected/es/main2.js (100%) rename test/chunking-form/samples/{ => side-effect-free-dependencies}/module-side-effects-empty-imports/_expected/system/main1.js (52%) rename test/chunking-form/samples/{ => side-effect-free-dependencies}/module-side-effects-empty-imports/_expected/system/main2.js (100%) create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/dep.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_config.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/amd/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/es/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/system/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/dep1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/dep2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_config.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/amd/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/es/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/system/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/dep1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/dep2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/amd/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/es/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/system/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/dep1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/dep2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/main.js diff --git a/src/Module.ts b/src/Module.ts index 3c8d459aac8..adf5d746851 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -348,11 +348,22 @@ export default class Module { for (const variable of this.imports) { relevantDependencies.add(variable.module!); } + if (this.isEntryPoint || this.dynamicallyImportedBy.length > 0) { + for (const exportName of this.getReexports().concat(this.getExports())) { + relevantDependencies.add(this.getVariableForExportName(exportName).module as Module); + } + } for (const dependency of this.dependencies) { if (dependency.moduleSideEffects) { relevantDependencies.add(dependency); } } + // TODO Lukas remove + // console.log( + // 'relevantDependencies', + // this.id.split('/').slice(-1)[0], + // Array.from(relevantDependencies).map(module => module.id.split('/').slice(-1)[0]) + // ); return (this.relevantDependencies = relevantDependencies); } diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main1.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main1.js deleted file mode 100644 index 46da3a11689..00000000000 --- a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main1.js +++ /dev/null @@ -1,7 +0,0 @@ -define(function () { 'use strict'; - - var dep = 42; - - console.log('main1', dep); - -}); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main1.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main1.js deleted file mode 100644 index b058f5de697..00000000000 --- a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main1.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -var dep = 42; - -console.log('main1', dep); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main1.js b/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main1.js deleted file mode 100644 index b68d1df59ab..00000000000 --- a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main1.js +++ /dev/null @@ -1,3 +0,0 @@ -var dep = 42; - -console.log('main1', dep); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/dep.js b/test/chunking-form/samples/module-side-effects-empty-imports/dep.js deleted file mode 100644 index 7a4e8a723a4..00000000000 --- a/test/chunking-form/samples/module-side-effects-empty-imports/dep.js +++ /dev/null @@ -1 +0,0 @@ -export default 42; diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/main1.js b/test/chunking-form/samples/module-side-effects-empty-imports/main1.js deleted file mode 100644 index 5f3346008f7..00000000000 --- a/test/chunking-form/samples/module-side-effects-empty-imports/main1.js +++ /dev/null @@ -1,2 +0,0 @@ -import dep from './dep.js'; -console.log('main1', dep); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/main2.js b/test/chunking-form/samples/module-side-effects-empty-imports/main2.js deleted file mode 100644 index 5abd0ce7185..00000000000 --- a/test/chunking-form/samples/module-side-effects-empty-imports/main2.js +++ /dev/null @@ -1,2 +0,0 @@ -import dep from './dep.js'; -console.log('main2'); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_config.js similarity index 67% rename from test/chunking-form/samples/module-side-effects-empty-imports/_config.js rename to test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_config.js index 615562a76d9..8715cf7802c 100644 --- a/test/chunking-form/samples/module-side-effects-empty-imports/_config.js +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_config.js @@ -1,3 +1,4 @@ +// TODO Lukas at the moment, there is probably an "empty" catch-all chunk that is pruned module.exports = { description: 'avoids empty imports if moduleSideEffects are false', options: { diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/amd/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/amd/main1.js new file mode 100644 index 00000000000..b6a9613a883 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/amd/main1.js @@ -0,0 +1,8 @@ +define(function () { 'use strict'; + + var value = 42; + console.log('Ignored side-effect'); + + console.log('main1', value); + +}); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/amd/main2.js similarity index 100% rename from test/chunking-form/samples/module-side-effects-empty-imports/_expected/amd/main2.js rename to test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/amd/main2.js diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/cjs/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/cjs/main1.js new file mode 100644 index 00000000000..c8249e7e0a6 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/cjs/main1.js @@ -0,0 +1,6 @@ +'use strict'; + +var value = 42; +console.log('Ignored side-effect'); + +console.log('main1', value); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/cjs/main2.js similarity index 100% rename from test/chunking-form/samples/module-side-effects-empty-imports/_expected/cjs/main2.js rename to test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/cjs/main2.js diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/es/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/es/main1.js new file mode 100644 index 00000000000..8651d00af96 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/es/main1.js @@ -0,0 +1,4 @@ +var value = 42; +console.log('Ignored side-effect'); + +console.log('main1', value); diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/es/main2.js similarity index 100% rename from test/chunking-form/samples/module-side-effects-empty-imports/_expected/es/main2.js rename to test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/es/main2.js diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/system/main1.js similarity index 52% rename from test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main1.js rename to test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/system/main1.js index 514a1366350..8eb92a30566 100644 --- a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main1.js +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/system/main1.js @@ -3,9 +3,10 @@ System.register([], function () { return { execute: function () { - var dep = 42; + var value = 42; + console.log('Ignored side-effect'); - console.log('main1', dep); + console.log('main1', value); } }; diff --git a/test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/system/main2.js similarity index 100% rename from test/chunking-form/samples/module-side-effects-empty-imports/_expected/system/main2.js rename to test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_expected/system/main2.js diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/dep.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/dep.js new file mode 100644 index 00000000000..472d9677f34 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/dep.js @@ -0,0 +1,2 @@ +export default 42; +console.log('Ignored side-effect'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/main1.js new file mode 100644 index 00000000000..41c2bef1288 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/main1.js @@ -0,0 +1,2 @@ +import value from './dep.js'; +console.log('main1', value); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/main2.js new file mode 100644 index 00000000000..e11a466317a --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/main2.js @@ -0,0 +1,2 @@ +import value from './dep.js'; +console.log('main2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_config.js new file mode 100644 index 00000000000..ba74be8e44a --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_config.js @@ -0,0 +1,8 @@ +module.exports = { + description: 'handles re-exports in entry points if moduleSideEffects are false', + options: { + treeshake: { + moduleSideEffects: false + } + } +}; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/amd/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/amd/main.js new file mode 100644 index 00000000000..876aec76659 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/amd/main.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + const value = 42; + + exports.value = value; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/cjs/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/cjs/main.js new file mode 100644 index 00000000000..181fa0fd711 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/cjs/main.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const value = 42; + +exports.value = value; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/es/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/es/main.js new file mode 100644 index 00000000000..d897952f7d1 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/es/main.js @@ -0,0 +1,3 @@ +const value = 42; + +export { value }; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/system/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/system/main.js new file mode 100644 index 00000000000..437f1af456e --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/_expected/system/main.js @@ -0,0 +1,10 @@ +System.register([], function (exports) { + 'use strict'; + return { + execute: function () { + + const value = exports('value', 42); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/dep1.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/dep1.js new file mode 100644 index 00000000000..9e4b436de45 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/dep1.js @@ -0,0 +1 @@ +export * from './dep2.js'; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/dep2.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/dep2.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/dep2.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/main.js new file mode 100644 index 00000000000..3f9d655d03d --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-1/main.js @@ -0,0 +1 @@ +export { value } from './dep1.js'; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_config.js new file mode 100644 index 00000000000..ba74be8e44a --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_config.js @@ -0,0 +1,8 @@ +module.exports = { + description: 'handles re-exports in entry points if moduleSideEffects are false', + options: { + treeshake: { + moduleSideEffects: false + } + } +}; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/amd/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/amd/main.js new file mode 100644 index 00000000000..876aec76659 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/amd/main.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + const value = 42; + + exports.value = value; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/cjs/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/cjs/main.js new file mode 100644 index 00000000000..181fa0fd711 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/cjs/main.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const value = 42; + +exports.value = value; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/es/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/es/main.js new file mode 100644 index 00000000000..d897952f7d1 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/es/main.js @@ -0,0 +1,3 @@ +const value = 42; + +export { value }; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/system/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/system/main.js new file mode 100644 index 00000000000..437f1af456e --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/_expected/system/main.js @@ -0,0 +1,10 @@ +System.register([], function (exports) { + 'use strict'; + return { + execute: function () { + + const value = exports('value', 42); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/dep1.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/dep1.js new file mode 100644 index 00000000000..9e4b436de45 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/dep1.js @@ -0,0 +1 @@ +export * from './dep2.js'; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/dep2.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/dep2.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/dep2.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/main.js new file mode 100644 index 00000000000..36969d3aa6f --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-2/main.js @@ -0,0 +1,2 @@ +import { value } from './dep1.js'; +export { value }; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js new file mode 100644 index 00000000000..ba74be8e44a --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js @@ -0,0 +1,8 @@ +module.exports = { + description: 'handles re-exports in entry points if moduleSideEffects are false', + options: { + treeshake: { + moduleSideEffects: false + } + } +}; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/amd/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/amd/main.js new file mode 100644 index 00000000000..876aec76659 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/amd/main.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + const value = 42; + + exports.value = value; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/cjs/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/cjs/main.js new file mode 100644 index 00000000000..181fa0fd711 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/cjs/main.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const value = 42; + +exports.value = value; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/es/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/es/main.js new file mode 100644 index 00000000000..d897952f7d1 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/es/main.js @@ -0,0 +1,3 @@ +const value = 42; + +export { value }; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/system/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/system/main.js new file mode 100644 index 00000000000..437f1af456e --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_expected/system/main.js @@ -0,0 +1,10 @@ +System.register([], function (exports) { + 'use strict'; + return { + execute: function () { + + const value = exports('value', 42); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/dep1.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/dep1.js new file mode 100644 index 00000000000..9e4b436de45 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/dep1.js @@ -0,0 +1 @@ +export * from './dep2.js'; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/dep2.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/dep2.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/dep2.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/main.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/main.js new file mode 100644 index 00000000000..07f5262f08a --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/main.js @@ -0,0 +1 @@ +export * from './dep1.js'; From c02b874739a0693d2d1e3c97c828abeaf2c487d7 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Mon, 3 Feb 2020 07:15:05 +0100 Subject: [PATCH 4/9] Infer side-effect free modules and hoist side-effects --- src/Module.ts | 28 ++++++++++++++--- src/ast/nodes/Program.ts | 8 ++++- .../_expected/amd/generated-dep1.js | 1 + .../_expected/amd/generated-dep2.js | 1 + .../_expected/amd/generated-shared2.js | 2 ++ .../_expected/cjs/generated-dep1.js | 1 + .../_expected/cjs/generated-dep2.js | 1 + .../_expected/cjs/generated-shared2.js | 2 ++ .../_expected/es/generated-dep1.js | 1 + .../_expected/es/generated-dep2.js | 1 + .../_expected/es/generated-shared2.js | 2 ++ .../_expected/system/generated-dep1.js | 2 +- .../_expected/system/generated-dep2.js | 2 +- .../_expected/system/generated-shared2.js | 2 ++ .../chunk-deshadowing-reassignment/dep1.js | 3 +- .../chunk-deshadowing-reassignment/dep2.js | 3 +- .../chunk-deshadowing-reassignment/shared1.js | 3 +- .../chunk-deshadowing-reassignment/shared2.js | 3 +- .../_expected/amd/generated-lib.js | 6 ++-- .../_expected/amd/main1.js | 12 ++++---- .../_expected/amd/main2.js | 2 +- .../_expected/cjs/generated-lib.js | 4 +-- .../_expected/cjs/main1.js | 8 +++-- .../_expected/cjs/main2.js | 1 + .../_expected/es/generated-lib.js | 4 +-- .../_expected/es/main1.js | 8 +++-- .../_expected/es/main2.js | 2 ++ .../_expected/system/generated-lib.js | 16 +++++----- .../_expected/system/main1.js | 30 ++++++++++--------- .../_expected/system/main2.js | 14 ++++----- .../samples/chunk-import-deshadowing/dep1.js | 8 +++-- .../samples/chunk-import-deshadowing/dep2.js | 8 +++-- .../samples/chunk-import-deshadowing/lib.js | 8 ++--- .../_expected/amd/generated-separate.js | 1 + .../_expected/amd/main1.js | 1 + .../_expected/cjs/generated-separate.js | 1 + .../_expected/cjs/main1.js | 1 + .../_expected/es/generated-separate.js | 1 + .../_expected/es/main1.js | 1 + .../_expected/system/generated-separate.js | 1 + .../_expected/system/main1.js | 1 + .../inlined.js | 1 + .../separate.js | 1 + .../_expected/amd/main2.js | 3 +- .../_expected/cjs/main2.js | 4 ++- .../_expected/es/main2.js | 5 +++- .../_expected/system/main2.js | 8 +++-- .../import-variable-duplicates/main1.js | 2 +- .../import-variable-duplicates/main2.js | 7 +++-- .../_expected/amd/main3.js | 2 +- .../_expected/cjs/main3.js | 3 +- .../_expected/es/main3.js | 4 ++- .../_expected/system/main3.js | 7 +++-- .../namespace-reexport-name-conflict/index.js | 1 - .../namespace-reexport-name-conflict/main3.js | 3 +- .../_expected/amd/generated-bar.js | 2 +- .../_expected/amd/generated-foo.js | 2 +- .../_expected/cjs/generated-bar.js | 2 -- .../_expected/cjs/generated-foo.js | 2 -- .../_expected/es/generated-bar.js | 2 -- .../_expected/es/generated-foo.js | 2 -- .../_expected/system/generated-bar.js | 3 +- .../_expected/system/generated-foo.js | 3 +- .../_expected/amd/commonjs.js | 4 +-- .../_expected/cjs/commonjs.js | 5 ++-- .../_expected/es/commonjs.js | 1 - .../_expected/system/commonjs.js | 4 +-- .../_expected/amd/generated-dep2.js | 1 + .../_expected/cjs/generated-dep2.js | 1 + .../_expected/es/generated-dep2.js | 1 + .../_expected/system/generated-dep2.js | 1 + .../samples/reexport-shortpaths/dep2.js | 3 +- .../samples/reexport-shortpaths/main1.js | 3 +- .../samples/reexport-shortpaths/main2.js | 2 +- .../samples/reexport-shortpaths/main3.js | 2 +- .../_expected/amd/main.js | 1 + .../_expected/cjs/main.js | 1 + .../_expected/es/main.js | 1 + .../_expected/system/main.js | 1 + .../resolve-dynamic-import/existing.js | 1 + .../_config.js | 7 +++++ .../_expected/amd/main1.js | 9 ++++++ .../_expected/amd/main2.js | 5 ++++ .../_expected/cjs/main1.js | 9 ++++++ .../_expected/cjs/main2.js | 5 ++++ .../_expected/es/main1.js | 7 +++++ .../_expected/es/main2.js | 3 ++ .../_expected/system/main1.js | 15 ++++++++++ .../_expected/system/main2.js | 11 +++++++ .../dep1.js | 5 ++++ .../main1.js | 2 ++ .../main2.js | 2 ++ .../hoist-side-effect-modules/_config.js | 8 +++++ .../_expected/amd/generated-dep2-effect.js | 5 ++++ .../_expected/amd/generated-dep4-effect.js | 5 ++++ .../_expected/amd/main1.js | 11 +++++++ .../_expected/amd/main2.js | 5 ++++ .../_expected/amd/main3.js | 5 ++++ .../_expected/cjs/generated-dep2-effect.js | 3 ++ .../_expected/cjs/generated-dep4-effect.js | 3 ++ .../_expected/cjs/main1.js | 12 ++++++++ .../_expected/cjs/main2.js | 6 ++++ .../_expected/cjs/main3.js | 5 ++++ .../_expected/es/generated-dep2-effect.js | 1 + .../_expected/es/generated-dep4-effect.js | 1 + .../_expected/es/main1.js | 10 +++++++ .../_expected/es/main2.js | 4 +++ .../_expected/es/main3.js | 3 ++ .../_expected/system/generated-dep2-effect.js | 10 +++++++ .../_expected/system/generated-dep4-effect.js | 10 +++++++ .../_expected/system/main1.js | 17 +++++++++++ .../_expected/system/main2.js | 11 +++++++ .../_expected/system/main3.js | 11 +++++++ .../hoist-side-effect-modules/dep1.js | 6 ++++ .../hoist-side-effect-modules/dep2-effect.js | 1 + .../hoist-side-effect-modules/dep3.js | 3 ++ .../hoist-side-effect-modules/dep4-effect.js | 1 + .../hoist-side-effect-modules/main1.js | 3 ++ .../hoist-side-effect-modules/main2.js | 2 ++ .../hoist-side-effect-modules/main3.js | 2 ++ .../_config.js | 1 + test/hooks/index.js | 6 ++-- test/misc/bundle-information.js | 4 +-- 123 files changed, 445 insertions(+), 117 deletions(-) create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_config.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/amd/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/amd/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/cjs/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/cjs/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/es/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/es/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/system/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/system/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/dep1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_config.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/generated-dep2-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/generated-dep4-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main3.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/generated-dep2-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/generated-dep4-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main3.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/generated-dep2-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/generated-dep4-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main3.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/generated-dep2-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/generated-dep4-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main3.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep2-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep3.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep4-effect.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main1.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main2.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main3.js diff --git a/src/Module.ts b/src/Module.ts index adf5d746851..7a2cad0d918 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -3,7 +3,11 @@ import * as ESTree from 'estree'; import { locate } from 'locate-character'; import MagicString from 'magic-string'; import extractAssignedNames from 'rollup-pluginutils/src/extractAssignedNames'; -import { createInclusionContext, InclusionContext } from './ast/ExecutionContext'; +import { + createHasEffectsContext, + createInclusionContext, + InclusionContext +} from './ast/ExecutionContext'; import ExportAllDeclaration from './ast/nodes/ExportAllDeclaration'; import ExportDefaultDeclaration from './ast/nodes/ExportDefaultDeclaration'; import ExportNamedDeclaration from './ast/nodes/ExportNamedDeclaration'; @@ -348,13 +352,29 @@ export default class Module { for (const variable of this.imports) { relevantDependencies.add(variable.module!); } - if (this.isEntryPoint || this.dynamicallyImportedBy.length > 0) { + if (this.isEntryPoint || this.dynamicallyImportedBy.length > 0 || this.graph.preserveModules) { for (const exportName of this.getReexports().concat(this.getExports())) { relevantDependencies.add(this.getVariableForExportName(exportName).module as Module); } } - for (const dependency of this.dependencies) { - if (dependency.moduleSideEffects) { + // TODO Lukas this could be a performance risk + if (this.graph.treeshakingOptions) { + const possibleDependencies = new Set(this.dependencies); + for (const dependency of possibleDependencies) { + if (!dependency.moduleSideEffects || relevantDependencies.has(dependency)) continue; + if ( + dependency instanceof ExternalModule || + (dependency.ast.included && dependency.ast.hasEffects(createHasEffectsContext())) + ) { + relevantDependencies.add(dependency); + } else { + for (const transitiveDependency of dependency.dependencies) { + possibleDependencies.add(transitiveDependency); + } + } + } + } else { + for (const dependency of this.dependencies) { relevantDependencies.add(dependency); } } diff --git a/src/ast/nodes/Program.ts b/src/ast/nodes/Program.ts index 8b5351c9b19..287722c9332 100644 --- a/src/ast/nodes/Program.ts +++ b/src/ast/nodes/Program.ts @@ -9,9 +9,15 @@ export default class Program extends NodeBase { sourceType!: 'module'; type!: NodeType.tProgram; + private hasCachedEffect = false; + hasEffects(context: HasEffectsContext) { + // We are caching here to later more efficiently identify side-effect-free modules + if (this.hasCachedEffect) return true; for (const node of this.body) { - if (node.hasEffects(context)) return true; + if (node.hasEffects(context)) { + return (this.hasCachedEffect = true); + } } return false; } diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-dep1.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-dep1.js index 23394b47956..9b17fe9ee5f 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-dep1.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-dep1.js @@ -1,6 +1,7 @@ define(['exports'], function (exports) { 'use strict'; var x = 42; + console.log('dep1'); exports.x = x; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-dep2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-dep2.js index 71f00bd9c70..cb1482e274a 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-dep2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-dep2.js @@ -1,6 +1,7 @@ define(['exports'], function (exports) { 'use strict'; var x = 43; + console.log('dep2'); exports.x = x; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-shared2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-shared2.js index 04c631986fa..e847953e2bd 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-shared2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/amd/generated-shared2.js @@ -1,8 +1,10 @@ define(['exports', './generated-dep1', './generated-dep2'], function (exports, dep1, dep2) { 'use strict'; var x = dep1.x + 1; + console.log('shared1'); var y = dep2.x + 1; + console.log('shared2'); exports.x = x; exports.y = y; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-dep1.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-dep1.js index 90fa851318c..0832148cd65 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-dep1.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-dep1.js @@ -1,5 +1,6 @@ 'use strict'; var x = 42; +console.log('dep1'); exports.x = x; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-dep2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-dep2.js index c123080ab7f..2d4b0b3b7e2 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-dep2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-dep2.js @@ -1,5 +1,6 @@ 'use strict'; var x = 43; +console.log('dep2'); exports.x = x; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-shared2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-shared2.js index 5482042bab1..6dfe1e7a09f 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-shared2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/cjs/generated-shared2.js @@ -4,8 +4,10 @@ var dep1 = require('./generated-dep1.js'); var dep2 = require('./generated-dep2.js'); var x = dep1.x + 1; +console.log('shared1'); var y = dep2.x + 1; +console.log('shared2'); exports.x = x; exports.y = y; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-dep1.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-dep1.js index b90c581245b..d6d2ae2cb09 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-dep1.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-dep1.js @@ -1,3 +1,4 @@ var x = 42; +console.log('dep1'); export { x }; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-dep2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-dep2.js index b2caa9826a4..2ba7d8fc572 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-dep2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-dep2.js @@ -1,3 +1,4 @@ var x = 43; +console.log('dep2'); export { x }; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-shared2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-shared2.js index 15af511db49..f0db7b88f4a 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-shared2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/es/generated-shared2.js @@ -2,7 +2,9 @@ import { x as x$1 } from './generated-dep1.js'; import { x as x$2 } from './generated-dep2.js'; var x = x$1 + 1; +console.log('shared1'); var y = x$2 + 1; +console.log('shared2'); export { x, y }; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep1.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep1.js index 80adb5c2211..ac898b84f11 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep1.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep1.js @@ -4,7 +4,7 @@ System.register([], function (exports) { execute: function () { var x = 42; - exports('x', x); + exports('x', x);console.log('dep1'); } }; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep2.js index 6c2a87f635a..1ddbb4ea71a 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-dep2.js @@ -4,7 +4,7 @@ System.register([], function (exports) { execute: function () { var x = 43; - exports('x', x); + exports('x', x);console.log('dep2'); } }; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-shared2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-shared2.js index a72e59cac53..e3daf5963c5 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-shared2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/_expected/system/generated-shared2.js @@ -10,8 +10,10 @@ System.register(['./generated-dep1.js', './generated-dep2.js'], function (export execute: function () { var x = exports('x', x$1 + 1); + console.log('shared1'); var y = exports('y', x$2 + 1); + console.log('shared2'); } }; diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/dep1.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/dep1.js index b18a2c15ab1..f4787466b09 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/dep1.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/dep1.js @@ -1,2 +1,3 @@ var x = 42; -export default x; \ No newline at end of file +export default x; +console.log('dep1'); diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/dep2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/dep2.js index e0f0cf4b168..93594e1b2cd 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/dep2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/dep2.js @@ -1,2 +1,3 @@ var x = 43; -export default x; \ No newline at end of file +export default x; +console.log('dep2'); diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/shared1.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/shared1.js index 079860f6572..9912e71e13c 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/shared1.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/shared1.js @@ -1,3 +1,4 @@ import './dep1.js'; import x from './dep1.js'; -export default x + 1; \ No newline at end of file +export default x + 1; +console.log('shared1'); diff --git a/test/chunking-form/samples/chunk-deshadowing-reassignment/shared2.js b/test/chunking-form/samples/chunk-deshadowing-reassignment/shared2.js index 7fe3fbb773a..c44f54fa2b6 100644 --- a/test/chunking-form/samples/chunk-deshadowing-reassignment/shared2.js +++ b/test/chunking-form/samples/chunk-deshadowing-reassignment/shared2.js @@ -1,3 +1,4 @@ import './dep2.js'; import x from './dep2.js'; -export default x + 1; \ No newline at end of file +export default x + 1; +console.log('shared2'); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/generated-lib.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/generated-lib.js index 2756a0bd25b..ef3191944b8 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/generated-lib.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/generated-lib.js @@ -1,9 +1,9 @@ define(['exports'], function (exports) { 'use strict'; - function emptyFunction () { + function emptyFunction() {} - } + console.log('lib'); - exports.emptyFunction = emptyFunction; + exports.emptyFunction = emptyFunction; }); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/main1.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/main1.js index b0baf5a2dbf..6489c2c14ca 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/main1.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/main1.js @@ -1,10 +1,12 @@ define(['./generated-lib'], function (lib) { 'use strict'; - function fn () { - var emptyFunction = lib.emptyFunction; - console.log(emptyFunction); - } + function fn() { + var emptyFunction = lib.emptyFunction; + console.log(emptyFunction); + } - fn(); + console.log('dep1'); + + fn(); }); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/main2.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/main2.js index 8eaddd1b192..2bc67f0467a 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/main2.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/amd/main2.js @@ -1,5 +1,5 @@ define(['./generated-lib'], function (lib) { 'use strict'; - + console.log('dep2'); }); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/generated-lib.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/generated-lib.js index f65547fdbe5..3707d070091 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/generated-lib.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/generated-lib.js @@ -1,7 +1,7 @@ 'use strict'; -function emptyFunction () { +function emptyFunction() {} -} +console.log('lib'); exports.emptyFunction = emptyFunction; diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/main1.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/main1.js index 7018f1f5678..cb8c77d4e2a 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/main1.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/main1.js @@ -2,9 +2,11 @@ var lib = require('./generated-lib.js'); -function fn () { - var emptyFunction = lib.emptyFunction; - console.log(emptyFunction); +function fn() { + var emptyFunction = lib.emptyFunction; + console.log(emptyFunction); } +console.log('dep1'); + fn(); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/main2.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/main2.js index a4c4529c43f..62250c6f3f2 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/main2.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/cjs/main2.js @@ -2,3 +2,4 @@ require('./generated-lib.js'); +console.log('dep2'); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/generated-lib.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/generated-lib.js index 45f2b1b4f90..e1ee2c27c53 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/generated-lib.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/generated-lib.js @@ -1,5 +1,5 @@ -function emptyFunction () { +function emptyFunction() {} -} +console.log('lib'); export { emptyFunction as e }; diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/main1.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/main1.js index 8d4d0f8f6d5..e63d0d8982c 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/main1.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/main1.js @@ -1,8 +1,10 @@ import { e as emptyFunction } from './generated-lib.js'; -function fn () { - var emptyFunction$1 = emptyFunction; - console.log(emptyFunction$1); +function fn() { + var emptyFunction$1 = emptyFunction; + console.log(emptyFunction$1); } +console.log('dep1'); + fn(); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/main2.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/main2.js index 1de20fb6656..36201d437b1 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/main2.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/es/main2.js @@ -1 +1,3 @@ import './generated-lib.js'; + +console.log('dep2'); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/generated-lib.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/generated-lib.js index 31d3ba3abb4..41c5389c2f2 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/generated-lib.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/generated-lib.js @@ -1,14 +1,14 @@ System.register([], function (exports) { - 'use strict'; - return { - execute: function () { + 'use strict'; + return { + execute: function () { - exports('e', emptyFunction); + exports('e', emptyFunction); - function emptyFunction () { + function emptyFunction() {} - } + console.log('lib'); - } - }; + } + }; }); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/main1.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/main1.js index 8029d14b1ee..bebccb02e6f 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/main1.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/main1.js @@ -1,19 +1,21 @@ System.register(['./generated-lib.js'], function () { - 'use strict'; - var emptyFunction; - return { - setters: [function (module) { - emptyFunction = module.e; - }], - execute: function () { + 'use strict'; + var emptyFunction; + return { + setters: [function (module) { + emptyFunction = module.e; + }], + execute: function () { - function fn () { - var emptyFunction$1 = emptyFunction; - console.log(emptyFunction$1); - } + function fn() { + var emptyFunction$1 = emptyFunction; + console.log(emptyFunction$1); + } - fn(); + console.log('dep1'); - } - }; + fn(); + + } + }; }); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/main2.js b/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/main2.js index eb8c6d4539e..67ec6dee448 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/main2.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/_expected/system/main2.js @@ -1,11 +1,11 @@ System.register(['./generated-lib.js'], function () { - 'use strict'; - return { - setters: [function () {}], - execute: function () { + 'use strict'; + return { + setters: [function () {}], + execute: function () { + console.log('dep2'); - - } - }; + } + }; }); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/dep1.js b/test/chunking-form/samples/chunk-import-deshadowing/dep1.js index 4b1e2bcfe1b..e9fa9a2785e 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/dep1.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/dep1.js @@ -1,6 +1,8 @@ import { emptyFunction as x } from './lib'; -export function fn () { - var emptyFunction = x; - console.log(emptyFunction); +export function fn() { + var emptyFunction = x; + console.log(emptyFunction); } + +console.log('dep1'); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/dep2.js b/test/chunking-form/samples/chunk-import-deshadowing/dep2.js index dc46066466b..2b07bc85b77 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/dep2.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/dep2.js @@ -1,5 +1,7 @@ import { another } from './lib'; -export function fn () { - another(); -} \ No newline at end of file +export function fn() { + another(); +} + +console.log('dep2'); diff --git a/test/chunking-form/samples/chunk-import-deshadowing/lib.js b/test/chunking-form/samples/chunk-import-deshadowing/lib.js index 9d333d2a1da..727754cdc2f 100644 --- a/test/chunking-form/samples/chunk-import-deshadowing/lib.js +++ b/test/chunking-form/samples/chunk-import-deshadowing/lib.js @@ -1,7 +1,5 @@ -export function emptyFunction () { +export function emptyFunction() {} -} +export function another() {} -export function another () { - -} \ No newline at end of file +console.log('lib'); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/generated-separate.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/generated-separate.js index c06b72922c5..39394a740ad 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/generated-separate.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/generated-separate.js @@ -2,6 +2,7 @@ define(['exports'], function (exports) { 'use strict'; var separate = 'separate'; const x = 2; + console.log('separate'); exports.default = separate; exports.x = x; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main1.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main1.js index 744d5b098dc..1e9a9c8c505 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main1.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main1.js @@ -2,6 +2,7 @@ define(['require', 'exports', './generated-separate'], function (require, export var inlined = 'inlined'; const x = 1; + console.log('inlined'); var inlined$1 = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/generated-separate.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/generated-separate.js index 6eb315e5cac..d1aecc86c45 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/generated-separate.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/generated-separate.js @@ -2,6 +2,7 @@ var separate = 'separate'; const x = 2; +console.log('separate'); exports.default = separate; exports.x = x; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main1.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main1.js index dc66435748d..005e3846beb 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main1.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main1.js @@ -6,6 +6,7 @@ require('./generated-separate.js'); var inlined = 'inlined'; const x = 1; +console.log('inlined'); var inlined$1 = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/generated-separate.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/generated-separate.js index e7122e67004..fd70da9ecd3 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/generated-separate.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/generated-separate.js @@ -1,5 +1,6 @@ var separate = 'separate'; const x = 2; +console.log('separate'); export default separate; export { x }; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main1.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main1.js index 36f87038dd8..7775436cdd1 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main1.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main1.js @@ -2,6 +2,7 @@ import './generated-separate.js'; var inlined = 'inlined'; const x = 1; +console.log('inlined'); var inlined$1 = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/generated-separate.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/generated-separate.js index 09405c5602c..97c75dde7ae 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/generated-separate.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/generated-separate.js @@ -5,6 +5,7 @@ System.register([], function (exports) { var separate = exports('default', 'separate'); const x = exports('x', 2); + console.log('separate'); } }; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main1.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main1.js index 6db94a041c5..31ff721b540 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main1.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main1.js @@ -6,6 +6,7 @@ System.register(['./generated-separate.js'], function (exports, module) { var inlined = 'inlined'; const x = 1; + console.log('inlined'); var inlined$1 = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/inlined.js b/test/chunking-form/samples/dynamic-import-inline-colouring/inlined.js index 179d1f36e2d..4e3176b2d7e 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/inlined.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/inlined.js @@ -1,2 +1,3 @@ export default 'inlined'; export const x = 1; +console.log('inlined'); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/separate.js b/test/chunking-form/samples/dynamic-import-inline-colouring/separate.js index 8b13495bb7a..f50a2d629a8 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/separate.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/separate.js @@ -1,2 +1,3 @@ export default 'separate'; export const x = 2; +console.log('separate'); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js index 638c64b4bd7..c1fbad76dd0 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js @@ -1,5 +1,6 @@ define(['./first'], function (first) { 'use strict'; - + console.log(first); + console.log(first); }); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main2.js b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main2.js index 8c7cb55b66b..f7881b5d294 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main2.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main2.js @@ -1,4 +1,6 @@ 'use strict'; -require('./first.js'); +var first = require('./first.js'); +console.log(first); +console.log(first); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/es/main2.js b/test/chunking-form/samples/import-variable-duplicates/_expected/es/main2.js index f9306583cd9..f893e390329 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/es/main2.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/es/main2.js @@ -1 +1,4 @@ -import './first.js'; +import head2 from './first.js'; + +console.log(head2); +console.log(head2); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/system/main2.js b/test/chunking-form/samples/import-variable-duplicates/_expected/system/main2.js index 3a99d9e3667..7fc36d77ff9 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/system/main2.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/system/main2.js @@ -1,10 +1,14 @@ System.register(['./first.js'], function () { 'use strict'; + var head2; return { - setters: [function () {}], + setters: [function (module) { + head2 = module.default; + }], execute: function () { - + console.log(head2); + console.log(head2); } }; diff --git a/test/chunking-form/samples/import-variable-duplicates/main1.js b/test/chunking-form/samples/import-variable-duplicates/main1.js index c0154c96dff..8e56f03bc10 100644 --- a/test/chunking-form/samples/import-variable-duplicates/main1.js +++ b/test/chunking-form/samples/import-variable-duplicates/main1.js @@ -2,4 +2,4 @@ import head1 from './first.js'; import head2 from './head.js'; console.log(head1); -console.log(head2); \ No newline at end of file +console.log(head2); diff --git a/test/chunking-form/samples/import-variable-duplicates/main2.js b/test/chunking-form/samples/import-variable-duplicates/main2.js index d85290aac51..8e56f03bc10 100644 --- a/test/chunking-form/samples/import-variable-duplicates/main2.js +++ b/test/chunking-form/samples/import-variable-duplicates/main2.js @@ -1,2 +1,5 @@ -import './first.js'; -import './head.js'; \ No newline at end of file +import head1 from './first.js'; +import head2 from './head.js'; + +console.log(head1); +console.log(head2); diff --git a/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/amd/main3.js b/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/amd/main3.js index 6401b09a1e2..8e61c58a778 100644 --- a/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/amd/main3.js +++ b/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/amd/main3.js @@ -1,5 +1,5 @@ define(['./generated-dep'], function (dep) { 'use strict'; - + console.log(dep.reexported); }); diff --git a/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/cjs/main3.js b/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/cjs/main3.js index 9fcaf192db3..a177a50614d 100644 --- a/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/cjs/main3.js +++ b/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/cjs/main3.js @@ -1,4 +1,5 @@ 'use strict'; -require('./generated-dep.js'); +var dep = require('./generated-dep.js'); +console.log(dep.reexported); diff --git a/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/es/main3.js b/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/es/main3.js index 81875f89bf4..b0d1ebd35c1 100644 --- a/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/es/main3.js +++ b/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/es/main3.js @@ -1 +1,3 @@ -import './generated-dep.js'; +import { r as reexported } from './generated-dep.js'; + +console.log(reexported); diff --git a/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/system/main3.js b/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/system/main3.js index 0b6277f0f56..5469d008508 100644 --- a/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/system/main3.js +++ b/test/chunking-form/samples/namespace-reexport-name-conflict/_expected/system/main3.js @@ -1,10 +1,13 @@ System.register(['./generated-dep.js'], function () { 'use strict'; + var reexported; return { - setters: [function () {}], + setters: [function (module) { + reexported = module.r; + }], execute: function () { - + console.log(reexported); } }; diff --git a/test/chunking-form/samples/namespace-reexport-name-conflict/index.js b/test/chunking-form/samples/namespace-reexport-name-conflict/index.js index 4506e18fb15..b570508bf1b 100644 --- a/test/chunking-form/samples/namespace-reexport-name-conflict/index.js +++ b/test/chunking-form/samples/namespace-reexport-name-conflict/index.js @@ -1,4 +1,3 @@ export { reexported } from './dep'; import { reexported } from 'external'; - console.log(reexported); diff --git a/test/chunking-form/samples/namespace-reexport-name-conflict/main3.js b/test/chunking-form/samples/namespace-reexport-name-conflict/main3.js index 1f6200b9dd1..0c0c4cf81e5 100644 --- a/test/chunking-form/samples/namespace-reexport-name-conflict/main3.js +++ b/test/chunking-form/samples/namespace-reexport-name-conflict/main3.js @@ -1 +1,2 @@ -import './dep'; +import { reexported } from './dep'; +console.log(reexported); diff --git a/test/chunking-form/samples/namespace-tracing/_expected/amd/generated-bar.js b/test/chunking-form/samples/namespace-tracing/_expected/amd/generated-bar.js index 43cc41e1615..f8f78c489f8 100644 --- a/test/chunking-form/samples/namespace-tracing/_expected/amd/generated-bar.js +++ b/test/chunking-form/samples/namespace-tracing/_expected/amd/generated-bar.js @@ -1,4 +1,4 @@ -define(['exports', './generated-broken'], function (exports, broken) { 'use strict'; +define(['exports'], function (exports) { 'use strict'; function bar() { console.log('bar'); diff --git a/test/chunking-form/samples/namespace-tracing/_expected/amd/generated-foo.js b/test/chunking-form/samples/namespace-tracing/_expected/amd/generated-foo.js index d08ae86cc78..2ba41e836d7 100644 --- a/test/chunking-form/samples/namespace-tracing/_expected/amd/generated-foo.js +++ b/test/chunking-form/samples/namespace-tracing/_expected/amd/generated-foo.js @@ -1,4 +1,4 @@ -define(['exports', './generated-broken'], function (exports, broken) { 'use strict'; +define(['exports'], function (exports) { 'use strict'; function foo() { console.log('foo'); diff --git a/test/chunking-form/samples/namespace-tracing/_expected/cjs/generated-bar.js b/test/chunking-form/samples/namespace-tracing/_expected/cjs/generated-bar.js index c1ada01763e..cb550ba0995 100644 --- a/test/chunking-form/samples/namespace-tracing/_expected/cjs/generated-bar.js +++ b/test/chunking-form/samples/namespace-tracing/_expected/cjs/generated-bar.js @@ -1,7 +1,5 @@ 'use strict'; -require('./generated-broken.js'); - function bar() { console.log('bar'); } diff --git a/test/chunking-form/samples/namespace-tracing/_expected/cjs/generated-foo.js b/test/chunking-form/samples/namespace-tracing/_expected/cjs/generated-foo.js index cf2842741a0..d3b4b5f6eee 100644 --- a/test/chunking-form/samples/namespace-tracing/_expected/cjs/generated-foo.js +++ b/test/chunking-form/samples/namespace-tracing/_expected/cjs/generated-foo.js @@ -1,7 +1,5 @@ 'use strict'; -require('./generated-broken.js'); - function foo() { console.log('foo'); } diff --git a/test/chunking-form/samples/namespace-tracing/_expected/es/generated-bar.js b/test/chunking-form/samples/namespace-tracing/_expected/es/generated-bar.js index f6d2390fb6c..dc980cbba31 100644 --- a/test/chunking-form/samples/namespace-tracing/_expected/es/generated-bar.js +++ b/test/chunking-form/samples/namespace-tracing/_expected/es/generated-bar.js @@ -1,5 +1,3 @@ -import './generated-broken.js'; - function bar() { console.log('bar'); } diff --git a/test/chunking-form/samples/namespace-tracing/_expected/es/generated-foo.js b/test/chunking-form/samples/namespace-tracing/_expected/es/generated-foo.js index 9792caf6b29..9eee01fe67a 100644 --- a/test/chunking-form/samples/namespace-tracing/_expected/es/generated-foo.js +++ b/test/chunking-form/samples/namespace-tracing/_expected/es/generated-foo.js @@ -1,5 +1,3 @@ -import './generated-broken.js'; - function foo() { console.log('foo'); } diff --git a/test/chunking-form/samples/namespace-tracing/_expected/system/generated-bar.js b/test/chunking-form/samples/namespace-tracing/_expected/system/generated-bar.js index ffd4c4e677a..699cd2779fb 100644 --- a/test/chunking-form/samples/namespace-tracing/_expected/system/generated-bar.js +++ b/test/chunking-form/samples/namespace-tracing/_expected/system/generated-bar.js @@ -1,7 +1,6 @@ -System.register(['./generated-broken.js'], function (exports) { +System.register([], function (exports) { 'use strict'; return { - setters: [function () {}], execute: function () { exports('b', bar); diff --git a/test/chunking-form/samples/namespace-tracing/_expected/system/generated-foo.js b/test/chunking-form/samples/namespace-tracing/_expected/system/generated-foo.js index 4a975af238b..6081a999a89 100644 --- a/test/chunking-form/samples/namespace-tracing/_expected/system/generated-foo.js +++ b/test/chunking-form/samples/namespace-tracing/_expected/system/generated-foo.js @@ -1,7 +1,6 @@ -System.register(['./generated-broken.js'], function (exports) { +System.register([], function (exports) { 'use strict'; return { - setters: [function () {}], execute: function () { exports('f', foo); diff --git a/test/chunking-form/samples/preserve-modules-commonjs/_expected/amd/commonjs.js b/test/chunking-form/samples/preserve-modules-commonjs/_expected/amd/commonjs.js index 6f1ab74a4e9..b561ce3eefc 100644 --- a/test/chunking-form/samples/preserve-modules-commonjs/_expected/amd/commonjs.js +++ b/test/chunking-form/samples/preserve-modules-commonjs/_expected/amd/commonjs.js @@ -1,8 +1,8 @@ -define(['exports', 'external', './other', './_virtual/_external_commonjs-external', './_virtual/other.js_commonjs-proxy'], function (exports, external, other, _external_commonjsExternal, other$1) { 'use strict'; +define(['exports', 'external', './_virtual/_external_commonjs-external', './_virtual/other.js_commonjs-proxy'], function (exports, external, _external_commonjsExternal, other) { 'use strict'; external = external && external.hasOwnProperty('default') ? external['default'] : external; - const { value } = other$1; + const { value } = other; console.log(_external_commonjsExternal, value); diff --git a/test/chunking-form/samples/preserve-modules-commonjs/_expected/cjs/commonjs.js b/test/chunking-form/samples/preserve-modules-commonjs/_expected/cjs/commonjs.js index d6feb15e433..7e3d761845a 100644 --- a/test/chunking-form/samples/preserve-modules-commonjs/_expected/cjs/commonjs.js +++ b/test/chunking-form/samples/preserve-modules-commonjs/_expected/cjs/commonjs.js @@ -3,11 +3,10 @@ Object.defineProperty(exports, '__esModule', { value: true }); require('external'); -require('./other.js'); var _external_commonjsExternal = require('./_virtual/_external_commonjs-external'); -var other$1 = require('./_virtual/other.js_commonjs-proxy'); +var other = require('./_virtual/other.js_commonjs-proxy'); -const { value } = other$1; +const { value } = other; console.log(_external_commonjsExternal, value); diff --git a/test/chunking-form/samples/preserve-modules-commonjs/_expected/es/commonjs.js b/test/chunking-form/samples/preserve-modules-commonjs/_expected/es/commonjs.js index d8c5c6995ab..b78f6b0097e 100644 --- a/test/chunking-form/samples/preserve-modules-commonjs/_expected/es/commonjs.js +++ b/test/chunking-form/samples/preserve-modules-commonjs/_expected/es/commonjs.js @@ -1,5 +1,4 @@ import 'external'; -import './other.js'; import external from './_virtual/_external_commonjs-external'; import require$$0 from './_virtual/other.js_commonjs-proxy'; diff --git a/test/chunking-form/samples/preserve-modules-commonjs/_expected/system/commonjs.js b/test/chunking-form/samples/preserve-modules-commonjs/_expected/system/commonjs.js index ccacb7d04ed..736eac98ee4 100644 --- a/test/chunking-form/samples/preserve-modules-commonjs/_expected/system/commonjs.js +++ b/test/chunking-form/samples/preserve-modules-commonjs/_expected/system/commonjs.js @@ -1,8 +1,8 @@ -System.register(['external', './other.js', './_virtual/_external_commonjs-external', './_virtual/other.js_commonjs-proxy'], function (exports) { +System.register(['external', './_virtual/_external_commonjs-external', './_virtual/other.js_commonjs-proxy'], function (exports) { 'use strict'; var external, require$$0; return { - setters: [function () {}, function () {}, function (module) { + setters: [function () {}, function (module) { external = module.default; }, function (module) { require$$0 = module.default; diff --git a/test/chunking-form/samples/reexport-shortpaths/_expected/amd/generated-dep2.js b/test/chunking-form/samples/reexport-shortpaths/_expected/amd/generated-dep2.js index ed7f5003965..a6664f9addc 100644 --- a/test/chunking-form/samples/reexport-shortpaths/_expected/amd/generated-dep2.js +++ b/test/chunking-form/samples/reexport-shortpaths/_expected/amd/generated-dep2.js @@ -1,6 +1,7 @@ define(['exports'], function (exports) { 'use strict'; function foo() {} + console.log('dep2'); exports.foo = foo; diff --git a/test/chunking-form/samples/reexport-shortpaths/_expected/cjs/generated-dep2.js b/test/chunking-form/samples/reexport-shortpaths/_expected/cjs/generated-dep2.js index 124edf63f6c..e71bc446c48 100644 --- a/test/chunking-form/samples/reexport-shortpaths/_expected/cjs/generated-dep2.js +++ b/test/chunking-form/samples/reexport-shortpaths/_expected/cjs/generated-dep2.js @@ -1,5 +1,6 @@ 'use strict'; function foo() {} +console.log('dep2'); exports.foo = foo; diff --git a/test/chunking-form/samples/reexport-shortpaths/_expected/es/generated-dep2.js b/test/chunking-form/samples/reexport-shortpaths/_expected/es/generated-dep2.js index 4533b2da3fe..5c686abbfa1 100644 --- a/test/chunking-form/samples/reexport-shortpaths/_expected/es/generated-dep2.js +++ b/test/chunking-form/samples/reexport-shortpaths/_expected/es/generated-dep2.js @@ -1,3 +1,4 @@ function foo() {} +console.log('dep2'); export { foo as f }; diff --git a/test/chunking-form/samples/reexport-shortpaths/_expected/system/generated-dep2.js b/test/chunking-form/samples/reexport-shortpaths/_expected/system/generated-dep2.js index 99ff9baa37a..b8c52e10393 100644 --- a/test/chunking-form/samples/reexport-shortpaths/_expected/system/generated-dep2.js +++ b/test/chunking-form/samples/reexport-shortpaths/_expected/system/generated-dep2.js @@ -6,6 +6,7 @@ System.register([], function (exports) { exports('f', foo); function foo() {} + console.log('dep2'); } }; diff --git a/test/chunking-form/samples/reexport-shortpaths/dep2.js b/test/chunking-form/samples/reexport-shortpaths/dep2.js index a5e4ff3389d..98d84515f5a 100644 --- a/test/chunking-form/samples/reexport-shortpaths/dep2.js +++ b/test/chunking-form/samples/reexport-shortpaths/dep2.js @@ -1 +1,2 @@ -export default function() {}; \ No newline at end of file +export default function() {} +console.log('dep2'); diff --git a/test/chunking-form/samples/reexport-shortpaths/main1.js b/test/chunking-form/samples/reexport-shortpaths/main1.js index 24640f29f7f..fe6ead8f25c 100644 --- a/test/chunking-form/samples/reexport-shortpaths/main1.js +++ b/test/chunking-form/samples/reexport-shortpaths/main1.js @@ -1,3 +1,2 @@ import foo from './dep1'; - -export default foo; \ No newline at end of file +export default foo; diff --git a/test/chunking-form/samples/reexport-shortpaths/main2.js b/test/chunking-form/samples/reexport-shortpaths/main2.js index ec8ef6016c0..122182eaf60 100644 --- a/test/chunking-form/samples/reexport-shortpaths/main2.js +++ b/test/chunking-form/samples/reexport-shortpaths/main2.js @@ -1 +1 @@ -import './dep1.js'; \ No newline at end of file +import './dep1.js'; diff --git a/test/chunking-form/samples/reexport-shortpaths/main3.js b/test/chunking-form/samples/reexport-shortpaths/main3.js index f752f4ebdc9..a763119892e 100644 --- a/test/chunking-form/samples/reexport-shortpaths/main3.js +++ b/test/chunking-form/samples/reexport-shortpaths/main3.js @@ -1 +1 @@ -import './dep2.js'; \ No newline at end of file +import './dep2.js'; diff --git a/test/chunking-form/samples/resolve-dynamic-import/_expected/amd/main.js b/test/chunking-form/samples/resolve-dynamic-import/_expected/amd/main.js index 354d7117d0f..1f28a5ebb9c 100644 --- a/test/chunking-form/samples/resolve-dynamic-import/_expected/amd/main.js +++ b/test/chunking-form/samples/resolve-dynamic-import/_expected/amd/main.js @@ -27,6 +27,7 @@ define(['require', './direct-relative-external', 'to-indirect-relative-external' new Promise(function (resolve, reject) { require(['to-indirect-absolute-external'], function (m) { resolve(_interopNamespace(m)); }, reject) }); const value = 'existing'; + console.log('existing'); var existing = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/test/chunking-form/samples/resolve-dynamic-import/_expected/cjs/main.js b/test/chunking-form/samples/resolve-dynamic-import/_expected/cjs/main.js index fae2ceae79a..4a96042e9d3 100644 --- a/test/chunking-form/samples/resolve-dynamic-import/_expected/cjs/main.js +++ b/test/chunking-form/samples/resolve-dynamic-import/_expected/cjs/main.js @@ -32,6 +32,7 @@ new Promise(function (resolve) { resolve(_interopNamespace(require('direct-absol new Promise(function (resolve) { resolve(_interopNamespace(require('to-indirect-absolute-external'))); }); const value = 'existing'; +console.log('existing'); var existing = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/test/chunking-form/samples/resolve-dynamic-import/_expected/es/main.js b/test/chunking-form/samples/resolve-dynamic-import/_expected/es/main.js index 691f388d15d..fb6bacbadd2 100644 --- a/test/chunking-form/samples/resolve-dynamic-import/_expected/es/main.js +++ b/test/chunking-form/samples/resolve-dynamic-import/_expected/es/main.js @@ -11,6 +11,7 @@ import('direct-absolute-external'); import('to-indirect-absolute-external'); const value = 'existing'; +console.log('existing'); var existing = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/test/chunking-form/samples/resolve-dynamic-import/_expected/system/main.js b/test/chunking-form/samples/resolve-dynamic-import/_expected/system/main.js index 7d417f56ec1..d1c80b61a3c 100644 --- a/test/chunking-form/samples/resolve-dynamic-import/_expected/system/main.js +++ b/test/chunking-form/samples/resolve-dynamic-import/_expected/system/main.js @@ -12,6 +12,7 @@ System.register(['./direct-relative-external', 'to-indirect-relative-external', module.import('to-indirect-absolute-external'); const value = 'existing'; + console.log('existing'); var existing = /*#__PURE__*/Object.freeze({ __proto__: null, diff --git a/test/chunking-form/samples/resolve-dynamic-import/existing.js b/test/chunking-form/samples/resolve-dynamic-import/existing.js index 29aa16bd444..f258c0462d0 100644 --- a/test/chunking-form/samples/resolve-dynamic-import/existing.js +++ b/test/chunking-form/samples/resolve-dynamic-import/existing.js @@ -1 +1,2 @@ export const value = 'existing'; +console.log('existing'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_config.js new file mode 100644 index 00000000000..78767a46819 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: 'avoids empty imports if they do not have side-effects', + options: { + input: ['main1', 'main2'], + external: ['external-side-effect'] + } +}; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/amd/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/amd/main1.js new file mode 100644 index 00000000000..8acd4520991 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/amd/main1.js @@ -0,0 +1,9 @@ +define(['external-side-effect'], function (externalSideEffect) { 'use strict'; + + function onlyUsedByOne() { + console.log('Hello'); + } + + onlyUsedByOne(); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/amd/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/amd/main2.js new file mode 100644 index 00000000000..52c48560358 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/amd/main2.js @@ -0,0 +1,5 @@ +define(['external-side-effect'], function (externalSideEffect) { 'use strict'; + + console.log('main2'); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/cjs/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/cjs/main1.js new file mode 100644 index 00000000000..5fa6a606ea6 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/cjs/main1.js @@ -0,0 +1,9 @@ +'use strict'; + +require('external-side-effect'); + +function onlyUsedByOne() { + console.log('Hello'); +} + +onlyUsedByOne(); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/cjs/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/cjs/main2.js new file mode 100644 index 00000000000..6870306ded8 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/cjs/main2.js @@ -0,0 +1,5 @@ +'use strict'; + +require('external-side-effect'); + +console.log('main2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/es/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/es/main1.js new file mode 100644 index 00000000000..1e5e5a759b2 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/es/main1.js @@ -0,0 +1,7 @@ +import 'external-side-effect'; + +function onlyUsedByOne() { + console.log('Hello'); +} + +onlyUsedByOne(); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/es/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/es/main2.js new file mode 100644 index 00000000000..7d885833b90 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/es/main2.js @@ -0,0 +1,3 @@ +import 'external-side-effect'; + +console.log('main2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/system/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/system/main1.js new file mode 100644 index 00000000000..184dec65313 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/system/main1.js @@ -0,0 +1,15 @@ +System.register(['external-side-effect'], function () { + 'use strict'; + return { + setters: [function () {}], + execute: function () { + + function onlyUsedByOne() { + console.log('Hello'); + } + + onlyUsedByOne(); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/system/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/system/main2.js new file mode 100644 index 00000000000..978a1d82672 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/_expected/system/main2.js @@ -0,0 +1,11 @@ +System.register(['external-side-effect'], function () { + 'use strict'; + return { + setters: [function () {}], + execute: function () { + + console.log('main2'); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/dep1.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/dep1.js new file mode 100644 index 00000000000..872cc66ce4c --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/dep1.js @@ -0,0 +1,5 @@ +import 'external-side-effect'; + +export default function onlyUsedByOne() { + console.log('Hello'); +} diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/main1.js new file mode 100644 index 00000000000..80842ff8290 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/main1.js @@ -0,0 +1,2 @@ +import dep from './dep1.js'; +dep(); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/main2.js new file mode 100644 index 00000000000..2ff59991d0b --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/avoid-side-effect-free-empty-imports/main2.js @@ -0,0 +1,2 @@ +import dep from './dep1.js'; +console.log('main2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_config.js new file mode 100644 index 00000000000..22e3b16521d --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_config.js @@ -0,0 +1,8 @@ +module.exports = { + solo: true, + description: 'hoist side-effect imports when avoiding empty imports', + options: { + input: ['main1', 'main2', 'main3'] + }, + expectedWarnings: ['CIRCULAR_DEPENDENCY'] +}; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/generated-dep2-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/generated-dep2-effect.js new file mode 100644 index 00000000000..af27f254599 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/generated-dep2-effect.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + console.log('dep2'); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/generated-dep4-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/generated-dep4-effect.js new file mode 100644 index 00000000000..8848968aaf5 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/generated-dep4-effect.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + console.log('dep4'); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main1.js new file mode 100644 index 00000000000..a878d2dfa06 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main1.js @@ -0,0 +1,11 @@ +define(['./generated-dep2-effect', './generated-dep4-effect'], function (dep2Effect, dep4Effect) { 'use strict'; + + var value = 42; + + function onlyUsedByOne(value) { + console.log('Hello', value); + } + + onlyUsedByOne(value); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main2.js new file mode 100644 index 00000000000..63cd356d00e --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main2.js @@ -0,0 +1,5 @@ +define(['./generated-dep2-effect', './generated-dep4-effect'], function (dep2Effect, dep4Effect) { 'use strict'; + + console.log('main2'); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main3.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main3.js new file mode 100644 index 00000000000..daf45b47633 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/amd/main3.js @@ -0,0 +1,5 @@ +define(['./generated-dep4-effect'], function (dep4Effect) { 'use strict'; + + console.log('main3'); + +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/generated-dep2-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/generated-dep2-effect.js new file mode 100644 index 00000000000..132fb447b0c --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/generated-dep2-effect.js @@ -0,0 +1,3 @@ +'use strict'; + +console.log('dep2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/generated-dep4-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/generated-dep4-effect.js new file mode 100644 index 00000000000..aa13e718bcb --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/generated-dep4-effect.js @@ -0,0 +1,3 @@ +'use strict'; + +console.log('dep4'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main1.js new file mode 100644 index 00000000000..2c4ce3ce415 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main1.js @@ -0,0 +1,12 @@ +'use strict'; + +require('./generated-dep2-effect.js'); +require('./generated-dep4-effect.js'); + +var value = 42; + +function onlyUsedByOne(value) { + console.log('Hello', value); +} + +onlyUsedByOne(value); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main2.js new file mode 100644 index 00000000000..5be153707f0 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main2.js @@ -0,0 +1,6 @@ +'use strict'; + +require('./generated-dep2-effect.js'); +require('./generated-dep4-effect.js'); + +console.log('main2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main3.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main3.js new file mode 100644 index 00000000000..3ecab4dc21d --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/cjs/main3.js @@ -0,0 +1,5 @@ +'use strict'; + +require('./generated-dep4-effect.js'); + +console.log('main3'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/generated-dep2-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/generated-dep2-effect.js new file mode 100644 index 00000000000..f5325d80e8a --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/generated-dep2-effect.js @@ -0,0 +1 @@ +console.log('dep2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/generated-dep4-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/generated-dep4-effect.js new file mode 100644 index 00000000000..d77202c1ef6 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/generated-dep4-effect.js @@ -0,0 +1 @@ +console.log('dep4'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main1.js new file mode 100644 index 00000000000..55d4df10f01 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main1.js @@ -0,0 +1,10 @@ +import './generated-dep2-effect.js'; +import './generated-dep4-effect.js'; + +var value = 42; + +function onlyUsedByOne(value) { + console.log('Hello', value); +} + +onlyUsedByOne(value); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main2.js new file mode 100644 index 00000000000..95610e4dd52 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main2.js @@ -0,0 +1,4 @@ +import './generated-dep2-effect.js'; +import './generated-dep4-effect.js'; + +console.log('main2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main3.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main3.js new file mode 100644 index 00000000000..dbeb90934cf --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/es/main3.js @@ -0,0 +1,3 @@ +import './generated-dep4-effect.js'; + +console.log('main3'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/generated-dep2-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/generated-dep2-effect.js new file mode 100644 index 00000000000..535b40f550f --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/generated-dep2-effect.js @@ -0,0 +1,10 @@ +System.register([], function () { + 'use strict'; + return { + execute: function () { + + console.log('dep2'); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/generated-dep4-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/generated-dep4-effect.js new file mode 100644 index 00000000000..b85397ce320 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/generated-dep4-effect.js @@ -0,0 +1,10 @@ +System.register([], function () { + 'use strict'; + return { + execute: function () { + + console.log('dep4'); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main1.js new file mode 100644 index 00000000000..9ba48709b62 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main1.js @@ -0,0 +1,17 @@ +System.register(['./generated-dep2-effect.js', './generated-dep4-effect.js'], function () { + 'use strict'; + return { + setters: [function () {}, function () {}], + execute: function () { + + var value = 42; + + function onlyUsedByOne(value) { + console.log('Hello', value); + } + + onlyUsedByOne(value); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main2.js new file mode 100644 index 00000000000..d285b264147 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main2.js @@ -0,0 +1,11 @@ +System.register(['./generated-dep2-effect.js', './generated-dep4-effect.js'], function () { + 'use strict'; + return { + setters: [function () {}, function () {}], + execute: function () { + + console.log('main2'); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main3.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main3.js new file mode 100644 index 00000000000..260b1872457 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_expected/system/main3.js @@ -0,0 +1,11 @@ +System.register(['./generated-dep4-effect.js'], function () { + 'use strict'; + return { + setters: [function () {}], + execute: function () { + + console.log('main3'); + + } + }; +}); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep1.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep1.js new file mode 100644 index 00000000000..78782cba6c6 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep1.js @@ -0,0 +1,6 @@ +import './dep2-effect.js'; +import './dep3.js' + +export default function onlyUsedByOne(value) { + console.log('Hello', value); +} diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep2-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep2-effect.js new file mode 100644 index 00000000000..f5325d80e8a --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep2-effect.js @@ -0,0 +1 @@ +console.log('dep2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep3.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep3.js new file mode 100644 index 00000000000..da1e13f92a9 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep3.js @@ -0,0 +1,3 @@ +import './dep1'; +import './dep4-effect.js'; +export default 42; diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep4-effect.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep4-effect.js new file mode 100644 index 00000000000..d77202c1ef6 --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/dep4-effect.js @@ -0,0 +1 @@ +console.log('dep4'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main1.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main1.js new file mode 100644 index 00000000000..f972de992bd --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main1.js @@ -0,0 +1,3 @@ +import dep from './dep1.js'; +import value from './dep3.js'; +dep(value); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main2.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main2.js new file mode 100644 index 00000000000..6819e0fe2ae --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main2.js @@ -0,0 +1,2 @@ +import './dep1.js'; +console.log('main2'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main3.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main3.js new file mode 100644 index 00000000000..41df9126f5a --- /dev/null +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/main3.js @@ -0,0 +1,2 @@ +import './dep4-effect.js'; +console.log('main3'); diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js index ba74be8e44a..c232745e1f7 100644 --- a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js @@ -1,3 +1,4 @@ +// TODO Lukas it may well be that avoidChunkImportHoisting could work differently module.exports = { description: 'handles re-exports in entry points if moduleSideEffects are false', options: { diff --git a/test/hooks/index.js b/test/hooks/index.js index 873a9a1906c..9ecc0fb8a93 100644 --- a/test/hooks/index.js +++ b/test/hooks/index.js @@ -985,9 +985,9 @@ describe('hooks', () => { plugins: [ loader({ input: `export default [import('a'), import('b')];`, - a: `import d from 'd'; import c from 'c'; export default () => c();`, - b: `import c from 'c'; export default () => c();`, - c: `export default () => console.log('c');`, + a: `import d from 'd'; import c from 'c'; export default () => c(d);`, + b: `import c from 'c'; export default () => c(0);`, + c: `export default (x) => console.log('c', x);`, d: `export default {};` }), { diff --git a/test/misc/bundle-information.js b/test/misc/bundle-information.js index 38519d3c019..3bf50a9ebc9 100644 --- a/test/misc/bundle-information.js +++ b/test/misc/bundle-information.js @@ -114,7 +114,7 @@ describe('The bundle object', () => { loader({ input1: 'import {shared} from "shared";import {input2} from "input2";console.log(input2, shared);', - input2: 'import {shared} from "shared";export const input2 = "input2";', + input2: 'import {shared} from "shared";export const input2 = shared + "input2";', shared: 'export const shared = "shared"' }) ] @@ -158,7 +158,7 @@ describe('The bundle object', () => { loader({ input1: 'import {shared} from "shared";import {input2} from "input2";console.log(input2, shared);', - input2: 'import {shared} from "shared";export const input2 = "input2";', + input2: 'import {shared} from "shared";export const input2 = shared + "input2";', shared: 'export const shared = "shared"' }) ] From 6913fe85d8169ede59d4c60788aad72fc93e4f8f Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Tue, 4 Feb 2020 06:28:03 +0100 Subject: [PATCH 5/9] Simplify some logic --- src/Chunk.ts | 9 +-- src/Graph.ts | 17 +++-- src/Module.ts | 8 +-- src/utils/chunkColouring.ts | 22 +++--- src/utils/executionOrder.ts | 68 +++++++++---------- .../hoist-side-effect-modules/_config.js | 1 - .../_config.js | 1 - 7 files changed, 55 insertions(+), 71 deletions(-) diff --git a/src/Chunk.ts b/src/Chunk.ts index e2524e069b5..dabf2ca17cf 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -561,13 +561,6 @@ export default class Chunk { if (dep instanceof Chunk) this.inlineChunkDependencies(dep, true); } } - // prune empty dependency chunks, inlining their side-effect dependencies - for (const dependency of this.dependencies) { - if (dependency instanceof Chunk && dependency.isEmpty) { - this.dependencies.delete(dependency); - this.inlineChunkDependencies(dependency, false); - } - } // TODO Lukas filtering and sorting dependencies, could this be done earlier? const sortedDependencies = Array.from(this.dependencies); sortByExecutionOrder(sortedDependencies); @@ -1075,7 +1068,7 @@ export default class Chunk { this.dependencies.add(dep); } else { if (dep === this) continue; - if (!dep.isEmpty) this.dependencies.add(dep); + this.dependencies.add(dep); if (deep) this.inlineChunkDependencies(dep, true); } } diff --git a/src/Graph.ts b/src/Graph.ts index 23589c518d7..e3da9ec9a25 100644 --- a/src/Graph.ts +++ b/src/Graph.ts @@ -242,24 +242,24 @@ export default class Graph { // entry point graph colouring, before generating the import and export facades timeStart('generate chunks', 2); - if (!this.preserveModules && !inlineDynamicImports) { - assignChunkColouringHashes(entryModules, manualChunkModulesByAlias); - } - // TODO: there is one special edge case unhandled here and that is that any module // exposed as an unresolvable export * (to a graph external export *, // either as a namespace import reexported or top-level export *) // should be made to be its own entry point module before chunking - let chunks: Chunk[] = []; + const chunks: Chunk[] = []; if (this.preserveModules) { for (const module of this.modules) { const chunk = new Chunk(this, [module]); - if (module.isEntryPoint || !chunk.isEmpty) { + if (isChunkRendered(chunk)) { chunk.entryModules = [module]; + chunks.push(chunk); } - chunks.push(chunk); } } else { + // TODO Lukas we want to get rid of hashes + if (!inlineDynamicImports) { + assignChunkColouringHashes(entryModules, manualChunkModulesByAlias); + } const chunkModules: { [entryHashSum: string]: Module[] } = {}; for (const module of this.modules) { const entryPointsHashStr = Uint8ArrayToHexString(module.entryPointsHash); @@ -275,14 +275,13 @@ export default class Graph { const chunkModulesOrdered = chunkModules[entryHashSum]; sortByExecutionOrder(chunkModulesOrdered); const chunk = new Chunk(this, chunkModulesOrdered); - chunks.push(chunk); + if (isChunkRendered(chunk)) chunks.push(chunk); } } for (const chunk of chunks) { chunk.link(); } - chunks = chunks.filter(isChunkRendered); const facades: Chunk[] = []; for (const chunk of chunks) { facades.push(...chunk.generateFacades()); diff --git a/src/Module.ts b/src/Module.ts index 7a2cad0d918..9cdda32896c 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -347,6 +347,7 @@ export default class Module { } getDependenciesToBeIncluded(): Set { + timeStart('getDependenciesToBeIncluded', 3); if (this.relevantDependencies) return this.relevantDependencies; const relevantDependencies = new Set(); for (const variable of this.imports) { @@ -378,12 +379,7 @@ export default class Module { relevantDependencies.add(dependency); } } - // TODO Lukas remove - // console.log( - // 'relevantDependencies', - // this.id.split('/').slice(-1)[0], - // Array.from(relevantDependencies).map(module => module.id.split('/').slice(-1)[0]) - // ); + timeEnd('getDependenciesToBeIncluded', 3); return (this.relevantDependencies = relevantDependencies); } diff --git a/src/utils/chunkColouring.ts b/src/utils/chunkColouring.ts index 1c35b4afa31..283b1ddf89e 100644 --- a/src/utils/chunkColouring.ts +++ b/src/utils/chunkColouring.ts @@ -8,12 +8,10 @@ export function assignChunkColouringHashes( entryModules: Module[], manualChunkModules: Record ) { - const { dependentEntryPointsByModule, dynamicImportersByModule } = analyzeModuleGraph( - entryModules - ); + const { dependentEntryPointsByModule, dynamicEntryModules } = analyzeModuleGraph(entryModules); const dynamicDependentEntryPointsByDynamicEntry: DependentModuleMap = getDynamicDependentEntryPoints( dependentEntryPointsByModule, - dynamicImportersByModule + dynamicEntryModules ); const staticEntries = new Set(entryModules); @@ -81,7 +79,7 @@ export function assignChunkColouringHashes( } } - for (const entry of dynamicImportersByModule.keys()) { + for (const entry of dynamicEntryModules) { if (!entry.manualChunkAlias) { const entryHash = randomUint8Array(10); addColourToModuleDependencies( @@ -97,9 +95,9 @@ function analyzeModuleGraph( entryModules: Module[] ): { dependentEntryPointsByModule: DependentModuleMap; - dynamicImportersByModule: DependentModuleMap; + dynamicEntryModules: Set; } { - const dynamicImportersByModule: DependentModuleMap = new Map(); + const dynamicEntryModules = new Set(); const dependentEntryPointsByModule: DependentModuleMap = new Map(); const entriesToHandle = new Set(entryModules); for (const currentEntry of entriesToHandle) { @@ -117,13 +115,13 @@ function analyzeModuleGraph( resolution.dynamicallyImportedBy.length > 0 && !resolution.manualChunkAlias ) { - getDependentModules(dynamicImportersByModule, resolution).add(module); + dynamicEntryModules.add(resolution); entriesToHandle.add(resolution); } } } } - return { dependentEntryPointsByModule, dynamicImportersByModule }; + return { dependentEntryPointsByModule, dynamicEntryModules }; } function getDependentModules(moduleMap: DependentModuleMap, module: Module): Set { @@ -134,15 +132,15 @@ function getDependentModules(moduleMap: DependentModuleMap, module: Module): Set function getDynamicDependentEntryPoints( dependentEntryPointsByModule: DependentModuleMap, - dynamicImportersByModule: DependentModuleMap + dynamicEntryModules: Set ): DependentModuleMap { const dynamicDependentEntryPointsByDynamicEntry: DependentModuleMap = new Map(); - for (const [dynamicEntry, importers] of dynamicImportersByModule.entries()) { + for (const dynamicEntry of dynamicEntryModules) { const dynamicDependentEntryPoints = getDependentModules( dynamicDependentEntryPointsByDynamicEntry, dynamicEntry ); - for (const importer of importers) { + for (const importer of dynamicEntry.dynamicallyImportedBy) { for (const entryPoint of dependentEntryPointsByModule.get(importer)!) { dynamicDependentEntryPoints.add(entryPoint); } diff --git a/src/utils/executionOrder.ts b/src/utils/executionOrder.ts index e5b1f75c288..4f8997174f1 100644 --- a/src/utils/executionOrder.ts +++ b/src/utils/executionOrder.ts @@ -16,51 +16,47 @@ export function sortByExecutionOrder(units: OrderedExecutionUnit[]) { export function analyseModuleExecution(entryModules: Module[]) { let nextExecIndex = 0; const cyclePaths: string[][] = []; - const analysedModules: { [id: string]: boolean } = {}; + const analysedModules = new Set(); + const dynamicImports = new Set(); + const parents = new Map(); const orderedModules: Module[] = []; - const dynamicImports: Module[] = []; - const parents: { [id: string]: string | null } = {}; const analyseModule = (module: Module | ExternalModule) => { - if (analysedModules[module.id]) return; + if (analysedModules.has(module)) return; - if (module instanceof ExternalModule) { - module.execIndex = nextExecIndex++; - analysedModules[module.id] = true; - return; - } - - for (const dependency of module.dependencies) { - if (dependency.id in parents) { - if (!analysedModules[dependency.id]) { - cyclePaths.push(getCyclePath(dependency.id, module.id, parents)); + if (module instanceof Module) { + for (const dependency of module.dependencies) { + if (parents.has(dependency)) { + if (!analysedModules.has(dependency)) { + cyclePaths.push(getCyclePath(dependency, module, parents)); + } + continue; } - continue; + parents.set(dependency, module); + analyseModule(dependency); } - parents[dependency.id] = module.id; - analyseModule(dependency); - } - for (const { resolution } of module.dynamicImports) { - if (resolution instanceof Module && dynamicImports.indexOf(resolution) === -1) { - dynamicImports.push(resolution); + for (const { resolution } of module.dynamicImports) { + if (resolution instanceof Module && !dynamicImports.has(resolution)) { + dynamicImports.add(resolution); + } } + orderedModules.push(module); } module.execIndex = nextExecIndex++; - analysedModules[module.id] = true; - orderedModules.push(module); + analysedModules.add(module); }; for (const curEntry of entryModules) { - if (!parents[curEntry.id]) { - parents[curEntry.id] = null; + if (!parents.has(curEntry)) { + parents.set(curEntry, null); analyseModule(curEntry); } } for (const curEntry of dynamicImports) { - if (!parents[curEntry.id]) { - parents[curEntry.id] = null; + if (!parents.has(curEntry)) { + parents.set(curEntry, null); analyseModule(curEntry); } } @@ -68,13 +64,17 @@ export function analyseModuleExecution(entryModules: Module[]) { return { orderedModules, cyclePaths }; } -function getCyclePath(id: string, parentId: string, parents: { [id: string]: string | null }) { - const path = [relativeId(id)]; - let curId = parentId; - while (curId !== id) { - path.push(relativeId(curId)); - curId = parents[curId]!; - if (!curId) break; +function getCyclePath( + module: Module | ExternalModule, + parent: Module, + parents: Map +) { + const path = [relativeId(module.id)]; + let nextModule = parent; + 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/hoist-side-effect-modules/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_config.js index 22e3b16521d..0e131b8996e 100644 --- a/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_config.js +++ b/test/chunking-form/samples/side-effect-free-dependencies/hoist-side-effect-modules/_config.js @@ -1,5 +1,4 @@ module.exports = { - solo: true, description: 'hoist side-effect imports when avoiding empty imports', options: { input: ['main1', 'main2', 'main3'] diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js index c232745e1f7..ba74be8e44a 100644 --- a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-reexports-3/_config.js @@ -1,4 +1,3 @@ -// TODO Lukas it may well be that avoidChunkImportHoisting could work differently module.exports = { description: 'handles re-exports in entry points if moduleSideEffects are false', options: { From 7c8285885b9e854529a012a41b9146e8c7fb6f9a Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Tue, 4 Feb 2020 14:56:27 +0100 Subject: [PATCH 6/9] Better encapsulate chunk assignment --- src/Chunk.ts | 34 +++++------------ src/Graph.ts | 38 +++++++------------ src/Module.ts | 3 -- .../{chunkColouring.ts => chunkAssignment.ts} | 20 ++++++++-- src/utils/entryHashing.ts | 1 + .../_expected/es/generated-m1.js | 4 +- .../_expected/es/main.js | 2 +- .../_expected/system/generated-m1.js | 4 +- .../_expected/system/main.js | 2 +- .../namespace-reexports/_expected/cjs/main.js | 4 +- .../amd/{4ef5e079.js => 19d89d54.js} | 0 .../cjs/{be351642.js => 797a17bf.js} | 0 .../_expected/es/{4cadb2a6.js => 114f0e8d.js} | 0 .../system/{b0f0487c.js => 52b8365a.js} | 0 14 files changed, 48 insertions(+), 64 deletions(-) rename src/utils/{chunkColouring.ts => chunkAssignment.ts} (87%) rename test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/amd/{4ef5e079.js => 19d89d54.js} (100%) rename test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/cjs/{be351642.js => 797a17bf.js} (100%) rename test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/es/{4cadb2a6.js => 114f0e8d.js} (100%) rename test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/system/{b0f0487c.js => 52b8365a.js} (100%) diff --git a/src/Chunk.ts b/src/Chunk.ts index dabf2ca17cf..3f8ad9bd033 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -115,10 +115,6 @@ function getGlobalName( } } -export function isChunkRendered(chunk: Chunk): boolean { - return !chunk.isEmpty || chunk.entryModules.length > 0 || chunk.manualChunkAlias !== null; -} - export default class Chunk { private static generateFacade( graph: Graph, @@ -147,7 +143,6 @@ export default class Chunk { graph: Graph; id: string | null = null; indentString: string = undefined as any; - isEmpty: boolean; manualChunkAlias: string | null = null; orderedModules: Module[]; renderedModules?: { @@ -162,6 +157,7 @@ export default class Chunk { private exports = new Set(); private fileName: string | null = null; private imports = new Set(); + private isEmpty = true; private name: string | null = null; private needsExportsShim = false; private renderedDependencies: Map< @@ -180,7 +176,6 @@ export default class Chunk { this.orderedModules = orderedModules; this.execIndex = orderedModules.length > 0 ? orderedModules[0].execIndex : Infinity; - this.isEmpty = true; for (const module of orderedModules) { if (this.isEmpty && module.isIncluded()) { this.isEmpty = false; @@ -357,9 +352,7 @@ export default class Chunk { } getDynamicImportIds(): string[] { - return Array.from(this.dynamicDependencies) - .map(chunk => chunk.id) - .filter(Boolean) as string[]; + return Array.from(this.dynamicDependencies).map(chunk => chunk.id as string); } getExportNames(): string[] { @@ -369,9 +362,7 @@ export default class Chunk { } getImportIds(): string[] { - return Array.from(this.dependencies) - .map(chunk => chunk.id) - .filter(Boolean) as string[]; + return Array.from(this.dependencies).map(chunk => chunk.id as string); } getRenderedHash(outputPluginDriver: PluginDriver): string { @@ -561,7 +552,6 @@ export default class Chunk { if (dep instanceof Chunk) this.inlineChunkDependencies(dep, true); } } - // TODO Lukas filtering and sorting dependencies, could this be done earlier? const sortedDependencies = Array.from(this.dependencies); sortByExecutionOrder(sortedDependencies); this.dependencies = new Set(sortedDependencies); @@ -783,19 +773,13 @@ export default class Chunk { chunkDependencies: Set ) { for (const depModule of moduleDependencies) { - if (depModule.chunk === this) { - continue; - } - let dependency: Chunk | ExternalModule; if (depModule instanceof Module) { - dependency = depModule.chunk!; - } else { - if (!(depModule.used || depModule.moduleSideEffects)) { - continue; + if (depModule.chunk && depModule.chunk !== this) { + chunkDependencies.add(depModule.chunk); } - dependency = depModule; + } else { + chunkDependencies.add(depModule); } - chunkDependencies.add(dependency); } } @@ -872,8 +856,8 @@ export default class Chunk { for (const { node, resolution } of module.dynamicImports) { if (!resolution) continue; if (resolution instanceof Module) { - if (resolution.chunk !== this && isChunkRendered(resolution.chunk!)) { - const resolutionChunk = resolution.facadeChunk || resolution.chunk!; + if (resolution.chunk && resolution.chunk !== this) { + const resolutionChunk = resolution.facadeChunk || resolution.chunk; node.renderFinalResolution( code, `'${this.getRelativePath(resolutionChunk.id!)}'`, diff --git a/src/Graph.ts b/src/Graph.ts index e3da9ec9a25..20d9a664841 100644 --- a/src/Graph.ts +++ b/src/Graph.ts @@ -4,7 +4,7 @@ import injectImportMeta from 'acorn-import-meta'; import * as ESTree from 'estree'; import GlobalScope from './ast/scopes/GlobalScope'; import { PathTracker } from './ast/utils/PathTracker'; -import Chunk, { isChunkRendered } from './Chunk'; +import Chunk from './Chunk'; import ExternalModule from './ExternalModule'; import Module, { defaultAcornOptions } from './Module'; import { ModuleLoader, UnresolvedModule } from './ModuleLoader'; @@ -21,8 +21,7 @@ import { WarningHandler } from './rollup/types'; import { BuildPhase } from './utils/buildPhase'; -import { assignChunkColouringHashes } from './utils/chunkColouring'; -import { Uint8ArrayToHexString } from './utils/entryHashing'; +import { getChunkAssignments } from './utils/chunkAssignment'; import { errDeprecation, error } from './utils/error'; import { analyseModuleExecution, sortByExecutionOrder } from './utils/executionOrder'; import { resolve } from './utils/path'; @@ -249,33 +248,22 @@ export default class Graph { const chunks: Chunk[] = []; if (this.preserveModules) { for (const module of this.modules) { - const chunk = new Chunk(this, [module]); - if (isChunkRendered(chunk)) { + if ( + module.isIncluded() || + module.isEntryPoint || + module.dynamicallyImportedBy.length > 0 + ) { + const chunk = new Chunk(this, [module]); chunk.entryModules = [module]; chunks.push(chunk); } } } else { - // TODO Lukas we want to get rid of hashes - if (!inlineDynamicImports) { - assignChunkColouringHashes(entryModules, manualChunkModulesByAlias); - } - const chunkModules: { [entryHashSum: string]: Module[] } = {}; - for (const module of this.modules) { - const entryPointsHashStr = Uint8ArrayToHexString(module.entryPointsHash); - const curChunk = chunkModules[entryPointsHashStr]; - if (curChunk) { - curChunk.push(module); - } else { - chunkModules[entryPointsHashStr] = [module]; - } - } - - for (const entryHashSum in chunkModules) { - const chunkModulesOrdered = chunkModules[entryHashSum]; - sortByExecutionOrder(chunkModulesOrdered); - const chunk = new Chunk(this, chunkModulesOrdered); - if (isChunkRendered(chunk)) chunks.push(chunk); + for (const chunkModules of inlineDynamicImports + ? [this.modules] + : getChunkAssignments(entryModules, manualChunkModulesByAlias)) { + sortByExecutionOrder(chunkModules); + chunks.push(new Chunk(this, chunkModules)); } } diff --git a/src/Module.ts b/src/Module.ts index 9cdda32896c..963b4187938 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -347,7 +347,6 @@ export default class Module { } getDependenciesToBeIncluded(): Set { - timeStart('getDependenciesToBeIncluded', 3); if (this.relevantDependencies) return this.relevantDependencies; const relevantDependencies = new Set(); for (const variable of this.imports) { @@ -358,7 +357,6 @@ export default class Module { relevantDependencies.add(this.getVariableForExportName(exportName).module as Module); } } - // TODO Lukas this could be a performance risk if (this.graph.treeshakingOptions) { const possibleDependencies = new Set(this.dependencies); for (const dependency of possibleDependencies) { @@ -379,7 +377,6 @@ export default class Module { relevantDependencies.add(dependency); } } - timeEnd('getDependenciesToBeIncluded', 3); return (this.relevantDependencies = relevantDependencies); } diff --git a/src/utils/chunkColouring.ts b/src/utils/chunkAssignment.ts similarity index 87% rename from src/utils/chunkColouring.ts rename to src/utils/chunkAssignment.ts index 283b1ddf89e..dd735098cf9 100644 --- a/src/utils/chunkColouring.ts +++ b/src/utils/chunkAssignment.ts @@ -1,13 +1,14 @@ import ExternalModule from '../ExternalModule'; import Module from '../Module'; -import { randomUint8Array, Uint8ArrayXor } from './entryHashing'; +import { randomUint8Array, Uint8ArrayToHexString, Uint8ArrayXor } from './entryHashing'; type DependentModuleMap = Map>; -export function assignChunkColouringHashes( +export function getChunkAssignments( entryModules: Module[], manualChunkModules: Record -) { +): Module[][] { + const includedModules = new Set(); const { dependentEntryPointsByModule, dynamicEntryModules } = analyzeModuleGraph(entryModules); const dynamicDependentEntryPointsByDynamicEntry: DependentModuleMap = getDynamicDependentEntryPoints( dependentEntryPointsByModule, @@ -23,6 +24,7 @@ export function assignChunkColouringHashes( const manualChunkAlias = entry.manualChunkAlias; const modulesToHandle = new Set([entry]); for (const module of modulesToHandle) { + includedModules.add(module); if (manualChunkAlias) { module.manualChunkAlias = manualChunkAlias; module.entryPointsHash = colour; @@ -89,6 +91,18 @@ export function assignChunkColouringHashes( ); } } + + const chunkModules: { [entryHashSum: string]: Module[] } = {}; + for (const module of includedModules) { + const entryPointsHashStr = Uint8ArrayToHexString(module.entryPointsHash); + const curChunk = chunkModules[entryPointsHashStr]; + if (curChunk) { + curChunk.push(module); + } else { + chunkModules[entryPointsHashStr] = [module]; + } + } + return Object.keys(chunkModules).map(entryHashSum => chunkModules[entryHashSum]); } function analyzeModuleGraph( diff --git a/src/utils/entryHashing.ts b/src/utils/entryHashing.ts index e8f7b52472a..bdde7a0dbfc 100644 --- a/src/utils/entryHashing.ts +++ b/src/utils/entryHashing.ts @@ -1,3 +1,4 @@ +// TODO Lukas delete? const CHAR_CODE_A = 97; const CHAR_CODE_0 = 48; diff --git a/test/chunking-form/samples/entry-point-without-own-code/_expected/es/generated-m1.js b/test/chunking-form/samples/entry-point-without-own-code/_expected/es/generated-m1.js index eb6534be2c3..4197cabf46a 100644 --- a/test/chunking-form/samples/entry-point-without-own-code/_expected/es/generated-m1.js +++ b/test/chunking-form/samples/entry-point-without-own-code/_expected/es/generated-m1.js @@ -1,5 +1,5 @@ import m2 from './m2.js'; -export { default as m } from './m2.js'; +export { default as a } from './m2.js'; @@ -8,4 +8,4 @@ var ms = /*#__PURE__*/Object.freeze({ m2: m2 }); -export { ms as a }; +export { ms as m }; diff --git a/test/chunking-form/samples/entry-point-without-own-code/_expected/es/main.js b/test/chunking-form/samples/entry-point-without-own-code/_expected/es/main.js index 107671de693..161f7abae87 100644 --- a/test/chunking-form/samples/entry-point-without-own-code/_expected/es/main.js +++ b/test/chunking-form/samples/entry-point-without-own-code/_expected/es/main.js @@ -1,4 +1,4 @@ import './m2.js'; -import { a as ms } from './generated-m1.js'; +import { m as ms } from './generated-m1.js'; console.log(ms); diff --git a/test/chunking-form/samples/entry-point-without-own-code/_expected/system/generated-m1.js b/test/chunking-form/samples/entry-point-without-own-code/_expected/system/generated-m1.js index b592474ea09..591300d8a86 100644 --- a/test/chunking-form/samples/entry-point-without-own-code/_expected/system/generated-m1.js +++ b/test/chunking-form/samples/entry-point-without-own-code/_expected/system/generated-m1.js @@ -4,7 +4,7 @@ System.register(['./m2.js'], function (exports) { return { setters: [function (module) { m2 = module.default; - exports('m', module.default); + exports('a', module.default); }], execute: function () { @@ -14,7 +14,7 @@ System.register(['./m2.js'], function (exports) { __proto__: null, m2: m2 }); - exports('a', ms); + exports('m', ms); } }; diff --git a/test/chunking-form/samples/entry-point-without-own-code/_expected/system/main.js b/test/chunking-form/samples/entry-point-without-own-code/_expected/system/main.js index 6c433a4d441..a210bd11cb5 100644 --- a/test/chunking-form/samples/entry-point-without-own-code/_expected/system/main.js +++ b/test/chunking-form/samples/entry-point-without-own-code/_expected/system/main.js @@ -3,7 +3,7 @@ System.register(['./m2.js', './generated-m1.js'], function () { var ms; return { setters: [function () {}, function (module) { - ms = module.a; + ms = module.m; }], execute: function () { diff --git a/test/chunking-form/samples/namespace-reexports/_expected/cjs/main.js b/test/chunking-form/samples/namespace-reexports/_expected/cjs/main.js index f56ee42c2ad..2ca1ab022e7 100644 --- a/test/chunking-form/samples/namespace-reexports/_expected/cjs/main.js +++ b/test/chunking-form/samples/namespace-reexports/_expected/cjs/main.js @@ -2,10 +2,10 @@ Object.defineProperty(exports, '__esModule', { value: true }); -var hsl2hsv$1 = require('./hsl2hsv.js'); +var hsl2hsv = require('./hsl2hsv.js'); var index = require('./generated-index.js'); -console.log(hsl2hsv$1.p); +console.log(hsl2hsv.p); var main = new Map(Object.entries(index.lib)); exports.default = main; diff --git a/test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/amd/4ef5e079.js b/test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/amd/19d89d54.js similarity index 100% rename from test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/amd/4ef5e079.js rename to test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/amd/19d89d54.js diff --git a/test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/cjs/be351642.js b/test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/cjs/797a17bf.js similarity index 100% rename from test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/cjs/be351642.js rename to test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/cjs/797a17bf.js diff --git a/test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/es/4cadb2a6.js b/test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/es/114f0e8d.js similarity index 100% rename from test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/es/4cadb2a6.js rename to test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/es/114f0e8d.js diff --git a/test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/system/b0f0487c.js b/test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/system/52b8365a.js similarity index 100% rename from test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/system/b0f0487c.js rename to test/chunking-form/samples/tree-shaken-dynamic-hash/_expected/system/52b8365a.js From bd20782b24dc83cfed99b063150307eb321f4bd2 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Tue, 4 Feb 2020 17:16:14 +0100 Subject: [PATCH 7/9] Get rid of colouring hashes --- src/Chunk.ts | 30 ++----- src/Graph.ts | 2 +- src/Module.ts | 7 +- src/utils/chunkAssignment.ts | 79 +++++++++++-------- src/utils/entryHashing.ts | 31 -------- .../_config.js | 1 - 6 files changed, 55 insertions(+), 95 deletions(-) delete mode 100644 src/utils/entryHashing.ts diff --git a/src/Chunk.ts b/src/Chunk.ts index 3f8ad9bd033..630d3134c92 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -352,7 +352,7 @@ export default class Chunk { } getDynamicImportIds(): string[] { - return Array.from(this.dynamicDependencies).map(chunk => chunk.id as string); + return [...this.dynamicDependencies].map(chunk => chunk.id as string); } getExportNames(): string[] { @@ -362,7 +362,7 @@ export default class Chunk { } getImportIds(): string[] { - return Array.from(this.dependencies).map(chunk => chunk.id as string); + return [...this.dependencies].map(chunk => chunk.id as string); } getRenderedHash(outputPluginDriver: PluginDriver): string { @@ -552,7 +552,7 @@ export default class Chunk { if (dep instanceof Chunk) this.inlineChunkDependencies(dep, true); } } - const sortedDependencies = Array.from(this.dependencies); + const sortedDependencies = [...this.dependencies]; sortByExecutionOrder(sortedDependencies); this.dependencies = new Set(sortedDependencies); @@ -656,7 +656,7 @@ export default class Chunk { const hasExports = this.renderedExports!.length !== 0 || - Array.from(this.renderedDependencies!.values()).some( + [...this.renderedDependencies!.values()].some( dep => (dep.reexports && dep.reexports.length !== 0)! ); @@ -687,7 +687,7 @@ export default class Chunk { this.renderedSource!, { accessedGlobals, - dependencies: Array.from(this.renderedDependencies!.values()), + dependencies: [...this.renderedDependencies!.values()], exports: this.renderedExports!, hasExports, indentString: this.indentString, @@ -841,10 +841,7 @@ export default class Chunk { hash.update(current.generateId(addons, options, existingNames, false, outputPluginDriver)); } if (current instanceof ExternalModule) continue; - for (const dependency of current.dependencies) { - dependenciesForHashing.add(dependency); - } - for (const dependency of current.dynamicDependencies) { + for (const dependency of [...current.dependencies, ...current.dynamicDependencies]) { dependenciesForHashing.add(dependency); } } @@ -1077,12 +1074,7 @@ export default class Chunk { } private setExternalRenderPaths(options: OutputOptions, inputBase: string) { - for (const dependency of this.dependencies) { - if (dependency instanceof ExternalModule) { - dependency.setRenderPath(options, inputBase); - } - } - for (const dependency of this.dynamicDependencies) { + for (const dependency of [...this.dependencies, ...this.dynamicDependencies]) { if (dependency instanceof ExternalModule) { dependency.setRenderPath(options, inputBase); } @@ -1154,14 +1146,6 @@ export default class Chunk { const map = module.getExportNamesByVariable(); for (const exportedVariable of map.keys()) { this.exports.add(exportedVariable); - const exportSourceModule = exportedVariable.module!; - const exportChunk = - exportSourceModule instanceof ExternalModule - ? exportSourceModule - : exportSourceModule.chunk!; - if (exportChunk !== this) { - this.dependencies.add(exportChunk); - } const exportingModule = exportedVariable.module; if (exportingModule && exportingModule.chunk && exportingModule.chunk !== this) { exportingModule.chunk.exports.add(exportedVariable); diff --git a/src/Graph.ts b/src/Graph.ts index 20d9a664841..ee64cafdb89 100644 --- a/src/Graph.ts +++ b/src/Graph.ts @@ -278,7 +278,7 @@ export default class Graph { timeEnd('generate chunks', 2); this.phase = BuildPhase.GENERATE; - return chunks.concat(facades); + return [...chunks, ...facades]; }); } diff --git a/src/Module.ts b/src/Module.ts index 963b4187938..62d49e835f0 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -205,7 +205,6 @@ export default class Module { node: ImportExpression; resolution: Module | ExternalModule | string | null; }[] = []; - entryPointsHash: Uint8Array = new Uint8Array(10); excludeFromSourcemap: boolean; execIndex = Infinity; exportAllModules: (Module | ExternalModule)[] = []; @@ -353,7 +352,7 @@ export default class Module { relevantDependencies.add(variable.module!); } if (this.isEntryPoint || this.dynamicallyImportedBy.length > 0 || this.graph.preserveModules) { - for (const exportName of this.getReexports().concat(this.getExports())) { + for (const exportName of [...this.getReexports(), ...this.getExports()]) { relevantDependencies.add(this.getVariableForExportName(exportName).module as Module); } } @@ -444,7 +443,7 @@ export default class Module { if (module instanceof ExternalModule) { reexports.add(`*${module.id}`); } else { - for (const name of module.getExports().concat(module.getReexports())) { + for (const name of [...module.getReexports(), ...module.getExports()]) { if (name !== 'default') reexports.add(name); } } @@ -613,7 +612,7 @@ export default class Module { module ); } - this.exportAllModules = this.exportAllModules.concat(externalExportAllModules); + this.exportAllModules = [...this.exportAllModules, ...externalExportAllModules]; } render(options: RenderOptions): MagicString { diff --git a/src/utils/chunkAssignment.ts b/src/utils/chunkAssignment.ts index dd735098cf9..53d5f2c41b6 100644 --- a/src/utils/chunkAssignment.ts +++ b/src/utils/chunkAssignment.ts @@ -1,33 +1,32 @@ import ExternalModule from '../ExternalModule'; import Module from '../Module'; -import { randomUint8Array, Uint8ArrayToHexString, Uint8ArrayXor } from './entryHashing'; -type DependentModuleMap = Map>; +type DependentModuleMap = Map>; export function getChunkAssignments( entryModules: Module[], manualChunkModules: Record ): Module[][] { - const includedModules = new Set(); + const assignedEntryPointsByModule: DependentModuleMap = new Map(); const { dependentEntryPointsByModule, dynamicEntryModules } = analyzeModuleGraph(entryModules); - const dynamicDependentEntryPointsByDynamicEntry: DependentModuleMap = getDynamicDependentEntryPoints( + const dynamicallyDependentEntryPointsByDynamicEntry: DependentModuleMap = getDynamicDependentEntryPoints( dependentEntryPointsByModule, dynamicEntryModules ); const staticEntries = new Set(entryModules); - function addColourToModuleDependencies( + function assignEntryToStaticDependencies( entry: Module, - colour: Uint8Array, - dynamicDependentEntryPoints: Set | null + dynamicDependentEntryPoints: Set | null, + assignedEntry: Module | string = entry ) { const manualChunkAlias = entry.manualChunkAlias; const modulesToHandle = new Set([entry]); for (const module of modulesToHandle) { - includedModules.add(module); + const assignedEntryPoints = getDependentModules(assignedEntryPointsByModule, module); if (manualChunkAlias) { module.manualChunkAlias = manualChunkAlias; - module.entryPointsHash = colour; + assignedEntryPoints.add(assignedEntry); } else if ( dynamicDependentEntryPoints && areEntryPointsContainedOrDynamicallyDependent( @@ -37,7 +36,7 @@ export function getChunkAssignments( ) { continue; } else { - Uint8ArrayXor(module.entryPointsHash, colour); + assignedEntryPoints.add(assignedEntry); } for (const dependency of module.getDependenciesToBeIncluded()) { if (!(dependency instanceof ExternalModule || dependency.manualChunkAlias)) { @@ -55,7 +54,9 @@ export function getChunkAssignments( for (const entry of entriesToCheck) { if (!superSet.has(entry)) { if (staticEntries.has(entry)) return false; - const dynamicDependentEntryPoints = dynamicDependentEntryPointsByDynamicEntry.get(entry)!; + const dynamicDependentEntryPoints = dynamicallyDependentEntryPointsByDynamicEntry.get( + entry + )!; for (const dependentEntry of dynamicDependentEntryPoints) { entriesToCheck.add(dependentEntry); } @@ -66,43 +67,31 @@ export function getChunkAssignments( if (manualChunkModules) { for (const chunkName of Object.keys(manualChunkModules)) { - const entryHash = randomUint8Array(10); - for (const entry of manualChunkModules[chunkName]) { - addColourToModuleDependencies(entry, entryHash, null); + assignEntryToStaticDependencies(entry, null, chunkName); } } } for (const entry of entryModules) { if (!entry.manualChunkAlias) { - const entryHash = randomUint8Array(10); - addColourToModuleDependencies(entry, entryHash, null); + assignEntryToStaticDependencies(entry, null); } } for (const entry of dynamicEntryModules) { if (!entry.manualChunkAlias) { - const entryHash = randomUint8Array(10); - addColourToModuleDependencies( + assignEntryToStaticDependencies( entry, - entryHash, - dynamicDependentEntryPointsByDynamicEntry.get(entry)! + dynamicallyDependentEntryPointsByDynamicEntry.get(entry)! ); } } - const chunkModules: { [entryHashSum: string]: Module[] } = {}; - for (const module of includedModules) { - const entryPointsHashStr = Uint8ArrayToHexString(module.entryPointsHash); - const curChunk = chunkModules[entryPointsHashStr]; - if (curChunk) { - curChunk.push(module); - } else { - chunkModules[entryPointsHashStr] = [module]; - } - } - return Object.keys(chunkModules).map(entryHashSum => chunkModules[entryHashSum]); + return createChunks( + [...Object.keys(manualChunkModules), ...entryModules, ...dynamicEntryModules], + assignedEntryPointsByModule + ); } function analyzeModuleGraph( @@ -138,7 +127,7 @@ function analyzeModuleGraph( return { dependentEntryPointsByModule, dynamicEntryModules }; } -function getDependentModules(moduleMap: DependentModuleMap, module: Module): Set { +function getDependentModules(moduleMap: DependentModuleMap, module: Module): Set { const dependentModules = moduleMap.get(module) || new Set(); moduleMap.set(module, dependentModules); return dependentModules; @@ -148,10 +137,10 @@ function getDynamicDependentEntryPoints( dependentEntryPointsByModule: DependentModuleMap, dynamicEntryModules: Set ): DependentModuleMap { - const dynamicDependentEntryPointsByDynamicEntry: DependentModuleMap = new Map(); + const dynamicallyDependentEntryPointsByDynamicEntry: DependentModuleMap = new Map(); for (const dynamicEntry of dynamicEntryModules) { const dynamicDependentEntryPoints = getDependentModules( - dynamicDependentEntryPointsByDynamicEntry, + dynamicallyDependentEntryPointsByDynamicEntry, dynamicEntry ); for (const importer of dynamicEntry.dynamicallyImportedBy) { @@ -160,5 +149,25 @@ function getDynamicDependentEntryPoints( } } } - return dynamicDependentEntryPointsByDynamicEntry; + return dynamicallyDependentEntryPointsByDynamicEntry; +} + +function createChunks( + allEntryPoints: (Module | string)[], + assignedEntryPointsByModule: DependentModuleMap +) { + const chunkModules: { [chunkSignature: string]: Module[] } = Object.create(null); + for (const [module, assignedEntryPoints] of assignedEntryPointsByModule) { + let chunkSignature = ''; + for (const entry of allEntryPoints) { + chunkSignature += assignedEntryPoints.has(entry) ? 'X' : '_'; + } + const chunk = chunkModules[chunkSignature]; + if (chunk) { + chunk.push(module); + } else { + chunkModules[chunkSignature] = [module]; + } + } + return Object.keys(chunkModules).map(chunkSignature => chunkModules[chunkSignature]); } diff --git a/src/utils/entryHashing.ts b/src/utils/entryHashing.ts deleted file mode 100644 index bdde7a0dbfc..00000000000 --- a/src/utils/entryHashing.ts +++ /dev/null @@ -1,31 +0,0 @@ -// TODO Lukas delete? -const CHAR_CODE_A = 97; -const CHAR_CODE_0 = 48; - -function intToHex(num: number): string { - if (num < 10) return String.fromCharCode(CHAR_CODE_0 + num); - else return String.fromCharCode(CHAR_CODE_A + (num - 10)); -} - -export function Uint8ArrayToHexString(buffer: Uint8Array): string { - let str = ''; - // hex conversion - 2 chars per 8 bit component - for (let i = 0; i < buffer.length; i++) { - const num = buffer[i]; - // big endian conversion, but whatever - str += intToHex(num >> 4); - str += intToHex(num & 0xf); - } - return str; -} - -export function randomUint8Array(len: number): Uint8Array { - const buffer = new Uint8Array(len); - for (let i = 0; i < buffer.length; i++) buffer[i] = Math.random() * (2 << 8); - return buffer; -} - -export function Uint8ArrayXor(to: Uint8Array, from: Uint8Array): Uint8Array { - for (let i = 0; i < to.length; i++) to[i] = to[i] ^ from[i]; - return to; -} diff --git a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_config.js b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_config.js index 8715cf7802c..615562a76d9 100644 --- a/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_config.js +++ b/test/chunking-form/samples/side-effect-free-dependencies/module-side-effects-empty-imports/_config.js @@ -1,4 +1,3 @@ -// TODO Lukas at the moment, there is probably an "empty" catch-all chunk that is pruned module.exports = { description: 'avoids empty imports if moduleSideEffects are false', options: { From 1efe9f648d7668d6c1d9885b53e77dad1017bf89 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Wed, 5 Feb 2020 06:54:57 +0100 Subject: [PATCH 8/9] Improve coverage --- src/Chunk.ts | 56 ++++++++----------- src/Module.ts | 7 +-- src/utils/chunkAssignment.ts | 8 +-- src/utils/executionOrder.ts | 3 - .../avoid-imports-preserve-modules/_config.js | 7 +++ .../_expected/amd/a.js | 9 +++ .../_expected/amd/b.js | 9 +++ .../_expected/amd/main.js | 5 ++ .../_expected/amd/one.js | 9 +++ .../_expected/cjs/a.js | 7 +++ .../_expected/cjs/b.js | 7 +++ .../_expected/cjs/main.js | 6 ++ .../_expected/cjs/one.js | 9 +++ .../_expected/es/a.js | 3 + .../_expected/es/b.js | 3 + .../_expected/es/main.js | 4 ++ .../_expected/es/one.js | 5 ++ .../_expected/system/a.js | 10 ++++ .../_expected/system/b.js | 10 ++++ .../_expected/system/main.js | 16 ++++++ .../_expected/system/one.js | 14 +++++ .../avoid-imports-preserve-modules/a.js | 1 + .../avoid-imports-preserve-modules/b.js | 1 + .../avoid-imports-preserve-modules/c.js | 1 + .../avoid-imports-preserve-modules/index.js | 3 + .../avoid-imports-preserve-modules/main.js | 3 + .../avoid-imports-preserve-modules/one.js | 2 + 27 files changed, 172 insertions(+), 46 deletions(-) create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_config.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/a.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/b.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/amd/one.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/a.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/b.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/cjs/one.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/a.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/b.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/es/one.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/a.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/b.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/_expected/system/one.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/a.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/b.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/c.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/index.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/main.js create mode 100644 test/chunking-form/samples/side-effect-free-dependencies/avoid-imports-preserve-modules/one.js diff --git a/src/Chunk.ts b/src/Chunk.ts index 630d3134c92..de4f4a689d7 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); } } } @@ -1084,22 +1081,19 @@ export default class Chunk { private setIdentifierRenderResolutions(options: OutputOptions) { for (const exportName of this.getExportNames()) { const exportVariable = this.exportNames[exportName]; - if (exportVariable) { - if (exportVariable instanceof ExportShimVariable) { - this.needsExportsShim = true; - } - exportVariable.exportName = exportName; - if ( - options.format !== 'es' && - options.format !== 'system' && - exportVariable.isReassigned && - !exportVariable.isId && - !(exportVariable instanceof ExportDefaultVariable && exportVariable.hasId) - ) { - exportVariable.setRenderNames('exports', exportName); - } else { - exportVariable.setRenderNames(null, null); - } + if (exportVariable instanceof ExportShimVariable) { + this.needsExportsShim = true; + } + exportVariable.exportName = exportName; + if ( + options.format !== 'es' && + options.format !== 'system' && + exportVariable.isReassigned && + !exportVariable.isId + ) { + exportVariable.setRenderNames('exports', exportName); + } else { + exportVariable.setRenderNames(null, null); } } @@ -1158,9 +1152,7 @@ export default class Chunk { const variable = reexport.module.getVariableForExportName(reexport.localName); if ((variable.module as Module).chunk !== this) { this.imports.add(variable); - if (variable.module instanceof Module) { - variable.module.chunk!.exports.add(variable); - } + (variable.module as Module).chunk!.exports.add(variable); } } } 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; From b33523814ab6acb08e145e7b1b71373ac8d014e9 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Fri, 7 Feb 2020 08:56:41 +0100 Subject: [PATCH 9/9] Store the build output as artifact and post an automated comment --- .circleci/config.yml | 33 +++++++++++++---------- .eslintrc.json | 2 +- package.json | 1 + scripts/post-comment.js | 60 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 15 deletions(-) create mode 100755 scripts/post-comment.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 9e0f0f807d5..bc4f2e17b15 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,14 +1,5 @@ version: 2 -unit_tests: &unit_tests - steps: - - checkout - - restore_cache: - key: dependency-cache-{{ checksum "package-lock.json" }} - - run: - name: Run unit tests. - command: npm run ci:test - jobs: analysis: docker: @@ -18,13 +9,13 @@ jobs: - restore_cache: key: dependency-cache-{{ checksum "package-lock.json" }} - run: - name: Install Dependencies + name: Installing Dependencies command: npm ci --ignore-scripts - run: - name: Run linting. + name: Running linting command: npm run ci:lint - run: - name: Run NPM Security Audit + name: Running NPM Security Audit command: npm run security - save_cache: key: dependency-cache-{{ checksum "package-lock.json" }} @@ -33,7 +24,20 @@ jobs: node-v10-latest: docker: - image: rollupcabal/circleci-node-v10:latest - <<: *unit_tests + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ checksum "package-lock.json" }} + - run: + name: Running tests + command: npm run ci:test + - store_artifacts: + name: Storing browser build for REPL + path: /home/circleci/project/dist/rollup.browser.js + destination: rollup.browser.js + - run: + name: Post REPL comment + command: ./scripts/post-comment.js node-v12-latest: docker: - image: rollupcabal/circleci-node-v12:latest @@ -42,9 +46,10 @@ jobs: - restore_cache: key: dependency-cache-{{ checksum "package-lock.json" }} - run: - name: Run tests with coverage. + name: Running tests with coverage command: npm run ci:coverage + workflows: version: 2 validate-test: diff --git a/.eslintrc.json b/.eslintrc.json index e35395ba7e3..5925f36e338 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -32,7 +32,7 @@ "plugin:import/warnings" ], "parserOptions": { - "ecmaVersion": 6, + "ecmaVersion": 2018, "sourceType": "module" }, "settings": { diff --git a/package.json b/package.json index 1c2105a002c..09b8917dc3e 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "micromatch": "^4.0.2", "minimist": "^1.2.0", "mocha": "^6.2.2", + "node-fetch": "^2.6.0", "nyc": "^15.0.0", "prettier": "^1.19.1", "pretty-bytes": "^5.3.0", diff --git a/scripts/post-comment.js b/scripts/post-comment.js new file mode 100755 index 00000000000..1532fa65085 --- /dev/null +++ b/scripts/post-comment.js @@ -0,0 +1,60 @@ +#!/usr/bin/env node + +const path = require('path'); +const fetch = require('node-fetch'); + +const authToken = process.env.GH_AUTH_TOKEN; +if (!authToken) { + throw new Error('Could not find auth token.'); +} + +const prNumber = path.basename( + process.env.CIRCLE_PULL_REQUEST || process.env.CI_PULL_REQUEST || '' +); +if (!prNumber) { + console.log('No pull request number found'); + process.exit(0); +} + +const headline = '### Thank you for your contribution! ❤️'; + +postComment(); + +async function postComment() { + const existingId = await findExistingComment(); + console.log(existingId ? `Update comment ${existingId}` : 'Create new comment.'); + const installPath = await getInstallPath(); + const path = existingId ? `issues/comments/${existingId}` : `issues/${prNumber}/comments`; + const method = existingId ? 'PATCH' : 'POST'; + await fetch(getApiUrl(path), { + method, + body: JSON.stringify({ + body: `${headline} + +You can try out this pull request locally via + +\`\`\` +npm install ${installPath} +\`\`\` + +or load it into the REPL: +https://rollupjs.org/repl/?circleci=${process.env.CIRCLE_BUILD_NUM} +` + }) + }); +} + +async function findExistingComment() { + const comments = await (await fetch(getApiUrl(`issues/${prNumber}/comments`), {})).json(); + const existingComment = comments.find(comment => comment.body.startsWith(headline)); + return existingComment && existingComment.id; +} + +async function getInstallPath() { + const prInfo = await (await fetch(getApiUrl(`pulls/${prNumber}`), {})).json(); + return `${prInfo.head.repo.full_name}#${prInfo.head.ref}`; +} + +function getApiUrl(path) { + return `https://${authToken}:x-oauth-basic@api.github.com/repos/rollup/rollup/${path}`; +}