From a4ac8f0328654cd7cdaaa30cfeb7cc5dbc49e3ec Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 10 Jun 2020 13:31:01 +0200 Subject: [PATCH] Cleanup --- lib/ContextModule.js | 23 ++++++-- lib/ContextModuleFactory.js | 27 +++++++--- lib/Dependency.js | 8 ++- lib/FlagDependencyUsagePlugin.js | 25 +++++---- lib/dependencies/ContextElementDependency.js | 31 ++++++++++- lib/dependencies/ImportDependenciesBlock.js | 45 ---------------- lib/dependencies/ImportDependency.js | 31 +++++++++-- lib/dependencies/ImportEagerDependency.js | 27 ++++------ lib/dependencies/ImportParserPlugin.js | 30 ++++------- lib/dependencies/ImportWeakDependency.js | 27 ++++------ lib/optimize/ModuleConcatenationPlugin.js | 4 +- lib/util/internalSerializables.js | 2 - lib/wasm/WasmFinalizeExportsPlugin.js | 3 +- test/cases/chunks/inline-options/dir12/a.js | 10 ++-- test/cases/chunks/inline-options/dir12/c.js | 5 -- test/cases/chunks/inline-options/dir12/d.js | 5 -- test/cases/chunks/inline-options/dir12/e.js | 5 -- test/cases/chunks/inline-options/dir12/f.js | 5 -- test/cases/chunks/inline-options/dir12/g.js | 5 -- test/cases/chunks/inline-options/dir13/a.js | 7 +++ .../inline-options/{dir12 => dir13}/b.js | 2 + test/cases/chunks/inline-options/index.js | 52 +++++++++---------- .../webpack.config.js | 9 +++- .../remove-export/webpack.config.js | 9 +++- types.d.ts | 42 ++++++++++++--- 25 files changed, 235 insertions(+), 204 deletions(-) delete mode 100644 lib/dependencies/ImportDependenciesBlock.js delete mode 100644 test/cases/chunks/inline-options/dir12/c.js delete mode 100644 test/cases/chunks/inline-options/dir12/d.js delete mode 100644 test/cases/chunks/inline-options/dir12/e.js delete mode 100644 test/cases/chunks/inline-options/dir12/f.js delete mode 100644 test/cases/chunks/inline-options/dir12/g.js create mode 100644 test/cases/chunks/inline-options/dir13/a.js rename test/cases/chunks/inline-options/{dir12 => dir13}/b.js (52%) diff --git a/lib/ContextModule.js b/lib/ContextModule.js index 1ad85cc2d..66526cc86 100644 --- a/lib/ContextModule.js +++ b/lib/ContextModule.js @@ -52,6 +52,7 @@ const makeSerializable = require("./util/makeSerializable"); * @property {RegExp=} include * @property {RegExp=} exclude * @property {RawChunkGroupOptions=} groupOptions + * @property {string[][]=} referencedExports exports referenced from modules (won't be mangled) */ /** @@ -66,13 +67,13 @@ const makeSerializable = require("./util/makeSerializable"); /** * @callback ResolveDependenciesCallback * @param {Error=} err - * @param {ContextElementDependency[]} dependencies + * @param {ContextElementDependency[]=} dependencies */ /** * @callback ResolveDependencies - * @param {TODO} fs - * @param {TODO} options + * @param {InputFileSystem} fs + * @param {ContextModuleOptions} options * @param {ResolveDependenciesCallback} callback */ @@ -116,6 +117,7 @@ class ContextModule extends Module { exclude: options.exclude, chunkName: options.chunkName, groupOptions: options.groupOptions, + referencedExports: options.referencedExports, namespaceObject: options.namespaceObject }; if (options.resolveOptions !== undefined) { @@ -183,6 +185,11 @@ class ContextModule extends Module { if (this.options.exclude) { identifier += `|exclude: ${this.options.exclude}`; } + if (this.options.referencedExports) { + identifier += `|referencedExports: ${JSON.stringify( + this.options.referencedExports + )}`; + } if (this.options.chunkName) { identifier += `|chunkName: ${this.options.chunkName}`; } @@ -234,6 +241,11 @@ class ContextModule extends Module { if (this.options.exclude) { identifier += ` exclude: ${this.prettyRegExp(this.options.exclude + "")}`; } + if (this.options.referencedExports) { + identifier += ` referencedExports: ${this.options.referencedExports + .map(e => e.join(".")) + .join(", ")}`; + } if (this.options.chunkName) { identifier += ` chunkName: ${this.options.chunkName}`; } @@ -284,6 +296,11 @@ class ContextModule extends Module { if (this.options.exclude) { identifier += ` exclude: ${this.prettyRegExp(this.options.exclude + "")}`; } + if (this.options.referencedExports) { + identifier += ` referencedExports: ${this.options.referencedExports + .map(e => e.join(".")) + .join(", ")}`; + } return identifier; } diff --git a/lib/ContextModuleFactory.js b/lib/ContextModuleFactory.js index a71a79f93..ee1e9a243 100644 --- a/lib/ContextModuleFactory.js +++ b/lib/ContextModuleFactory.js @@ -12,10 +12,13 @@ const ModuleFactory = require("./ModuleFactory"); const ContextElementDependency = require("./dependencies/ContextElementDependency"); const { join } = require("./util/fs"); +/** @typedef {import("./ContextModule").ContextModuleOptions} ContextModuleOptions */ +/** @typedef {import("./ContextModule").ResolveDependenciesCallback} ResolveDependenciesCallback */ /** @typedef {import("./Module")} Module */ /** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */ /** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */ /** @typedef {import("./dependencies/ContextDependency")} ContextDependency */ +/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */ const EMPTY_RESOLVE_OPTIONS = {}; @@ -210,14 +213,23 @@ module.exports = class ContextModuleFactory extends ModuleFactory { ); } + /** + * @param {InputFileSystem} fs file system + * @param {ContextModuleOptions} options options + * @param {ResolveDependenciesCallback} callback callback function + * @returns {void} + */ resolveDependencies(fs, options, callback) { const cmf = this; - let resource = options.resource; - let resourceQuery = options.resourceQuery; - let recursive = options.recursive; - let regExp = options.regExp; - let include = options.include; - let exclude = options.exclude; + const { + resource, + resourceQuery, + recursive, + regExp, + include, + exclude, + referencedExports + } = options; if (!regExp || !resource) return callback(null, []); const addDirectory = (directory, callback) => { @@ -266,7 +278,8 @@ module.exports = class ContextModuleFactory extends ModuleFactory { .map(obj => { const dep = new ContextElementDependency( obj.request + resourceQuery, - obj.request + obj.request, + referencedExports ); dep.optional = true; return dep; diff --git a/lib/Dependency.js b/lib/Dependency.js index 896521ac2..0acdad615 100644 --- a/lib/Dependency.js +++ b/lib/Dependency.js @@ -53,13 +53,11 @@ */ /** - * @typedef {Object} ReferencedExportItem - * @property {string} name name of the referenced export - * @property {boolean=} canMangle when true, referenced export can be mangled + * @typedef {Object} ReferencedExport + * @property {string[]} name name of the referenced export + * @property {boolean=} canMangle when false, referenced export can not be mangled, defaults to true */ -/** @typedef {ReferencedExportItem[]} ReferencedExport */ - class Dependency { constructor() { // TODO check if this can be moved into ModuleDependency diff --git a/lib/FlagDependencyUsagePlugin.js b/lib/FlagDependencyUsagePlugin.js index 315ec905d..8a66b8902 100644 --- a/lib/FlagDependencyUsagePlugin.js +++ b/lib/FlagDependencyUsagePlugin.js @@ -47,7 +47,15 @@ class FlagDependencyUsagePlugin { const processModule = (module, usedExports) => { const exportsInfo = moduleGraph.getExportsInfo(module); if (usedExports.length > 0) { - for (let usedExport of usedExports) { + for (const usedExportInfo of usedExports) { + let usedExport; + let canMangle = true; + if (Array.isArray(usedExportInfo)) { + usedExport = usedExportInfo; + } else { + usedExport = usedExportInfo.name; + canMangle = usedExportInfo.canMangle !== false; + } if (usedExport.length === 0) { if (exportsInfo.setUsedInUnknownWay()) { queue.enqueue(module); @@ -55,16 +63,11 @@ class FlagDependencyUsagePlugin { } else { let currentExportsInfo = exportsInfo; for (let i = 0; i < usedExport.length; i++) { - const exportItem = usedExport[i]; - let exportInfo; - if (typeof exportItem === "object") { - exportInfo = currentExportsInfo.getExportInfo( - exportItem.name - ); - if (exportItem.canMangle === false) - exportInfo.canMangleUse = false; - } else { - exportInfo = currentExportsInfo.getExportInfo(exportItem); + const exportInfo = currentExportsInfo.getExportInfo( + usedExport[i] + ); + if (canMangle === false) { + exportInfo.canMangleUse = false; } const lastOne = i === usedExport.length - 1; if (!lastOne) { diff --git a/lib/dependencies/ContextElementDependency.js b/lib/dependencies/ContextElementDependency.js index a78579e52..820b6dea7 100644 --- a/lib/dependencies/ContextElementDependency.js +++ b/lib/dependencies/ContextElementDependency.js @@ -5,12 +5,17 @@ "use strict"; +const Dependency = require("../Dependency"); const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ + class ContextElementDependency extends ModuleDependency { - constructor(request, userRequest) { + constructor(request, userRequest, referencedExports) { super(request); + this.referencedExports = referencedExports; if (userRequest) { this.userRequest = userRequest; @@ -20,6 +25,30 @@ class ContextElementDependency extends ModuleDependency { get type() { return "context element"; } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph) { + return this.referencedExports + ? this.referencedExports.map(e => ({ + name: e, + canMangle: false + })) + : Dependency.EXPORTS_OBJECT_REFERENCED; + } + + serialize(context) { + context.write(this.referencedExports); + super.serialize(context); + } + + deserialize(context) { + this.referencedExports = context.read(); + super.deserialize(context); + } } makeSerializable( diff --git a/lib/dependencies/ImportDependenciesBlock.js b/lib/dependencies/ImportDependenciesBlock.js deleted file mode 100644 index 891b92af8..000000000 --- a/lib/dependencies/ImportDependenciesBlock.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ - -"use strict"; - -const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); -const makeSerializable = require("../util/makeSerializable"); - -/** @typedef {import("../ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */ -/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ - -class ImportDependenciesBlock extends AsyncDependenciesBlock { - /** - * @param {ChunkGroupOptions} groupOptions options for the chunk group - * @param {DependencyLocation} loc location info - * @param {string} request request string for the block - * @param {[number, number]} range position of the block - */ - constructor(groupOptions, loc, request, range) { - super(groupOptions, loc, request); - /** @type {[number, number]} */ - this.range = range; - } - - serialize(context) { - const { write } = context; - write(this.range); - super.serialize(context); - } - - deserialize(context) { - const { read } = context; - this.range = read(); - super.deserialize(context); - } -} - -makeSerializable( - ImportDependenciesBlock, - "webpack/lib/dependencies/ImportDependenciesBlock" -); - -module.exports = ImportDependenciesBlock; diff --git a/lib/dependencies/ImportDependency.js b/lib/dependencies/ImportDependency.js index 12fe10e61..00c746bd3 100644 --- a/lib/dependencies/ImportDependency.js +++ b/lib/dependencies/ImportDependency.js @@ -10,15 +10,21 @@ const makeSerializable = require("../util/makeSerializable"); const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */ /** @typedef {import("../Dependency")} Dependency */ /** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ -/** @typedef {import("../dependencies/ImportDependenciesBlock")} ImportDependenciesBlock */ class ImportDependency extends ModuleDependency { - constructor(request, referencedExports) { + /** + * @param {string} request the request + * @param {[number, number]} range expression range + * @param {string[][]=} referencedExports list of referenced exports + */ + constructor(request, range, referencedExports) { super(request); + this.range = range; this.referencedExports = referencedExports; } @@ -33,9 +39,24 @@ class ImportDependency extends ModuleDependency { */ getReferencedExports(moduleGraph) { return this.referencedExports - ? this.referencedExports + ? this.referencedExports.map(e => ({ + name: e, + canMangle: false + })) : Dependency.EXPORTS_OBJECT_REFERENCED; } + + serialize(context) { + context.write(this.range); + context.write(this.referencedExports); + super.serialize(context); + } + + deserialize(context) { + this.range = context.read(); + this.referencedExports = context.read(); + super.deserialize(context); + } } makeSerializable(ImportDependency, "webpack/lib/dependencies/ImportDependency"); @@ -53,7 +74,7 @@ ImportDependency.Template = class ImportDependencyTemplate extends ModuleDepende { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements } ) { const dep = /** @type {ImportDependency} */ (dependency); - const block = /** @type {ImportDependenciesBlock} */ (moduleGraph.getParentBlock( + const block = /** @type {AsyncDependenciesBlock} */ (moduleGraph.getParentBlock( dep )); const content = runtimeTemplate.moduleNamespacePromise({ @@ -66,7 +87,7 @@ ImportDependency.Template = class ImportDependencyTemplate extends ModuleDepende runtimeRequirements }); - source.replace(block.range[0], block.range[1] - 1, content); + source.replace(dep.range[0], dep.range[1] - 1, content); } }; diff --git a/lib/dependencies/ImportEagerDependency.js b/lib/dependencies/ImportEagerDependency.js index cf2da75d0..754a31dbc 100644 --- a/lib/dependencies/ImportEagerDependency.js +++ b/lib/dependencies/ImportEagerDependency.js @@ -5,9 +5,8 @@ "use strict"; -const Dependency = require("../Dependency"); const makeSerializable = require("../util/makeSerializable"); -const ModuleDependency = require("./ModuleDependency"); +const ImportDependency = require("./ImportDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ @@ -15,27 +14,19 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ -class ImportEagerDependency extends ModuleDependency { +class ImportEagerDependency extends ImportDependency { + /** + * @param {string} request the request + * @param {[number, number]} range expression range + * @param {string[][]=} referencedExports list of referenced exports + */ constructor(request, range, referencedExports) { - super(request); - this.referencedExports = referencedExports; - this.range = range; + super(request, range, referencedExports); } get type() { return "import() eager"; } - - /** - * Returns list of exports referenced by this dependency - * @param {ModuleGraph} moduleGraph module graph - * @returns {(string[] | ReferencedExport)[]} referenced exports - */ - getReferencedExports(moduleGraph) { - return this.referencedExports - ? this.referencedExports - : Dependency.EXPORTS_OBJECT_REFERENCED; - } } makeSerializable( @@ -43,7 +34,7 @@ makeSerializable( "webpack/lib/dependencies/ImportEagerDependency" ); -ImportEagerDependency.Template = class ImportEagerDependencyTemplate extends ModuleDependency.Template { +ImportEagerDependency.Template = class ImportEagerDependencyTemplate extends ImportDependency.Template { /** * @param {Dependency} dependency the dependency for which the template should be applied * @param {ReplaceSource} source the current replace source which can be modified diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index 1cfff57c6..5c4245cdb 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -5,11 +5,11 @@ "use strict"; +const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); const CommentCompilationWarning = require("../CommentCompilationWarning"); const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); const ContextDependencyHelpers = require("./ContextDependencyHelpers"); const ImportContextDependency = require("./ImportContextDependency"); -const ImportDependenciesBlock = require("./ImportDependenciesBlock"); const ImportDependency = require("./ImportDependency"); const ImportEagerDependency = require("./ImportEagerDependency"); const ImportWeakDependency = require("./ImportWeakDependency"); @@ -31,6 +31,7 @@ class ImportParserPlugin { let mode = "lazy"; let include = null; let exclude = null; + /** @type {string[][] | null} */ let exports = null; /** @type {RawChunkGroupOptions} */ const groupOptions = {}; @@ -167,23 +168,10 @@ class ImportParserPlugin { ) ); } else { - // Convert export names to be of type Object[] with name and other properties: if (typeof importOptions.webpackExports === "string") { - exports = [ - [ - { - name: importOptions.webpackExports, - canMangle: false - } - ] - ]; + exports = [[importOptions.webpackExports]]; } else { - exports = importOptions.webpackExports.map(exp => [ - { - name: exp, - canMangle: false - } - ]); + exports = Array.from(importOptions.webpackExports, e => [e]); } } } @@ -214,16 +202,15 @@ class ImportParserPlugin { ); parser.state.current.addDependency(dep); } else { - const depBlock = new ImportDependenciesBlock( + const depBlock = new AsyncDependenciesBlock( { ...groupOptions, name: chunkName }, expr.loc, - param.string, - expr.range + param.string ); - const dep = new ImportDependency(param.string, exports); + const dep = new ImportDependency(param.string, expr.range, exports); dep.loc = expr.loc; depBlock.addDependency(dep); parser.state.current.addBlock(depBlock); @@ -262,7 +249,8 @@ class ImportParserPlugin { mode, namespaceObject: parser.state.module.buildMeta.strictHarmonyModule ? "strict" - : true + : true, + referencedExports: exports }, parser ); diff --git a/lib/dependencies/ImportWeakDependency.js b/lib/dependencies/ImportWeakDependency.js index 2e930c2ca..22fe5d2b0 100644 --- a/lib/dependencies/ImportWeakDependency.js +++ b/lib/dependencies/ImportWeakDependency.js @@ -5,9 +5,8 @@ "use strict"; -const Dependency = require("../Dependency"); const makeSerializable = require("../util/makeSerializable"); -const ModuleDependency = require("./ModuleDependency"); +const ImportDependency = require("./ImportDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ /** @typedef {import("../Dependency")} Dependency */ @@ -15,28 +14,20 @@ const ModuleDependency = require("./ModuleDependency"); /** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ /** @typedef {import("../ModuleGraph")} ModuleGraph */ -class ImportWeakDependency extends ModuleDependency { +class ImportWeakDependency extends ImportDependency { + /** + * @param {string} request the request + * @param {[number, number]} range expression range + * @param {string[][]=} referencedExports list of referenced exports + */ constructor(request, range, referencedExports) { - super(request); - this.referencedExports = referencedExports; - this.range = range; + super(request, range, referencedExports); this.weak = true; } get type() { return "import() weak"; } - - /** - * Returns list of exports referenced by this dependency - * @param {ModuleGraph} moduleGraph module graph - * @returns {(string[] | ReferencedExport)[]} referenced exports - */ - getReferencedExports(moduleGraph) { - return this.referencedExports - ? this.referencedExports - : Dependency.EXPORTS_OBJECT_REFERENCED; - } } makeSerializable( @@ -44,7 +35,7 @@ makeSerializable( "webpack/lib/dependencies/ImportWeakDependency" ); -ImportWeakDependency.Template = class ImportDependencyTemplate extends ModuleDependency.Template { +ImportWeakDependency.Template = class ImportDependencyTemplate extends ImportDependency.Template { /** * @param {Dependency} dependency the dependency for which the template should be applied * @param {ReplaceSource} source the current replace source which can be modified diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 36180c098..d1cfc7b1e 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -485,7 +485,9 @@ class ModuleConcatenationPlugin { const importedNames = compilation.getDependencyReferencedExports(dep); if ( - importedNames.every(i => i.length > 0) || + importedNames.every(i => + Array.isArray(i) ? i.length > 0 : i.name.length > 0 + ) || Array.isArray(moduleGraph.getProvidedExports(module)) ) { set.add(connection.module); diff --git a/lib/util/internalSerializables.js b/lib/util/internalSerializables.js index 58f2b3112..5053ab902 100644 --- a/lib/util/internalSerializables.js +++ b/lib/util/internalSerializables.js @@ -92,8 +92,6 @@ module.exports = { require("../dependencies/HarmonyImportSpecifierDependency"), "dependencies/ImportContextDependency": () => require("../dependencies/ImportContextDependency"), - "dependencies/ImportDependenciesBlock": () => - require("../dependencies/ImportDependenciesBlock"), "dependencies/ImportDependency": () => require("../dependencies/ImportDependency"), "dependencies/ImportEagerDependency": () => diff --git a/lib/wasm/WasmFinalizeExportsPlugin.js b/lib/wasm/WasmFinalizeExportsPlugin.js index 91af6e7f3..aa9d516c3 100644 --- a/lib/wasm/WasmFinalizeExportsPlugin.js +++ b/lib/wasm/WasmFinalizeExportsPlugin.js @@ -44,7 +44,8 @@ class WasmFinalizeExportsPlugin { connection.dependency ); - for (const names of referencedExports) { + for (const info of referencedExports) { + const names = Array.isArray(info) ? info : info.name; if (names.length === 0) continue; const name = names[0]; if (typeof name === "object") continue; diff --git a/test/cases/chunks/inline-options/dir12/a.js b/test/cases/chunks/inline-options/dir12/a.js index 21e2fd6d5..880c38a19 100644 --- a/test/cases/chunks/inline-options/dir12/a.js +++ b/test/cases/chunks/inline-options/dir12/a.js @@ -1,5 +1,9 @@ -export const a = "a"; +export const c = "c"; -export const b = "b"; +export const d = "d"; -export default "default"; +export const longnameforexport = "longnameforexport"; + +export default "default2"; + +export const usedExports = __webpack_exports_info__.usedExports; diff --git a/test/cases/chunks/inline-options/dir12/c.js b/test/cases/chunks/inline-options/dir12/c.js deleted file mode 100644 index 21e2fd6d5..000000000 --- a/test/cases/chunks/inline-options/dir12/c.js +++ /dev/null @@ -1,5 +0,0 @@ -export const a = "a"; - -export const b = "b"; - -export default "default"; diff --git a/test/cases/chunks/inline-options/dir12/d.js b/test/cases/chunks/inline-options/dir12/d.js deleted file mode 100644 index 21e2fd6d5..000000000 --- a/test/cases/chunks/inline-options/dir12/d.js +++ /dev/null @@ -1,5 +0,0 @@ -export const a = "a"; - -export const b = "b"; - -export default "default"; diff --git a/test/cases/chunks/inline-options/dir12/e.js b/test/cases/chunks/inline-options/dir12/e.js deleted file mode 100644 index 661628847..000000000 --- a/test/cases/chunks/inline-options/dir12/e.js +++ /dev/null @@ -1,5 +0,0 @@ -export const a = "a"; - -export const longnameforexport = "longnameforexport"; - -export default "default"; diff --git a/test/cases/chunks/inline-options/dir12/f.js b/test/cases/chunks/inline-options/dir12/f.js deleted file mode 100644 index 21e2fd6d5..000000000 --- a/test/cases/chunks/inline-options/dir12/f.js +++ /dev/null @@ -1,5 +0,0 @@ -export const a = "a"; - -export const b = "b"; - -export default "default"; diff --git a/test/cases/chunks/inline-options/dir12/g.js b/test/cases/chunks/inline-options/dir12/g.js deleted file mode 100644 index 21e2fd6d5..000000000 --- a/test/cases/chunks/inline-options/dir12/g.js +++ /dev/null @@ -1,5 +0,0 @@ -export const a = "a"; - -export const b = "b"; - -export default "default"; diff --git a/test/cases/chunks/inline-options/dir13/a.js b/test/cases/chunks/inline-options/dir13/a.js new file mode 100644 index 000000000..fbeecbd20 --- /dev/null +++ b/test/cases/chunks/inline-options/dir13/a.js @@ -0,0 +1,7 @@ +export const c = "c"; + +export const d = "d"; + +export default "default2"; + +export const usedExports = __webpack_exports_info__.usedExports; diff --git a/test/cases/chunks/inline-options/dir12/b.js b/test/cases/chunks/inline-options/dir13/b.js similarity index 52% rename from test/cases/chunks/inline-options/dir12/b.js rename to test/cases/chunks/inline-options/dir13/b.js index 21e2fd6d5..b73c5a615 100644 --- a/test/cases/chunks/inline-options/dir12/b.js +++ b/test/cases/chunks/inline-options/dir13/b.js @@ -3,3 +3,5 @@ export const a = "a"; export const b = "b"; export default "default"; + +export const usedExports = __webpack_exports_info__.usedExports; diff --git a/test/cases/chunks/inline-options/index.js b/test/cases/chunks/inline-options/index.js index c1887e6ed..acf02f708 100644 --- a/test/cases/chunks/inline-options/index.js +++ b/test/cases/chunks/inline-options/index.js @@ -117,18 +117,18 @@ it("should not find module when mode is weak and chunk not served elsewhere (wit }); it("should contain only one export from webpackExports from module", function () { - return import(/* webpackExports: "a" */ "./dir12/a").then(module => { - expect(module).toHaveProperty("a"); - expect(module).not.toHaveProperty("b"); - expect(module).not.toHaveProperty("default"); - }); + return import(/* webpackExports: "usedExports" */ "./dir12/a?1").then( + module => { + expect(module.usedExports).toEqual(["usedExports"]); + } + ); }); it("should contain only webpackExports from module", function () { - return import(/* webpackExports: ["a", "b"] */ "./dir12/b").then(module => { - expect(module).toHaveProperty("a"); - expect(module).toHaveProperty("b"); - expect(module).not.toHaveProperty("default"); + return import( + /* webpackExports: ["a", "usedExports", "b"] */ "./dir12/a?2" + ).then(module => { + expect(module.usedExports).toEqual(["a", "b", "usedExports"]); }); }); @@ -136,30 +136,27 @@ it("should contain only webpackExports from module in eager mode", function () { return import( /* webpackMode: "eager", - webpackExports: ["a", "b"] - */ "./dir12/c" + webpackExports: ["a", "usedExports", "b"] + */ "./dir12/a?3" ).then(module => { - expect(module).toHaveProperty("a"); - expect(module).toHaveProperty("b"); - expect(module).not.toHaveProperty("default"); + expect(module.usedExports).toEqual(["a", "b", "usedExports"]); }); }); it("should contain webpackExports from module in weak mode", function () { - require("./dir12/d"); + require.resolve("./dir12/a?4"); return import( /* webpackMode: "weak", - webpackExports: ["a", "b"] - */ "./dir12/d" + webpackExports: ["a", "usedExports", "b"] + */ "./dir12/a?4" ).then(module => { - expect(module).toHaveProperty("a"); - expect(module).toHaveProperty("b"); + expect(module.usedExports).toEqual(["a", "b", "usedExports"]); }); }); it("should not mangle webpackExports from module", function () { - return import(/* webpackExports: "longnameforexport" */ "./dir12/e").then( + return import(/* webpackExports: "longnameforexport" */ "./dir12/a?5").then( module => { expect(module).toHaveProperty("longnameforexport"); } @@ -167,17 +164,18 @@ it("should not mangle webpackExports from module", function () { }); it("should not mangle default webpackExports from module", function () { - return import(/* webpackExports: "default" */ "./dir12/f").then(module => { + return import(/* webpackExports: "default" */ "./dir12/a?6").then(module => { expect(module).toHaveProperty("default"); }); }); -it("should contain only default from webpackExports from module", function () { - return import(/* webpackExports: "default" */ "./dir12/g").then(module => { - expect(module).not.toHaveProperty("a"); - expect(module).not.toHaveProperty("b"); - expect(module).toHaveProperty("default"); - }); +it("should contain only webpackExports from module in context mode", function () { + const x = "b"; + return import(/* webpackExports: "usedExports" */ `./dir13/${x}`).then( + module => { + expect(module.usedExports).toEqual(["usedExports"]); + } + ); }); function testChunkLoading(load, expectedSyncInitial, expectedSyncRequested) { diff --git a/test/configCases/deep-scope-analysis/remove-export-scope-hoisting/webpack.config.js b/test/configCases/deep-scope-analysis/remove-export-scope-hoisting/webpack.config.js index 8d73a4314..c15fa93cc 100644 --- a/test/configCases/deep-scope-analysis/remove-export-scope-hoisting/webpack.config.js +++ b/test/configCases/deep-scope-analysis/remove-export-scope-hoisting/webpack.config.js @@ -26,11 +26,16 @@ module.exports = { refModule && refModule.identifier().endsWith("reference.js") && referencedExports.some( - names => names.length === 1 && names[0] === "unused" + names => + Array.isArray(names) && + names.length === 1 && + names[0] === "unused" ) ) { return referencedExports.filter( - names => names.length !== 1 || names[0] !== "unused" + names => + (Array.isArray(names) && names.length !== 1) || + names[0] !== "unused" ); } return referencedExports; diff --git a/test/configCases/deep-scope-analysis/remove-export/webpack.config.js b/test/configCases/deep-scope-analysis/remove-export/webpack.config.js index 13509d7e8..457f57d5d 100644 --- a/test/configCases/deep-scope-analysis/remove-export/webpack.config.js +++ b/test/configCases/deep-scope-analysis/remove-export/webpack.config.js @@ -20,11 +20,16 @@ module.exports = { refModule && refModule.identifier().endsWith("reference.js") && referencedExports.some( - names => names.length === 1 && names[0] === "unused" + names => + Array.isArray(names) && + names.length === 1 && + names[0] === "unused" ) ) { return referencedExports.filter( - names => names.length !== 1 || names[0] !== "unused" + names => + (Array.isArray(names) && names.length !== 1) || + names[0] !== "unused" ); } return referencedExports; diff --git a/types.d.ts b/types.d.ts index dd89615f2..f8467a565 100644 --- a/types.d.ts +++ b/types.d.ts @@ -888,7 +888,7 @@ declare class Compilation { void >; dependencyReferencedExports: SyncWaterfallHook< - [(string[] | ReferencedExportItem[])[], Dependency] + [(string[] | ReferencedExport)[], Dependency] >; finishModules: AsyncSeriesHook<[Iterable]>; finishRebuildingModule: AsyncSeriesHook<[Module]>; @@ -1141,7 +1141,7 @@ declare class Compilation { assignDepth(module: Module): void; getDependencyReferencedExports( dependency: Dependency - ): (string[] | ReferencedExportItem[])[]; + ): (string[] | ReferencedExport)[]; removeReasonsOfDependencyBlock( module: Module, block: DependenciesBlockLike @@ -1593,6 +1593,9 @@ declare interface ContainerReferencePluginOptions { */ remotes: Remotes; } +declare abstract class ContextElementDependency extends ModuleDependency { + referencedExports: any; +} declare class ContextExclusionPlugin { constructor(negativeMatcher: RegExp); negativeMatcher: RegExp; @@ -1610,7 +1613,28 @@ declare abstract class ContextModuleFactory extends ModuleFactory { alternatives: AsyncSeriesWaterfallHook<[any[]]>; }>; resolverFactory: any; - resolveDependencies(fs?: any, options?: any, callback?: any): any; + resolveDependencies( + fs: InputFileSystem, + options: { + mode: "sync" | "eager" | "weak" | "async-weak" | "lazy" | "lazy-once"; + recursive: boolean; + regExp: RegExp; + namespaceObject?: boolean | "strict"; + addon?: string; + chunkName?: string; + include?: RegExp; + exclude?: RegExp; + groupOptions?: RawChunkGroupOptions; + /** + * exports referenced from modules (won't be mangled) + */ + referencedExports?: string[][]; + resource: string; + resourceQuery?: string; + resolveOptions: any; + }, + callback: (err?: Error, dependencies?: ContextElementDependency[]) => any + ): void; } declare class ContextReplacementPlugin { constructor( @@ -1689,7 +1713,7 @@ declare class Dependency { */ getReferencedExports( moduleGraph: ModuleGraph - ): (string[] | ReferencedExportItem[])[]; + ): (string[] | ReferencedExport)[]; getCondition(moduleGraph: ModuleGraph): () => boolean; /** @@ -5399,6 +5423,10 @@ declare class ProvidePlugin { type PublicPath = | string | ((pathData: PathData, assetInfo: AssetInfo) => string); +declare interface RawChunkGroupOptions { + preloadOrder?: number; + prefetchOrder?: number; +} declare class ReadFileCompileWasmPlugin { constructor(options?: any); options: any; @@ -5423,14 +5451,14 @@ type RecursiveArrayOrRecord = | RuntimeValue | { [index: string]: RecursiveArrayOrRecord } | RecursiveArrayOrRecord[]; -declare interface ReferencedExportItem { +declare interface ReferencedExport { /** * name of the referenced export */ - name: string; + name: string[]; /** - * when true, referenced export can be mangled + * when false, referenced export can not be mangled, defaults to true */ canMangle?: boolean; }