diff --git a/lib/javascript/JavascriptModulesPlugin.js b/lib/javascript/JavascriptModulesPlugin.js index 4249a2f5105..218f138cb27 100644 --- a/lib/javascript/JavascriptModulesPlugin.js +++ b/lib/javascript/JavascriptModulesPlugin.js @@ -5,6 +5,7 @@ "use strict"; +const eslintScope = require("eslint-scope"); const { SyncWaterfallHook, SyncHook, SyncBailHook } = require("tapable"); const vm = require("vm"); const { @@ -12,7 +13,8 @@ const { OriginalSource, PrefixSource, RawSource, - CachedSource + CachedSource, + ReplaceSource } = require("webpack-sources"); const Compilation = require("../Compilation"); const { tryRunOrWebpackError } = require("../HookWebpackError"); @@ -30,11 +32,13 @@ const { last, someInIterable } = require("../util/IterableHelpers"); const StringXor = require("../util/StringXor"); const { compareModulesByIdentifier } = require("../util/comparators"); const createHash = require("../util/createHash"); +const { getPathInAst, getAllReferences } = require("../util/mergeScope"); const nonNumericOnlyHash = require("../util/nonNumericOnlyHash"); const { intersectRuntime } = require("../util/runtime"); const JavascriptGenerator = require("./JavascriptGenerator"); const JavascriptParser = require("./JavascriptParser"); +/** @typedef {import("eslint-scope").Variable} Variable */ /** @typedef {import("webpack-sources").Source} Source */ /** @typedef {import("../Chunk")} Chunk */ /** @typedef {import("../ChunkGraph")} ChunkGraph */ @@ -818,13 +822,19 @@ class JavascriptModulesPlugin { const lastInlinedModule = last(inlinedModules); const startupSource = new ConcatSource(); startupSource.add(`var ${RuntimeGlobals.exports} = {};\n`); + const renamedInlinedModules = this.renamedRootModule( + allModules, + renderContext, + inlinedModules, + chunkRenderContext, + hooks + ); + for (const m of inlinedModules) { - const renderedModule = this.renderModule( - m, - chunkRenderContext, - hooks, - false - ); + const renderedModule = + renamedInlinedModules.get(m) || + this.renderModule(m, chunkRenderContext, hooks, false); + if (renderedModule) { const innerStrict = !allStrict && m.buildInfo.strict; const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements( @@ -840,11 +850,9 @@ class JavascriptModulesPlugin { ? // TODO check globals and top-level declarations of other entries and chunk modules // to make a better decision "it need to be isolated against other entry modules." - : chunkModules - ? "it need to be isolated against other modules in the chunk." - : exports && !webpackExports - ? `it uses a non-standard name for the exports (${m.exportsArgument}).` - : hooks.embedInRuntimeBailout.call(m, renderContext); + : exports && !webpackExports + ? `it uses a non-standard name for the exports (${m.exportsArgument}).` + : hooks.embedInRuntimeBailout.call(m, renderContext); let footer; if (iife !== undefined) { startupSource.add( @@ -1383,6 +1391,146 @@ class JavascriptModulesPlugin { "JavascriptModulesPlugin.getCompilationHooks().renderRequire" ); } + + /** + * @param {Module[]} allModules allModules + * @param {MainRenderContext} renderContext renderContext + * @param {Set} inlinedModules inlinedModules + * @param {ChunkRenderContext} chunkRenderContext chunkRenderContext + * @param {CompilationHooks} hooks hooks + * @returns {Map} renamed inlined modules + */ + renamedRootModule( + allModules, + renderContext, + inlinedModules, + chunkRenderContext, + hooks + ) { + const { runtimeTemplate } = renderContext; + + /** @type {Map }>} */ + const inlinedModulesToInfo = new Map(); + /** @type {Set} */ + const nonInlinedModuleThroughIdentifiers = new Set(); + /** @type {Map} */ + const renamedInlinedModules = new Map(); + /** @type {Set<{ m: Module, variable: Variable}>} */ + const usedIdentifiers = new Set(); + + for (const m of allModules) { + const isInlinedModule = inlinedModules && inlinedModules.has(m); + const moduleSource = this.renderModule( + m, + chunkRenderContext, + hooks, + isInlinedModule ? false : true + ); + + if (!moduleSource) continue; + const code = /** @type {string} */ (moduleSource.source()); + const ast = JavascriptParser._parse(code, { + sourceType: "auto" + }); + + const scopeManager = eslintScope.analyze(ast, { + ecmaVersion: 6, + sourceType: "module", + optimistic: true, + ignoreEval: true + }); + + const globalScope = scopeManager.acquire(ast); + if (inlinedModules && inlinedModules.has(m)) { + const moduleScope = globalScope.childScopes[0]; + const variables = new Set(); + for (const variable of moduleScope.variables) { + variables.add(variable); + } + inlinedModulesToInfo.set(m, { source: moduleSource, ast, variables }); + } else { + for (const ref of globalScope.through) { + nonInlinedModuleThroughIdentifiers.add(ref.identifier.name); + } + } + } + + for (const [module, { variables }] of inlinedModulesToInfo) { + for (const variable of variables) { + if (nonInlinedModuleThroughIdentifiers.has(variable.name)) { + usedIdentifiers.add({ m: module, variable }); + } + } + } + + const usedName = new Set(); + for (const { variable, m } of usedIdentifiers) { + const references = getAllReferences(variable); + const { ast, source: _source } = inlinedModulesToInfo.get(m); + const source = new ReplaceSource(_source); + const allIdentifiers = new Set( + references.map(r => r.identifier).concat(variable.identifiers) + ); + + const newName = this.findNewName( + variable.name, + usedName, + m.readableIdentifier(runtimeTemplate.requestShortener) + ); + + for (const identifier of allIdentifiers) { + const r = identifier.range; + const path = getPathInAst(ast, identifier); + if (path && path.length > 1) { + const maybeProperty = + path[1].type === "AssignmentPattern" && path[1].left === path[0] + ? path[2] + : path[1]; + if (maybeProperty.type === "Property" && maybeProperty.shorthand) { + source.insert(r[1], `: ${newName}`); + continue; + } + } + source.replace(r[0], r[1] - 1, newName); + } + + renamedInlinedModules.set(m, source); + } + + return renamedInlinedModules; + } + + /** + * @param {string} oldName oldName + * @param {Set} usedName usedName + * @param {string} extraInfo extraInfo + * @returns {string} extraInfo + */ + findNewName(oldName, usedName, extraInfo) { + let name = oldName; + + // Remove uncool stuff + extraInfo = extraInfo.replace( + /\.+\/|(\/index)?\.([a-zA-Z0-9]{1,4})($|\s|\?)|\s*\+\s*\d+\s*modules/g, + "" + ); + const splittedInfo = extraInfo.split("/"); + while (splittedInfo.length) { + name = splittedInfo.pop() + (name ? "_" + name : ""); + const nameIdent = Template.toIdentifier(name); + if (!usedName.has(nameIdent)) { + return nameIdent; + } + } + + let i = 0; + let nameWithNumber = Template.toIdentifier(`${oldName}_${i}`); + while (usedName.has(nameWithNumber)) { + i++; + nameWithNumber = Template.toIdentifier(`${oldName}_${i}`); + } + return nameWithNumber; + } } module.exports = JavascriptModulesPlugin; diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js index 70d7c5b462f..d75a0367831 100644 --- a/lib/optimize/ConcatenatedModule.js +++ b/lib/optimize/ConcatenatedModule.js @@ -26,6 +26,7 @@ const { concatComparators } = require("../util/comparators"); const createHash = require("../util/createHash"); const { makePathsRelative } = require("../util/identifier"); const makeSerializable = require("../util/makeSerializable"); +const { getAllReferences, getPathInAst } = require("../util/mergeScope"); const propertyAccess = require("../util/propertyAccess"); const { propertyName } = require("../util/propertyName"); const { @@ -625,72 +626,6 @@ const addScopeSymbols = (s, nameSet, scopeSet1, scopeSet2) => { } }; -/** - * @param {Variable} variable variable - * @returns {Reference[]} references - */ -const getAllReferences = variable => { - let set = variable.references; - // Look for inner scope variables too (like in class Foo { t() { Foo } }) - const identifiers = new Set(variable.identifiers); - for (const scope of variable.scope.childScopes) { - for (const innerVar of scope.variables) { - if (innerVar.identifiers.some(id => identifiers.has(id))) { - set = set.concat(innerVar.references); - break; - } - } - } - return set; -}; - -/** - * @param {TODO} ast ast - * @param {TODO} node node - * @returns {TODO} result - */ -const getPathInAst = (ast, node) => { - if (ast === node) { - return []; - } - - const nr = node.range; - - const enterNode = n => { - if (!n) return undefined; - const r = n.range; - if (r) { - if (r[0] <= nr[0] && r[1] >= nr[1]) { - const path = getPathInAst(n, node); - if (path) { - path.push(n); - return path; - } - } - } - return undefined; - }; - - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - const enterResult = enterNode(ast[i]); - if (enterResult !== undefined) return enterResult; - } - } else if (ast && typeof ast === "object") { - const keys = Object.keys(ast); - for (let i = 0; i < keys.length; i++) { - const value = ast[keys[i]]; - if (Array.isArray(value)) { - const pathResult = getPathInAst(value, node); - if (pathResult !== undefined) return pathResult; - } else if (value && typeof value === "object") { - const enterResult = enterNode(value); - if (enterResult !== undefined) return enterResult; - } - } - } -}; - const TYPES = new Set(["javascript"]); class ConcatenatedModule extends Module { diff --git a/lib/util/mergeScope.js b/lib/util/mergeScope.js new file mode 100644 index 00000000000..d9190ebb8b1 --- /dev/null +++ b/lib/util/mergeScope.js @@ -0,0 +1,79 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** @typedef {import("eslint-scope").Reference} Reference */ +/** @typedef {import("eslint-scope").Variable} Variable */ +/** @typedef {import("../javascript/JavascriptParser").AnyNode} AnyNode */ +/** @typedef {import("../javascript/JavascriptParser").Program} Program */ + +/** + * @param {Variable} variable variable + * @returns {Reference[]} references + */ +const getAllReferences = variable => { + let set = variable.references; + // Look for inner scope variables too (like in class Foo { t() { Foo } }) + const identifiers = new Set(variable.identifiers); + for (const scope of variable.scope.childScopes) { + for (const innerVar of scope.variables) { + if (innerVar.identifiers.some(id => identifiers.has(id))) { + set = set.concat(innerVar.references); + break; + } + } + } + return set; +}; + +/** + * @param {Program | Program[]} ast ast + * @param {AnyNode} node node + * @returns {undefined | AnyNode[]} result + */ +const getPathInAst = (ast, node) => { + if (ast === node) { + return []; + } + + const nr = node.range; + + const enterNode = n => { + if (!n) return undefined; + const r = n.range; + if (r) { + if (r[0] <= nr[0] && r[1] >= nr[1]) { + const path = getPathInAst(n, node); + if (path) { + path.push(n); + return path; + } + } + } + return undefined; + }; + + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + const enterResult = enterNode(ast[i]); + if (enterResult !== undefined) return enterResult; + } + } else if (ast && typeof ast === "object") { + const keys = Object.keys(ast); + for (let i = 0; i < keys.length; i++) { + const value = ast[keys[i]]; + if (Array.isArray(value)) { + const pathResult = getPathInAst(value, node); + if (pathResult !== undefined) return pathResult; + } else if (value && typeof value === "object") { + const enterResult = enterNode(value); + if (enterResult !== undefined) return enterResult; + } + } + } +}; + +module.exports = { getAllReferences, getPathInAst }; diff --git a/test/__snapshots__/StatsTestCases.basictest.js.snap b/test/__snapshots__/StatsTestCases.basictest.js.snap index 3909e7f9f0b..9f13125a451 100644 --- a/test/__snapshots__/StatsTestCases.basictest.js.snap +++ b/test/__snapshots__/StatsTestCases.basictest.js.snap @@ -157,7 +157,7 @@ webpack/runtime/make namespace object 274 bytes {main} [code generated] exports[`StatsTestCases should print correct stats for asset 1`] = ` "asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] [from: images/file.png] (auxiliary name: main) -asset bundle.js 13.6 KiB [emitted] (name: main) +asset bundle.js 13.4 KiB [emitted] (name: main) asset static/file.html 12 bytes [emitted] [from: static/file.html] (auxiliary name: main) runtime modules 1.15 KiB 2 modules modules by path ./ 9.36 KiB (javascript) 14.6 KiB (asset) @@ -519,10 +519,10 @@ webpack x.x.x compiled with 1 warning in X ms" exports[`StatsTestCases should print correct stats for chunk-module-id-range 1`] = ` "PublicPath: auto -asset main1.js 4.52 KiB [emitted] (name: main1) -asset main2.js 4.51 KiB [emitted] (name: main2) -Entrypoint main1 4.52 KiB = main1.js -Entrypoint main2 4.51 KiB = main2.js +asset main1.js 4.39 KiB [emitted] (name: main1) +asset main2.js 4.39 KiB [emitted] (name: main2) +Entrypoint main1 4.39 KiB = main1.js +Entrypoint main2 4.39 KiB = main2.js chunk (runtime: main1) main1.js (main1) 189 bytes (javascript) 670 bytes (runtime) [entry] [rendered] > ./main1 main1 runtime modules 670 bytes 3 modules @@ -546,7 +546,7 @@ webpack x.x.x compiled successfully in X ms" exports[`StatsTestCases should print correct stats for chunks 1`] = ` "PublicPath: auto -asset bundle.js 10.3 KiB [emitted] (name: main) +asset bundle.js 10.2 KiB [emitted] (name: main) asset 964.bundle.js 323 bytes [emitted] asset 226.bundle.js 206 bytes [emitted] asset 899.bundle.js 138 bytes [emitted] @@ -751,7 +751,7 @@ exports[`StatsTestCases should print correct stats for concat-and-sideeffects 1` `; exports[`StatsTestCases should print correct stats for context-independence 1`] = ` -"asset main-ca1a74034b366de49c9b.js 12.8 KiB [emitted] [immutable] (name: main) +"asset main-ca1a74034b366de49c9b.js 12.7 KiB [emitted] [immutable] (name: main) sourceMap main-ca1a74034b366de49c9b.js.map 11.1 KiB [emitted] [dev] (auxiliary name: main) asset 977-0d034101f87f8fa73545.js 455 bytes [emitted] [immutable] sourceMap 977-0d034101f87f8fa73545.js.map 347 bytes [emitted] [dev] @@ -767,7 +767,7 @@ built modules 500 bytes [built] ./a/cc/b.js (in my-layer) 18 bytes [optional] [built] [code generated] webpack x.x.x compiled successfully in X ms -asset main-ca1a74034b366de49c9b.js 12.8 KiB [emitted] [immutable] (name: main) +asset main-ca1a74034b366de49c9b.js 12.7 KiB [emitted] [immutable] (name: main) sourceMap main-ca1a74034b366de49c9b.js.map 11.1 KiB [emitted] [dev] (auxiliary name: main) asset 977-0d034101f87f8fa73545.js 455 bytes [emitted] [immutable] sourceMap 977-0d034101f87f8fa73545.js.map 347 bytes [emitted] [dev] @@ -841,7 +841,7 @@ webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for custom-terser 1`] = ` -"asset bundle.js 586 bytes [emitted] [minimized] (name: main) +"asset bundle.js 623 bytes [emitted] [minimized] (name: main) ./index.js 128 bytes [built] [code generated] [no exports used] ./a.js 49 bytes [built] [code generated] @@ -1021,7 +1021,7 @@ webpack x.x.x compiled with 1 error in X ms" `; exports[`StatsTestCases should print correct stats for dynamic-chunk-name-error 1`] = ` -"assets by status 8.29 KiB [cached] 3 assets +"assets by status 8.04 KiB [cached] 3 assets runtime modules 3.54 KiB 8 modules cacheable modules 128 bytes ./entry-1.js 63 bytes [built] [code generated] @@ -1164,7 +1164,7 @@ webpack x.x.x compiled with 2 errors in X ms" exports[`StatsTestCases should print correct stats for exclude-with-loader 1`] = ` "hidden assets 34 bytes 1 asset -asset bundle.js 5.38 KiB [emitted] (name: main) +asset bundle.js 5.25 KiB [emitted] (name: main) runtime modules 1.81 KiB 5 modules hidden modules 99 bytes 2 modules cacheable modules 119 bytes @@ -1174,7 +1174,7 @@ webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for external 1`] = ` -"asset main.js 1.37 KiB [emitted] (name: main) +"asset main.js 1.25 KiB [emitted] (name: main) ./index.js 17 bytes [built] [code generated] external \\"test\\" 42 bytes [built] [code generated] webpack x.x.x compiled successfully in X ms" @@ -1295,7 +1295,7 @@ asset 22c24a3b26d46118dc06.js 809 bytes [emitted] [immutable]" `; exports[`StatsTestCases should print correct stats for import-context-filter 1`] = ` -"asset entry.js 12 KiB [emitted] (name: entry) +"asset entry.js 11.9 KiB [emitted] (name: entry) asset 717.js 482 bytes [emitted] asset 776.js 482 bytes [emitted] asset 0.js 475 bytes [emitted] @@ -1394,7 +1394,7 @@ webpack x.x.x compiled successfully in X ms" exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = ` "1 chunks: - asset bundle1.js 4.85 KiB [emitted] (name: main) + asset bundle1.js 4.72 KiB [emitted] (name: main) chunk (runtime: main) bundle1.js (main) 219 bytes (javascript) 1.77 KiB (runtime) <{792}> >{792}< [entry] [rendered] runtime modules 1.77 KiB 4 modules cacheable modules 219 bytes @@ -1547,14 +1547,14 @@ webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for max-external-module-readable-identifier 1`] = ` -"asset main.js 1.45 KiB [emitted] (name: main) +"asset main.js 1.32 KiB [emitted] (name: main) ./index.js 17 bytes [built] [code generated] external \\"very-very-very-very-long-external-module-readable-identifier-it-should...(truncated) 42 bytes [built] [code generated] webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for max-modules 1`] = ` -"asset main.js 5.46 KiB [emitted] (name: main) +"asset main.js 5.34 KiB [emitted] (name: main) ./index.js 181 bytes [built] [code generated] ./a.js?1 33 bytes [built] [code generated] ./a.js?2 33 bytes [built] [code generated] @@ -1579,7 +1579,7 @@ webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for max-modules-default 1`] = ` -"asset main.js 5.46 KiB [emitted] (name: main) +"asset main.js 5.34 KiB [emitted] (name: main) ./index.js 181 bytes [built] [code generated] ./a.js?1 33 bytes [built] [code generated] ./a.js?2 33 bytes [built] [code generated] @@ -1630,9 +1630,9 @@ webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for module-deduplication 1`] = ` -"asset e2.js 12.2 KiB [emitted] (name: e2) -asset e3.js 12.2 KiB [emitted] (name: e3) -asset e1.js 12.2 KiB [emitted] (name: e1) +"asset e2.js 12.1 KiB [emitted] (name: e2) +asset e3.js 12.1 KiB [emitted] (name: e3) +asset e1.js 12.1 KiB [emitted] (name: e1) asset 471.js 856 bytes [emitted] asset 752.js 856 bytes [emitted] asset 637.js 854 bytes [emitted] @@ -1676,9 +1676,9 @@ webpack x.x.x compiled successfully" `; exports[`StatsTestCases should print correct stats for module-deduplication-named 1`] = ` -"asset e2.js 12.1 KiB [emitted] (name: e2) -asset e1.js 12.1 KiB [emitted] (name: e1) -asset e3.js 12.1 KiB [emitted] (name: e3) +"asset e2.js 12 KiB [emitted] (name: e2) +asset e1.js 12 KiB [emitted] (name: e1) +asset e3.js 12 KiB [emitted] (name: e3) asset async1.js 961 bytes [emitted] (name: async1) asset async2.js 961 bytes [emitted] (name: async2) asset async3.js 960 bytes [emitted] (name: async3) @@ -1765,7 +1765,7 @@ webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for module-trace-disabled-in-error 1`] = ` -"assets by status 2 KiB [cached] 1 asset +"assets by status 1.88 KiB [cached] 1 asset ./index.js 19 bytes [built] [code generated] ./inner.js 53 bytes [built] [code generated] ./not-existing.js 26 bytes [built] [code generated] @@ -1787,7 +1787,7 @@ webpack x.x.x compiled with 2 errors in X ms" `; exports[`StatsTestCases should print correct stats for module-trace-enabled-in-error 1`] = ` -"assets by status 2 KiB [cached] 1 asset +"assets by status 1.88 KiB [cached] 1 asset ./index.js 19 bytes [built] [code generated] ./inner.js 53 bytes [built] [code generated] ./not-existing.js 26 bytes [built] [code generated] @@ -1907,7 +1907,7 @@ webpack x.x.x compiled with 1 error and 1 warning in X ms" `; exports[`StatsTestCases should print correct stats for optimize-chunks 1`] = ` -"asset main.js 11.1 KiB {792} [emitted] (name: main) +"asset main.js 11 KiB {792} [emitted] (name: main) asset cir2 from cir1.js 377 bytes {816}, {915} [emitted] (name: cir2 from cir1) asset cir1.js 333 bytes {712} [emitted] (name: cir1) asset cir2.js 333 bytes {915} [emitted] (name: cir2) @@ -2106,9 +2106,9 @@ webpack x.x.x compiled with 2 errors in X ms" exports[`StatsTestCases should print correct stats for performance-no-async-chunks-shown 1`] = ` "asset main.js 294 KiB [emitted] [big] (name: main) -asset sec.js 1.53 KiB [emitted] (name: sec) +asset sec.js 1.41 KiB [emitted] (name: sec) Entrypoint main [big] 294 KiB = main.js -Entrypoint sec 1.53 KiB = sec.js +Entrypoint sec 1.41 KiB = sec.js ./index.js 32 bytes [built] [code generated] ./index2.js 48 bytes [built] [code generated] ./a.js 293 KiB [built] [code generated] @@ -2243,11 +2243,11 @@ exports[`StatsTestCases should print correct stats for preset-detailed 1`] = ` [LogTestPlugin] Log [LogTestPlugin] End PublicPath: auto -asset main.js 10.3 KiB {792} [emitted] (name: main) +asset main.js 10.2 KiB {792} [emitted] (name: main) asset 964.js 323 bytes {964} [emitted] asset 226.js 206 bytes {226} [emitted] asset 899.js 138 bytes {899} [emitted] -Entrypoint main 10.3 KiB = main.js +Entrypoint main 10.2 KiB = main.js chunk {226} (runtime: main) 226.js 44 bytes <{964}> [rendered] > [964] ./c.js 1:0-52 chunk {792} (runtime: main) main.js (main) 73 bytes (javascript) 6.05 KiB (runtime) >{899}< >{964}< [entry] [rendered] @@ -2421,7 +2421,7 @@ exports[`StatsTestCases should print correct stats for preset-normal 1`] = ` " [LogTestPlugin] Error [LogTestPlugin] Warning [LogTestPlugin] Info -asset main.js 10.3 KiB [emitted] (name: main) +asset main.js 10.2 KiB [emitted] (name: main) asset 964.js 323 bytes [emitted] asset 226.js 206 bytes [emitted] asset 899.js 138 bytes [emitted] @@ -2519,11 +2519,11 @@ exports[`StatsTestCases should print correct stats for preset-verbose 1`] = ` [LogTestPlugin] Log [LogTestPlugin] End PublicPath: auto -asset main.js 10.3 KiB {792} [emitted] (name: main) +asset main.js 10.2 KiB {792} [emitted] (name: main) asset 964.js 323 bytes {964} [emitted] asset 226.js 206 bytes {226} [emitted] asset 899.js 138 bytes {899} [emitted] -Entrypoint main 10.3 KiB = main.js +Entrypoint main 10.2 KiB = main.js chunk {226} (runtime: main) 226.js 44 bytes <{964}> [rendered] > [964] ./c.js 1:0-52 ./d.js [425] 22 bytes {226} [depth 2] [built] [code generated] @@ -2845,18 +2845,18 @@ b-source-map: exports[`StatsTestCases should print correct stats for related-assets 1`] = ` "default: - assets by path *.js 15.3 KiB - asset default-main.js 14.5 KiB [emitted] (name: main) 3 related assets + assets by path *.js 15.2 KiB + asset default-main.js 14.4 KiB [emitted] (name: main) 3 related assets asset default-chunk_js.js 803 bytes [emitted] 3 related assets assets by path *.css 142 bytes asset default-chunk_js.css 73 bytes [emitted] 3 related assets asset default-main.css 69 bytes [emitted] (name: main) 3 related assets relatedAssets: - assets by path *.js 15.3 KiB - asset relatedAssets-main.js 14.5 KiB [emitted] (name: main) - compressed relatedAssets-main.js.br 14.5 KiB [emitted] - compressed relatedAssets-main.js.gz 14.5 KiB [emitted] + assets by path *.js 15.2 KiB + asset relatedAssets-main.js 14.4 KiB [emitted] (name: main) + compressed relatedAssets-main.js.br 14.4 KiB [emitted] + compressed relatedAssets-main.js.gz 14.4 KiB [emitted] sourceMap relatedAssets-main.js.map 12.6 KiB [emitted] [dev] (auxiliary name: main) compressed relatedAssets-main.js.map.br 12.6 KiB [emitted] compressed relatedAssets-main.js.map.gz 12.6 KiB [emitted] @@ -2881,9 +2881,9 @@ relatedAssets: compressed relatedAssets-main.css.gz 75 bytes [emitted] exclude1: - assets by path *.js 15.3 KiB - asset exclude1-main.js 14.5 KiB [emitted] (name: main) - hidden assets 29.1 KiB 2 assets + assets by path *.js 15.2 KiB + asset exclude1-main.js 14.4 KiB [emitted] (name: main) + hidden assets 28.8 KiB 2 assets sourceMap exclude1-main.js.map 12.5 KiB [emitted] [dev] (auxiliary name: main) hidden assets 25.1 KiB 2 assets + 1 related asset @@ -2909,11 +2909,11 @@ exclude1: + 1 related asset exclude2: - assets by path *.js 15.3 KiB - asset exclude2-main.js 14.5 KiB [emitted] (name: main) + assets by path *.js 15.2 KiB + asset exclude2-main.js 14.4 KiB [emitted] (name: main) hidden assets 12.5 KiB 1 asset - compressed exclude2-main.js.br 14.5 KiB [emitted] - compressed exclude2-main.js.gz 14.5 KiB [emitted] + compressed exclude2-main.js.br 14.4 KiB [emitted] + compressed exclude2-main.js.gz 14.4 KiB [emitted] asset exclude2-chunk_js.js 804 bytes [emitted] hidden assets 295 bytes 1 asset compressed exclude2-chunk_js.js.br 804 bytes [emitted] @@ -2930,10 +2930,10 @@ exclude2: exclude3: hidden assets 878 bytes 2 assets - assets by status 14.6 KiB [emitted] - asset exclude3-main.js 14.5 KiB [emitted] (name: main) - compressed exclude3-main.js.br 14.5 KiB [emitted] - compressed exclude3-main.js.gz 14.5 KiB [emitted] + assets by status 14.5 KiB [emitted] + asset exclude3-main.js 14.4 KiB [emitted] (name: main) + compressed exclude3-main.js.br 14.4 KiB [emitted] + compressed exclude3-main.js.gz 14.4 KiB [emitted] sourceMap exclude3-main.js.map 12.5 KiB [emitted] [dev] (auxiliary name: main) compressed exclude3-main.js.map.br 12.5 KiB [emitted] compressed exclude3-main.js.map.gz 12.5 KiB [emitted] @@ -2946,7 +2946,7 @@ exclude3: `; exports[`StatsTestCases should print correct stats for resolve-plugin-context 1`] = ` -"asset bundle.js 1.67 KiB [emitted] (name: main) +"asset bundle.js 1.55 KiB [emitted] (name: main) modules by path ./node_modules/def/ 17 bytes ./node_modules/def/index.js 16 bytes [built] [code generated] ./node_modules/def/node_modules/xyz/index.js 1 bytes [built] [code generated] @@ -2957,7 +2957,7 @@ webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for reverse-sort-modules 1`] = ` -"asset main.js 5.46 KiB [emitted] (name: main) +"asset main.js 5.34 KiB [emitted] (name: main) ./index.js 181 bytes [built] [code generated] ./c.js?9 33 bytes [built] [code generated] ./c.js?8 33 bytes [built] [code generated] @@ -3066,8 +3066,8 @@ webpack x.x.x compiled successfully" exports[`StatsTestCases should print correct stats for runtime-specific-used-exports 1`] = ` "production: - asset production-a.js 13.2 KiB [emitted] (name: a) - asset production-b.js 13.2 KiB [emitted] (name: b) + asset production-a.js 13.1 KiB [emitted] (name: a) + asset production-b.js 13.1 KiB [emitted] (name: b) asset production-dw_js-_a6170.js 1.15 KiB [emitted] asset production-dw_js-_a6171.js 1.15 KiB [emitted] asset production-dx_js.js 1.15 KiB [emitted] @@ -3233,8 +3233,8 @@ development: development (webpack x.x.x) compiled successfully in X ms global: - asset global-a.js 13.4 KiB [emitted] (name: a) - asset global-b.js 13.4 KiB [emitted] (name: b) + asset global-a.js 13.3 KiB [emitted] (name: a) + asset global-b.js 13.3 KiB [emitted] (name: b) asset global-dw_js.js 1.15 KiB [emitted] asset global-dx_js.js 1.15 KiB [emitted] asset global-dy_js.js 1.15 KiB [emitted] @@ -3391,7 +3391,7 @@ webpack x.x.x compiled successfully in X ms" `; exports[`StatsTestCases should print correct stats for side-effects-issue-7428 1`] = ` -"asset main.js 12.4 KiB [emitted] (name: main) +"asset main.js 12.2 KiB [emitted] (name: main) asset 1.js 643 bytes [emitted] runtime modules 6.62 KiB 9 modules cacheable modules 823 bytes @@ -3569,9 +3569,9 @@ webpack x.x.x compiled successfully in X ms" exports[`StatsTestCases should print correct stats for split-chunks 1`] = ` "default: Entrypoint main 11.5 KiB = default/main.js - Entrypoint a 12.6 KiB = default/a.js - Entrypoint b 3.93 KiB = default/b.js - Entrypoint c 3.93 KiB = default/c.js + Entrypoint a 12.5 KiB = default/a.js + Entrypoint b 3.81 KiB = default/b.js + Entrypoint c 3.81 KiB = default/c.js chunk (runtime: a, main) default/async-g.js (async-g) 45 bytes <{263}> <{425}> <{628}> <{723}> <{996}> ={935}= [rendered] > ./g ./a.js 6:0-47 ./g.js 45 bytes [built] [code generated] @@ -3843,7 +3843,7 @@ name-too-long: custom-chunks-filter: Entrypoint main 11.5 KiB = custom-chunks-filter/main.js - Entrypoint a 12.6 KiB = custom-chunks-filter/a.js + Entrypoint a 12.5 KiB = custom-chunks-filter/a.js Entrypoint b 8.13 KiB = custom-chunks-filter/628.js 412 bytes custom-chunks-filter/723.js 412 bytes custom-chunks-filter/935.js 412 bytes custom-chunks-filter/425.js 412 bytes custom-chunks-filter/b.js 6.52 KiB Entrypoint c 8.13 KiB = custom-chunks-filter/628.js 412 bytes custom-chunks-filter/862.js 412 bytes custom-chunks-filter/935.js 412 bytes custom-chunks-filter/425.js 412 bytes custom-chunks-filter/c.js 6.52 KiB chunk (runtime: a, main) custom-chunks-filter/async-g.js (async-g) 45 bytes <{263}> <{425}> <{628}> <{723}> <{996}> ={935}= [rendered] diff --git a/test/configCases/output-module/inlined-moudle/index.js b/test/configCases/output-module/inlined-moudle/index.js new file mode 100644 index 00000000000..d528599c4d3 --- /dev/null +++ b/test/configCases/output-module/inlined-moudle/index.js @@ -0,0 +1,18 @@ +import { value as v1 } from "./module1"; +const v2 = require("./module2") +const module3Inc = require("./module3") + +var value = 42; + +function inc() { + value++; +} + +it("single inlined module should not be wrapped in IIFE", () => { + expect(value).toBe(42); + expect(v1).toBe(undefined); + expect(v2).toBe(undefined); + expect(module3Inc).toBe(undefined); + inc(); + expect(value).toBe(43); +}); diff --git a/test/configCases/output-module/inlined-moudle/module1.js b/test/configCases/output-module/inlined-moudle/module1.js new file mode 100644 index 00000000000..67ebbe022de --- /dev/null +++ b/test/configCases/output-module/inlined-moudle/module1.js @@ -0,0 +1,3 @@ +let value; + +export { value }; diff --git a/test/configCases/output-module/inlined-moudle/module2.js b/test/configCases/output-module/inlined-moudle/module2.js new file mode 100644 index 00000000000..3e533c777ea --- /dev/null +++ b/test/configCases/output-module/inlined-moudle/module2.js @@ -0,0 +1,3 @@ +let value + +module.exports = value diff --git a/test/configCases/output-module/inlined-moudle/module3.js b/test/configCases/output-module/inlined-moudle/module3.js new file mode 100644 index 00000000000..5b457b1be85 --- /dev/null +++ b/test/configCases/output-module/inlined-moudle/module3.js @@ -0,0 +1,3 @@ +let inc + +module.exports = inc diff --git a/test/configCases/output-module/inlined-moudle/webpack.config.js b/test/configCases/output-module/inlined-moudle/webpack.config.js new file mode 100644 index 00000000000..61f4abca976 --- /dev/null +++ b/test/configCases/output-module/inlined-moudle/webpack.config.js @@ -0,0 +1,13 @@ +/** @type {import("../../../../").Configuration} */ +module.exports = { + output: { + module: true + }, + optimization: { + concatenateModules: true + }, + experiments: { + outputModule: true + }, + target: "es2020" +}; diff --git a/types.d.ts b/types.d.ts index 769cd056294..39223778a1a 100644 --- a/types.d.ts +++ b/types.d.ts @@ -5529,6 +5529,18 @@ declare class JavascriptModulesPlugin { renderContext: RenderBootstrapContext, hooks: CompilationHooksJavascriptModulesPlugin ): string; + renamedRootModule( + allModules: Module[], + renderContext: MainRenderContext, + inlinedModules: Set, + chunkRenderContext: ChunkRenderContext, + hooks: CompilationHooksJavascriptModulesPlugin + ): Map; + findNewName( + oldName: string, + usedName: Set, + extraInfo: string + ): string; static getCompilationHooks( compilation: Compilation ): CompilationHooksJavascriptModulesPlugin;