diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
| commit | efbc2ffe6a1ee5ec38a4396305561d6515d0943e (patch) | |
| tree | 2b4c94f18f2c792dfda813050755d5c0273fae22 /node_modules/webpack/lib/dependencies | |
| parent | 43acceb75957c880a5ba5a31aae221394a36d5f6 (diff) | |
node fixes, updates
Diffstat (limited to 'node_modules/webpack/lib/dependencies')
117 files changed, 17273 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/dependencies/AMDDefineDependency.js b/node_modules/webpack/lib/dependencies/AMDDefineDependency.js new file mode 100644 index 00000000..4acb1525 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDDefineDependency.js @@ -0,0 +1,265 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +/** @type {Record<string, { definition: string, content: string, requests: string[] }>} */ +const DEFINITIONS = { + f: { + definition: "var __WEBPACK_AMD_DEFINE_RESULT__;", + content: `!(__WEBPACK_AMD_DEFINE_RESULT__ = (#).call(exports, ${RuntimeGlobals.require}, exports, module), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`, + requests: [ + RuntimeGlobals.require, + RuntimeGlobals.exports, + RuntimeGlobals.module + ] + }, + o: { + definition: "", + content: "!(module.exports = #)", + requests: [RuntimeGlobals.module] + }, + of: { + definition: + "var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;", + content: `!(__WEBPACK_AMD_DEFINE_FACTORY__ = (#), + __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? + (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, ${RuntimeGlobals.require}, exports, module)) : + __WEBPACK_AMD_DEFINE_FACTORY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`, + requests: [ + RuntimeGlobals.require, + RuntimeGlobals.exports, + RuntimeGlobals.module + ] + }, + af: { + definition: + "var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;", + content: `!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, __WEBPACK_AMD_DEFINE_RESULT__ = (#).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`, + requests: [RuntimeGlobals.exports, RuntimeGlobals.module] + }, + ao: { + definition: "", + content: "!(#, module.exports = #)", + requests: [RuntimeGlobals.module] + }, + aof: { + definition: + "var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;", + content: `!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, __WEBPACK_AMD_DEFINE_FACTORY__ = (#), + __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? + (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), + __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))`, + requests: [RuntimeGlobals.exports, RuntimeGlobals.module] + }, + lf: { + definition: "var XXX, XXXmodule;", + content: `!(XXXmodule = { id: YYY, exports: {}, loaded: false }, XXX = (#).call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule), XXXmodule.loaded = true, XXX === undefined && (XXX = XXXmodule.exports))`, + requests: [RuntimeGlobals.require, RuntimeGlobals.module] + }, + lo: { + definition: "var XXX;", + content: "!(XXX = #)", + requests: [] + }, + lof: { + definition: "var XXX, XXXfactory, XXXmodule;", + content: `!(XXXfactory = (#), (typeof XXXfactory === 'function' ? ((XXXmodule = { id: YYY, exports: {}, loaded: false }), (XXX = XXXfactory.call(XXXmodule.exports, ${RuntimeGlobals.require}, XXXmodule.exports, XXXmodule)), (XXXmodule.loaded = true), XXX === undefined && (XXX = XXXmodule.exports)) : XXX = XXXfactory))`, + requests: [RuntimeGlobals.require, RuntimeGlobals.module] + }, + laf: { + definition: "var __WEBPACK_AMD_DEFINE_ARRAY__, XXX, XXXexports;", + content: + "!(__WEBPACK_AMD_DEFINE_ARRAY__ = #, XXX = (#).apply(XXXexports = {}, __WEBPACK_AMD_DEFINE_ARRAY__), XXX === undefined && (XXX = XXXexports))", + requests: [] + }, + lao: { + definition: "var XXX;", + content: "!(#, XXX = #)", + requests: [] + }, + laof: { + definition: "var XXXarray, XXXfactory, XXXexports, XXX;", + content: `!(XXXarray = #, XXXfactory = (#), + (typeof XXXfactory === 'function' ? + ((XXX = XXXfactory.apply(XXXexports = {}, XXXarray)), XXX === undefined && (XXX = XXXexports)) : + (XXX = XXXfactory) + ))`, + requests: [] + } +}; + +class AMDDefineDependency extends NullDependency { + /** + * @param {Range} range range + * @param {Range | null} arrayRange array range + * @param {Range | null} functionRange function range + * @param {Range | null} objectRange object range + * @param {string | null} namedModule true, when define is called with a name + */ + constructor(range, arrayRange, functionRange, objectRange, namedModule) { + super(); + this.range = range; + this.arrayRange = arrayRange; + this.functionRange = functionRange; + this.objectRange = objectRange; + this.namedModule = namedModule; + this.localModule = null; + } + + get type() { + return "amd define"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + write(this.arrayRange); + write(this.functionRange); + write(this.objectRange); + write(this.namedModule); + write(this.localModule); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.range = read(); + this.arrayRange = read(); + this.functionRange = read(); + this.objectRange = read(); + this.namedModule = read(); + this.localModule = read(); + super.deserialize(context); + } +} + +makeSerializable( + AMDDefineDependency, + "webpack/lib/dependencies/AMDDefineDependency" +); + +AMDDefineDependency.Template = class AMDDefineDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { runtimeRequirements }) { + const dep = /** @type {AMDDefineDependency} */ (dependency); + const branch = this.branch(dep); + const { definition, content, requests } = DEFINITIONS[branch]; + for (const req of requests) { + runtimeRequirements.add(req); + } + this.replace(dep, source, definition, content); + } + + /** + * @param {AMDDefineDependency} dependency dependency + * @returns {string} variable name + */ + localModuleVar(dependency) { + return ( + dependency.localModule && + dependency.localModule.used && + dependency.localModule.variableName() + ); + } + + /** + * @param {AMDDefineDependency} dependency dependency + * @returns {string} branch + */ + branch(dependency) { + const localModuleVar = this.localModuleVar(dependency) ? "l" : ""; + const arrayRange = dependency.arrayRange ? "a" : ""; + const objectRange = dependency.objectRange ? "o" : ""; + const functionRange = dependency.functionRange ? "f" : ""; + return localModuleVar + arrayRange + objectRange + functionRange; + } + + /** + * @param {AMDDefineDependency} dependency dependency + * @param {ReplaceSource} source source + * @param {string} definition definition + * @param {string} text text + */ + replace(dependency, source, definition, text) { + const localModuleVar = this.localModuleVar(dependency); + if (localModuleVar) { + text = text.replace(/XXX/g, localModuleVar.replace(/\$/g, "$$$$")); + definition = definition.replace( + /XXX/g, + localModuleVar.replace(/\$/g, "$$$$") + ); + } + + if (dependency.namedModule) { + text = text.replace(/YYY/g, JSON.stringify(dependency.namedModule)); + } + + const texts = text.split("#"); + + if (definition) source.insert(0, definition); + + let current = dependency.range[0]; + if (dependency.arrayRange) { + source.replace( + current, + dependency.arrayRange[0] - 1, + /** @type {string} */ (texts.shift()) + ); + current = dependency.arrayRange[1]; + } + + if (dependency.objectRange) { + source.replace( + current, + dependency.objectRange[0] - 1, + /** @type {string} */ (texts.shift()) + ); + current = dependency.objectRange[1]; + } else if (dependency.functionRange) { + source.replace( + current, + dependency.functionRange[0] - 1, + /** @type {string} */ (texts.shift()) + ); + current = dependency.functionRange[1]; + } + source.replace( + current, + dependency.range[1] - 1, + /** @type {string} */ (texts.shift()) + ); + if (texts.length > 0) throw new Error("Implementation error"); + } +}; + +module.exports = AMDDefineDependency; diff --git a/node_modules/webpack/lib/dependencies/AMDDefineDependencyParserPlugin.js b/node_modules/webpack/lib/dependencies/AMDDefineDependencyParserPlugin.js new file mode 100644 index 00000000..14fbe4af --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDDefineDependencyParserPlugin.js @@ -0,0 +1,497 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const AMDDefineDependency = require("./AMDDefineDependency"); +const AMDRequireArrayDependency = require("./AMDRequireArrayDependency"); +const AMDRequireContextDependency = require("./AMDRequireContextDependency"); +const AMDRequireItemDependency = require("./AMDRequireItemDependency"); +const ConstDependency = require("./ConstDependency"); +const ContextDependencyHelpers = require("./ContextDependencyHelpers"); +const DynamicExports = require("./DynamicExports"); +const LocalModuleDependency = require("./LocalModuleDependency"); +const { addLocalModule, getLocalModule } = require("./LocalModulesHelpers"); + +/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */ +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").FunctionExpression} FunctionExpression */ +/** @typedef {import("estree").Identifier} Identifier */ +/** @typedef {import("estree").Literal} Literal */ +/** @typedef {import("estree").MemberExpression} MemberExpression */ +/** @typedef {import("estree").ObjectExpression} ObjectExpression */ +/** @typedef {import("estree").SimpleCallExpression} SimpleCallExpression */ +/** @typedef {import("estree").SpreadElement} SpreadElement */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +/** + * @param {Expression | SpreadElement} expr expression + * @returns {expr is CallExpression} true if it's a bound function expression + */ +const isBoundFunctionExpression = expr => { + if (expr.type !== "CallExpression") return false; + if (expr.callee.type !== "MemberExpression") return false; + if (expr.callee.computed) return false; + if (expr.callee.object.type !== "FunctionExpression") return false; + if (expr.callee.property.type !== "Identifier") return false; + if (expr.callee.property.name !== "bind") return false; + return true; +}; + +/** @typedef {FunctionExpression | ArrowFunctionExpression} UnboundFunctionExpression */ + +/** + * @param {Expression | SpreadElement} expr expression + * @returns {expr is FunctionExpression | ArrowFunctionExpression} true when unbound function expression + */ +const isUnboundFunctionExpression = expr => { + if (expr.type === "FunctionExpression") return true; + if (expr.type === "ArrowFunctionExpression") return true; + return false; +}; + +/** + * @param {Expression | SpreadElement} expr expression + * @returns {expr is FunctionExpression | ArrowFunctionExpression | CallExpression} true when callable + */ +const isCallable = expr => { + if (isUnboundFunctionExpression(expr)) return true; + if (isBoundFunctionExpression(expr)) return true; + return false; +}; + +class AMDDefineDependencyParserPlugin { + /** + * @param {JavascriptParserOptions} options parserOptions + */ + constructor(options) { + this.options = options; + } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + parser.hooks.call + .for("define") + .tap( + "AMDDefineDependencyParserPlugin", + this.processCallDefine.bind(this, parser) + ); + } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @param {Record<number, string>} identifiers identifiers + * @param {string=} namedModule named module + * @returns {boolean | undefined} result + */ + processArray(parser, expr, param, identifiers, namedModule) { + if (param.isArray()) { + const items = /** @type {BasicEvaluatedExpression[]} */ (param.items); + for (const [idx, item] of items.entries()) { + if ( + item.isString() && + ["require", "module", "exports"].includes( + /** @type {string} */ (item.string) + ) + ) + identifiers[/** @type {number} */ (idx)] = /** @type {string} */ ( + item.string + ); + const result = this.processItem(parser, expr, item, namedModule); + if (result === undefined) { + this.processContext(parser, expr, item); + } + } + return true; + } else if (param.isConstArray()) { + /** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */ + const deps = []; + const array = /** @type {string[]} */ (param.array); + for (const [idx, request] of array.entries()) { + let dep; + let localModule; + if (request === "require") { + identifiers[idx] = request; + dep = RuntimeGlobals.require; + } else if (["exports", "module"].includes(request)) { + identifiers[idx] = request; + dep = request; + } else if ((localModule = getLocalModule(parser.state, request))) { + localModule.flagUsed(); + dep = new LocalModuleDependency(localModule, undefined, false); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + } else { + dep = this.newRequireItemDependency(request); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + } + deps.push(dep); + } + const dep = this.newRequireArrayDependency( + deps, + /** @type {Range} */ (param.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.module.addPresentationalDependency(dep); + return true; + } + } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @param {string=} namedModule named module + * @returns {boolean | undefined} result + */ + processItem(parser, expr, param, namedModule) { + if (param.isConditional()) { + const options = /** @type {BasicEvaluatedExpression[]} */ (param.options); + for (const item of options) { + const result = this.processItem(parser, expr, item); + if (result === undefined) { + this.processContext(parser, expr, item); + } + } + + return true; + } else if (param.isString()) { + let dep; + let localModule; + + if (param.string === "require") { + dep = new ConstDependency( + RuntimeGlobals.require, + /** @type {Range} */ (param.range), + [RuntimeGlobals.require] + ); + } else if (param.string === "exports") { + dep = new ConstDependency( + "exports", + /** @type {Range} */ (param.range), + [RuntimeGlobals.exports] + ); + } else if (param.string === "module") { + dep = new ConstDependency( + "module", + /** @type {Range} */ (param.range), + [RuntimeGlobals.module] + ); + } else if ( + (localModule = getLocalModule( + parser.state, + /** @type {string} */ (param.string), + namedModule + )) + ) { + localModule.flagUsed(); + dep = new LocalModuleDependency(localModule, param.range, false); + } else { + dep = this.newRequireItemDependency( + /** @type {string} */ (param.string), + param.range + ); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + } + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + } + } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | undefined} result + */ + processContext(parser, expr, param) { + const dep = ContextDependencyHelpers.create( + AMDRequireContextDependency, + /** @type {Range} */ (param.range), + param, + expr, + this.options, + { + category: "amd" + }, + parser + ); + if (!dep) return; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @returns {boolean | undefined} result + */ + processCallDefine(parser, expr) { + /** @type {TODO} */ + let array; + /** @type {FunctionExpression | ArrowFunctionExpression | CallExpression | Identifier | undefined} */ + let fn; + /** @type {ObjectExpression | Identifier | undefined} */ + let obj; + /** @type {string | undefined} */ + let namedModule; + switch (expr.arguments.length) { + case 1: + if (isCallable(expr.arguments[0])) { + // define(f() {…}) + fn = expr.arguments[0]; + } else if (expr.arguments[0].type === "ObjectExpression") { + // define({…}) + obj = expr.arguments[0]; + } else { + // define(expr) + // unclear if function or object + obj = fn = /** @type {Identifier} */ (expr.arguments[0]); + } + break; + case 2: + if (expr.arguments[0].type === "Literal") { + namedModule = /** @type {string} */ (expr.arguments[0].value); + // define("…", …) + if (isCallable(expr.arguments[1])) { + // define("…", f() {…}) + fn = expr.arguments[1]; + } else if (expr.arguments[1].type === "ObjectExpression") { + // define("…", {…}) + obj = expr.arguments[1]; + } else { + // define("…", expr) + // unclear if function or object + obj = fn = /** @type {Identifier} */ (expr.arguments[1]); + } + } else { + array = expr.arguments[0]; + if (isCallable(expr.arguments[1])) { + // define([…], f() {}) + fn = expr.arguments[1]; + } else if (expr.arguments[1].type === "ObjectExpression") { + // define([…], {…}) + obj = expr.arguments[1]; + } else { + // define([…], expr) + // unclear if function or object + obj = fn = /** @type {Identifier} */ (expr.arguments[1]); + } + } + break; + case 3: + // define("…", […], f() {…}) + namedModule = + /** @type {string} */ + ( + /** @type {Literal} */ + (expr.arguments[0]).value + ); + array = expr.arguments[1]; + if (isCallable(expr.arguments[2])) { + // define("…", […], f() {}) + fn = expr.arguments[2]; + } else if (expr.arguments[2].type === "ObjectExpression") { + // define("…", […], {…}) + obj = expr.arguments[2]; + } else { + // define("…", […], expr) + // unclear if function or object + obj = fn = /** @type {Identifier} */ (expr.arguments[2]); + } + break; + default: + return; + } + DynamicExports.bailout(parser.state); + /** @type {Identifier[] | null} */ + let fnParams = null; + let fnParamsOffset = 0; + if (fn) { + if (isUnboundFunctionExpression(fn)) { + fnParams = + /** @type {Identifier[]} */ + (fn.params); + } else if (isBoundFunctionExpression(fn)) { + const object = + /** @type {FunctionExpression} */ + (/** @type {MemberExpression} */ (fn.callee).object); + + fnParams = + /** @type {Identifier[]} */ + (object.params); + fnParamsOffset = fn.arguments.length - 1; + if (fnParamsOffset < 0) { + fnParamsOffset = 0; + } + } + } + const fnRenames = new Map(); + if (array) { + /** @type {Record<number, string>} */ + const identifiers = {}; + const param = parser.evaluateExpression(array); + const result = this.processArray( + parser, + expr, + param, + identifiers, + namedModule + ); + if (!result) return; + if (fnParams) { + fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => { + if (identifiers[idx]) { + fnRenames.set(param.name, parser.getVariableInfo(identifiers[idx])); + return false; + } + return true; + }); + } + } else { + const identifiers = ["require", "exports", "module"]; + if (fnParams) { + fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => { + if (identifiers[idx]) { + fnRenames.set(param.name, parser.getVariableInfo(identifiers[idx])); + return false; + } + return true; + }); + } + } + /** @type {boolean | undefined} */ + let inTry; + if (fn && isUnboundFunctionExpression(fn)) { + inTry = parser.scope.inTry; + parser.inScope(fnParams, () => { + for (const [name, varInfo] of fnRenames) { + parser.setVariable(name, varInfo); + } + parser.scope.inTry = /** @type {boolean} */ (inTry); + if (fn.body.type === "BlockStatement") { + parser.detectMode(fn.body.body); + const prev = parser.prevStatement; + parser.preWalkStatement(fn.body); + parser.prevStatement = prev; + parser.walkStatement(fn.body); + } else { + parser.walkExpression(fn.body); + } + }); + } else if (fn && isBoundFunctionExpression(fn)) { + inTry = parser.scope.inTry; + + const object = + /** @type {FunctionExpression} */ + (/** @type {MemberExpression} */ (fn.callee).object); + + parser.inScope( + /** @type {Identifier[]} */ + (object.params).filter( + i => !["require", "module", "exports"].includes(i.name) + ), + () => { + for (const [name, varInfo] of fnRenames) { + parser.setVariable(name, varInfo); + } + parser.scope.inTry = /** @type {boolean} */ (inTry); + + if (object.body.type === "BlockStatement") { + parser.detectMode(object.body.body); + const prev = parser.prevStatement; + parser.preWalkStatement(object.body); + parser.prevStatement = prev; + parser.walkStatement(object.body); + } else { + parser.walkExpression(object.body); + } + } + ); + if (fn.arguments) { + parser.walkExpressions(fn.arguments); + } + } else if (fn || obj) { + parser.walkExpression(fn || obj); + } + + const dep = this.newDefineDependency( + /** @type {Range} */ (expr.range), + array ? /** @type {Range} */ (array.range) : null, + fn ? /** @type {Range} */ (fn.range) : null, + obj ? /** @type {Range} */ (obj.range) : null, + namedModule || null + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + if (namedModule) { + dep.localModule = addLocalModule(parser.state, namedModule); + } + parser.state.module.addPresentationalDependency(dep); + return true; + } + + /** + * @param {Range} range range + * @param {Range | null} arrayRange array range + * @param {Range | null} functionRange function range + * @param {Range | null} objectRange object range + * @param {string | null} namedModule true, when define is called with a name + * @returns {AMDDefineDependency} AMDDefineDependency + */ + newDefineDependency( + range, + arrayRange, + functionRange, + objectRange, + namedModule + ) { + return new AMDDefineDependency( + range, + arrayRange, + functionRange, + objectRange, + namedModule + ); + } + + /** + * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array + * @param {Range} range range + * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency + */ + newRequireArrayDependency(depsArray, range) { + return new AMDRequireArrayDependency(depsArray, range); + } + + /** + * @param {string} request request + * @param {Range=} range range + * @returns {AMDRequireItemDependency} AMDRequireItemDependency + */ + newRequireItemDependency(request, range) { + return new AMDRequireItemDependency(request, range); + } +} + +module.exports = AMDDefineDependencyParserPlugin; diff --git a/node_modules/webpack/lib/dependencies/AMDPlugin.js b/node_modules/webpack/lib/dependencies/AMDPlugin.js new file mode 100644 index 00000000..2ae03b78 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDPlugin.js @@ -0,0 +1,236 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const { + approve, + evaluateToIdentifier, + evaluateToString, + toConstantDependency +} = require("../javascript/JavascriptParserHelpers"); + +const AMDDefineDependency = require("./AMDDefineDependency"); +const AMDDefineDependencyParserPlugin = require("./AMDDefineDependencyParserPlugin"); +const AMDRequireArrayDependency = require("./AMDRequireArrayDependency"); +const AMDRequireContextDependency = require("./AMDRequireContextDependency"); +const AMDRequireDependenciesBlockParserPlugin = require("./AMDRequireDependenciesBlockParserPlugin"); +const AMDRequireDependency = require("./AMDRequireDependency"); +const AMDRequireItemDependency = require("./AMDRequireItemDependency"); +const { + AMDDefineRuntimeModule, + AMDOptionsRuntimeModule +} = require("./AMDRuntimeModules"); +const ConstDependency = require("./ConstDependency"); +const LocalModuleDependency = require("./LocalModuleDependency"); +const UnsupportedDependency = require("./UnsupportedDependency"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "AMDPlugin"; + +class AMDPlugin { + /** + * @param {Record<string, any>} amdOptions the AMD options + */ + constructor(amdOptions) { + this.amdOptions = amdOptions; + } + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + const amdOptions = this.amdOptions; + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { contextModuleFactory, normalModuleFactory }) => { + compilation.dependencyTemplates.set( + AMDRequireDependency, + new AMDRequireDependency.Template() + ); + + compilation.dependencyFactories.set( + AMDRequireItemDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + AMDRequireItemDependency, + new AMDRequireItemDependency.Template() + ); + + compilation.dependencyTemplates.set( + AMDRequireArrayDependency, + new AMDRequireArrayDependency.Template() + ); + + compilation.dependencyFactories.set( + AMDRequireContextDependency, + contextModuleFactory + ); + compilation.dependencyTemplates.set( + AMDRequireContextDependency, + new AMDRequireContextDependency.Template() + ); + + compilation.dependencyTemplates.set( + AMDDefineDependency, + new AMDDefineDependency.Template() + ); + + compilation.dependencyTemplates.set( + UnsupportedDependency, + new UnsupportedDependency.Template() + ); + + compilation.dependencyTemplates.set( + LocalModuleDependency, + new LocalModuleDependency.Template() + ); + + compilation.hooks.runtimeRequirementInModule + .for(RuntimeGlobals.amdDefine) + .tap(PLUGIN_NAME, (module, set) => { + set.add(RuntimeGlobals.require); + }); + + compilation.hooks.runtimeRequirementInModule + .for(RuntimeGlobals.amdOptions) + .tap(PLUGIN_NAME, (module, set) => { + set.add(RuntimeGlobals.requireScope); + }); + + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.amdDefine) + .tap(PLUGIN_NAME, (chunk, set) => { + compilation.addRuntimeModule(chunk, new AMDDefineRuntimeModule()); + }); + + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.amdOptions) + .tap(PLUGIN_NAME, (chunk, set) => { + compilation.addRuntimeModule( + chunk, + new AMDOptionsRuntimeModule(amdOptions) + ); + }); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + if (parserOptions.amd !== undefined && !parserOptions.amd) return; + + /** + * @param {string} optionExpr option expression + * @param {string} rootName root name + * @param {function(): TODO} getMembers callback + */ + const tapOptionsHooks = (optionExpr, rootName, getMembers) => { + parser.hooks.expression + .for(optionExpr) + .tap( + PLUGIN_NAME, + toConstantDependency(parser, RuntimeGlobals.amdOptions, [ + RuntimeGlobals.amdOptions + ]) + ); + parser.hooks.evaluateIdentifier + .for(optionExpr) + .tap( + PLUGIN_NAME, + evaluateToIdentifier(optionExpr, rootName, getMembers, true) + ); + parser.hooks.evaluateTypeof + .for(optionExpr) + .tap(PLUGIN_NAME, evaluateToString("object")); + parser.hooks.typeof + .for(optionExpr) + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("object")) + ); + }; + + new AMDRequireDependenciesBlockParserPlugin(parserOptions).apply( + parser + ); + new AMDDefineDependencyParserPlugin(parserOptions).apply(parser); + + tapOptionsHooks("define.amd", "define", () => "amd"); + tapOptionsHooks("require.amd", "require", () => ["amd"]); + tapOptionsHooks( + "__webpack_amd_options__", + "__webpack_amd_options__", + () => [] + ); + + parser.hooks.expression.for("define").tap(PLUGIN_NAME, expr => { + const dep = new ConstDependency( + RuntimeGlobals.amdDefine, + /** @type {Range} */ (expr.range), + [RuntimeGlobals.amdDefine] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + parser.hooks.typeof + .for("define") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("function")) + ); + parser.hooks.evaluateTypeof + .for("define") + .tap(PLUGIN_NAME, evaluateToString("function")); + parser.hooks.canRename.for("define").tap(PLUGIN_NAME, approve); + parser.hooks.rename.for("define").tap(PLUGIN_NAME, expr => { + const dep = new ConstDependency( + RuntimeGlobals.amdDefine, + /** @type {Range} */ (expr.range), + [RuntimeGlobals.amdDefine] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return false; + }); + parser.hooks.typeof + .for("require") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("function")) + ); + parser.hooks.evaluateTypeof + .for("require") + .tap(PLUGIN_NAME, evaluateToString("function")); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); + } + ); + } +} + +module.exports = AMDPlugin; diff --git a/node_modules/webpack/lib/dependencies/AMDRequireArrayDependency.js b/node_modules/webpack/lib/dependencies/AMDRequireArrayDependency.js new file mode 100644 index 00000000..a182f6c2 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDRequireArrayDependency.js @@ -0,0 +1,123 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const DependencyTemplate = require("../DependencyTemplate"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./AMDRequireItemDependency")} AMDRequireItemDependency */ +/** @typedef {import("./LocalModuleDependency")} LocalModuleDependency */ + +class AMDRequireArrayDependency extends NullDependency { + /** + * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array + * @param {Range} range range + */ + constructor(depsArray, range) { + super(); + + this.depsArray = depsArray; + this.range = range; + } + + get type() { + return "amd require array"; + } + + get category() { + return "amd"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.depsArray); + write(this.range); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.depsArray = read(); + this.range = read(); + + super.deserialize(context); + } +} + +makeSerializable( + AMDRequireArrayDependency, + "webpack/lib/dependencies/AMDRequireArrayDependency" +); + +AMDRequireArrayDependency.Template = class AMDRequireArrayDependencyTemplate extends ( + DependencyTemplate +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {AMDRequireArrayDependency} */ (dependency); + const content = this.getContent(dep, templateContext); + source.replace(dep.range[0], dep.range[1] - 1, content); + } + + /** + * @param {AMDRequireArrayDependency} dep the dependency for which the template should be applied + * @param {DependencyTemplateContext} templateContext the context object + * @returns {string} content + */ + getContent(dep, templateContext) { + const requires = dep.depsArray.map(dependency => + this.contentForDependency(dependency, templateContext) + ); + return `[${requires.join(", ")}]`; + } + + /** + * @param {TODO} dep the dependency for which the template should be applied + * @param {DependencyTemplateContext} templateContext the context object + * @returns {string} content + */ + contentForDependency( + dep, + { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } + ) { + if (typeof dep === "string") { + return dep; + } + + if (dep.localModule) { + return dep.localModule.variableName(); + } + return runtimeTemplate.moduleExports({ + module: moduleGraph.getModule(dep), + chunkGraph, + request: dep.request, + runtimeRequirements + }); + } +}; + +module.exports = AMDRequireArrayDependency; diff --git a/node_modules/webpack/lib/dependencies/AMDRequireContextDependency.js b/node_modules/webpack/lib/dependencies/AMDRequireContextDependency.js new file mode 100644 index 00000000..f040cb6e --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDRequireContextDependency.js @@ -0,0 +1,68 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ContextDependency = require("./ContextDependency"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class AMDRequireContextDependency extends ContextDependency { + /** + * @param {TODO} options options + * @param {Range} range range + * @param {Range} valueRange value range + */ + constructor(options, range, valueRange) { + super(options); + + this.range = range; + this.valueRange = valueRange; + } + + get type() { + return "amd require context"; + } + + get category() { + return "amd"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.range); + write(this.valueRange); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.range = read(); + this.valueRange = read(); + + super.deserialize(context); + } +} + +makeSerializable( + AMDRequireContextDependency, + "webpack/lib/dependencies/AMDRequireContextDependency" +); + +AMDRequireContextDependency.Template = require("./ContextDependencyTemplateAsRequireCall"); + +module.exports = AMDRequireContextDependency; diff --git a/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlock.js b/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlock.js new file mode 100644 index 00000000..615660c3 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlock.js @@ -0,0 +1,28 @@ +/* + 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("../Dependency").DependencyLocation} DependencyLocation */ + +class AMDRequireDependenciesBlock extends AsyncDependenciesBlock { + /** + * @param {DependencyLocation} loc location info + * @param {string=} request request + */ + constructor(loc, request) { + super(null, loc, request); + } +} + +makeSerializable( + AMDRequireDependenciesBlock, + "webpack/lib/dependencies/AMDRequireDependenciesBlock" +); + +module.exports = AMDRequireDependenciesBlock; diff --git a/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js b/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js new file mode 100644 index 00000000..803ce398 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js @@ -0,0 +1,410 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); +const AMDRequireArrayDependency = require("./AMDRequireArrayDependency"); +const AMDRequireContextDependency = require("./AMDRequireContextDependency"); +const AMDRequireDependenciesBlock = require("./AMDRequireDependenciesBlock"); +const AMDRequireDependency = require("./AMDRequireDependency"); +const AMDRequireItemDependency = require("./AMDRequireItemDependency"); +const ConstDependency = require("./ConstDependency"); +const ContextDependencyHelpers = require("./ContextDependencyHelpers"); +const LocalModuleDependency = require("./LocalModuleDependency"); +const { getLocalModule } = require("./LocalModulesHelpers"); +const UnsupportedDependency = require("./UnsupportedDependency"); +const getFunctionExpression = require("./getFunctionExpression"); + +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").Identifier} Identifier */ +/** @typedef {import("estree").SourceLocation} SourceLocation */ +/** @typedef {import("estree").SpreadElement} SpreadElement */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class AMDRequireDependenciesBlockParserPlugin { + /** + * @param {JavascriptParserOptions} options parserOptions + */ + constructor(options) { + this.options = options; + } + + /** + * @param {JavascriptParser} parser the parser + * @param {Expression | SpreadElement} expression expression + * @returns {boolean} need bind this + */ + processFunctionArgument(parser, expression) { + let bindThis = true; + const fnData = getFunctionExpression(expression); + if (fnData) { + parser.inScope( + fnData.fn.params.filter( + i => + !["require", "module", "exports"].includes( + /** @type {Identifier} */ (i).name + ) + ), + () => { + if (fnData.fn.body.type === "BlockStatement") { + parser.walkStatement(fnData.fn.body); + } else { + parser.walkExpression(fnData.fn.body); + } + } + ); + parser.walkExpressions(fnData.expressions); + if (fnData.needThis === false) { + bindThis = false; + } + } else { + parser.walkExpression(expression); + } + return bindThis; + } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + parser.hooks.call + .for("require") + .tap( + "AMDRequireDependenciesBlockParserPlugin", + this.processCallRequire.bind(this, parser) + ); + } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | undefined} result + */ + processArray(parser, expr, param) { + if (param.isArray()) { + for (const p of /** @type {BasicEvaluatedExpression[]} */ (param.items)) { + const result = this.processItem(parser, expr, p); + if (result === undefined) { + this.processContext(parser, expr, p); + } + } + return true; + } else if (param.isConstArray()) { + /** @type {(string | LocalModuleDependency | AMDRequireItemDependency)[]} */ + const deps = []; + for (const request of /** @type {any[]} */ (param.array)) { + let dep; + let localModule; + if (request === "require") { + dep = RuntimeGlobals.require; + } else if (["exports", "module"].includes(request)) { + dep = request; + } else if ((localModule = getLocalModule(parser.state, request))) { + localModule.flagUsed(); + dep = new LocalModuleDependency(localModule, undefined, false); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + } else { + dep = this.newRequireItemDependency(request); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + } + deps.push(dep); + } + const dep = this.newRequireArrayDependency( + deps, + /** @type {Range} */ (param.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.module.addPresentationalDependency(dep); + return true; + } + } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | undefined} result + */ + processItem(parser, expr, param) { + if (param.isConditional()) { + for (const p of /** @type {BasicEvaluatedExpression[]} */ ( + param.options + )) { + const result = this.processItem(parser, expr, p); + if (result === undefined) { + this.processContext(parser, expr, p); + } + } + return true; + } else if (param.isString()) { + let dep; + let localModule; + if (param.string === "require") { + dep = new ConstDependency( + RuntimeGlobals.require, + /** @type {TODO} */ (param.string), + [RuntimeGlobals.require] + ); + } else if (param.string === "module") { + dep = new ConstDependency( + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).moduleArgument, + /** @type {Range} */ (param.range), + [RuntimeGlobals.module] + ); + } else if (param.string === "exports") { + dep = new ConstDependency( + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).exportsArgument, + /** @type {Range} */ (param.range), + [RuntimeGlobals.exports] + ); + } else if ( + (localModule = getLocalModule( + parser.state, + /** @type {string} */ (param.string) + )) + ) { + localModule.flagUsed(); + dep = new LocalModuleDependency(localModule, param.range, false); + } else { + dep = this.newRequireItemDependency( + /** @type {string} */ (param.string), + param.range + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + } + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + } + } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | undefined} result + */ + processContext(parser, expr, param) { + const dep = ContextDependencyHelpers.create( + AMDRequireContextDependency, + /** @type {Range} */ (param.range), + param, + expr, + this.options, + { + category: "amd" + }, + parser + ); + if (!dep) return; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + } + + /** + * @param {BasicEvaluatedExpression} param param + * @returns {string | undefined} result + */ + processArrayForRequestString(param) { + if (param.isArray()) { + const result = + /** @type {BasicEvaluatedExpression[]} */ + (param.items).map(item => this.processItemForRequestString(item)); + if (result.every(Boolean)) return result.join(" "); + } else if (param.isConstArray()) { + return /** @type {string[]} */ (param.array).join(" "); + } + } + + /** + * @param {BasicEvaluatedExpression} param param + * @returns {string | undefined} result + */ + processItemForRequestString(param) { + if (param.isConditional()) { + const result = + /** @type {BasicEvaluatedExpression[]} */ + (param.options).map(item => this.processItemForRequestString(item)); + if (result.every(Boolean)) return result.join("|"); + } else if (param.isString()) { + return param.string; + } + } + + /** + * @param {JavascriptParser} parser the parser + * @param {CallExpression} expr call expression + * @returns {boolean | undefined} result + */ + processCallRequire(parser, expr) { + /** @type {BasicEvaluatedExpression | undefined} */ + let param; + /** @type {AMDRequireDependenciesBlock | undefined | null} */ + let depBlock; + /** @type {AMDRequireDependency | undefined} */ + let dep; + /** @type {boolean | undefined} */ + let result; + + const old = parser.state.current; + + if (expr.arguments.length >= 1) { + param = parser.evaluateExpression( + /** @type {Expression} */ (expr.arguments[0]) + ); + depBlock = this.newRequireDependenciesBlock( + /** @type {DependencyLocation} */ (expr.loc), + this.processArrayForRequestString(param) + ); + dep = this.newRequireDependency( + /** @type {Range} */ (expr.range), + /** @type {Range} */ (param.range), + expr.arguments.length > 1 + ? /** @type {Range} */ (expr.arguments[1].range) + : null, + expr.arguments.length > 2 + ? /** @type {Range} */ (expr.arguments[2].range) + : null + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + depBlock.addDependency(dep); + + parser.state.current = /** @type {TODO} */ (depBlock); + } + + if (expr.arguments.length === 1) { + parser.inScope([], () => { + result = this.processArray( + parser, + expr, + /** @type {BasicEvaluatedExpression} */ (param) + ); + }); + parser.state.current = old; + if (!result) return; + parser.state.current.addBlock( + /** @type {AMDRequireDependenciesBlock} */ (depBlock) + ); + return true; + } + + if (expr.arguments.length === 2 || expr.arguments.length === 3) { + try { + parser.inScope([], () => { + result = this.processArray( + parser, + expr, + /** @type {BasicEvaluatedExpression} */ (param) + ); + }); + if (!result) { + const dep = new UnsupportedDependency( + "unsupported", + /** @type {Range} */ (expr.range) + ); + old.addPresentationalDependency(dep); + if (parser.state.module) { + parser.state.module.addError( + new UnsupportedFeatureWarning( + `Cannot statically analyse 'require(…, …)' in line ${ + /** @type {SourceLocation} */ (expr.loc).start.line + }`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } + depBlock = null; + return true; + } + /** @type {AMDRequireDependency} */ + (dep).functionBindThis = this.processFunctionArgument( + parser, + expr.arguments[1] + ); + if (expr.arguments.length === 3) { + /** @type {AMDRequireDependency} */ + (dep).errorCallbackBindThis = this.processFunctionArgument( + parser, + expr.arguments[2] + ); + } + } finally { + parser.state.current = old; + if (depBlock) parser.state.current.addBlock(depBlock); + } + return true; + } + } + + /** + * @param {DependencyLocation} loc location + * @param {string=} request request + * @returns {AMDRequireDependenciesBlock} AMDRequireDependenciesBlock + */ + newRequireDependenciesBlock(loc, request) { + return new AMDRequireDependenciesBlock(loc, request); + } + + /** + * @param {Range} outerRange outer range + * @param {Range} arrayRange array range + * @param {Range | null} functionRange function range + * @param {Range | null} errorCallbackRange error callback range + * @returns {AMDRequireDependency} dependency + */ + newRequireDependency( + outerRange, + arrayRange, + functionRange, + errorCallbackRange + ) { + return new AMDRequireDependency( + outerRange, + arrayRange, + functionRange, + errorCallbackRange + ); + } + + /** + * @param {string} request request + * @param {Range=} range range + * @returns {AMDRequireItemDependency} AMDRequireItemDependency + */ + newRequireItemDependency(request, range) { + return new AMDRequireItemDependency(request, range); + } + + /** + * @param {(string | LocalModuleDependency | AMDRequireItemDependency)[]} depsArray deps array + * @param {Range} range range + * @returns {AMDRequireArrayDependency} AMDRequireArrayDependency + */ + newRequireArrayDependency(depsArray, range) { + return new AMDRequireArrayDependency(depsArray, range); + } +} +module.exports = AMDRequireDependenciesBlockParserPlugin; diff --git a/node_modules/webpack/lib/dependencies/AMDRequireDependency.js b/node_modules/webpack/lib/dependencies/AMDRequireDependency.js new file mode 100644 index 00000000..930348fc --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDRequireDependency.js @@ -0,0 +1,189 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class AMDRequireDependency extends NullDependency { + /** + * @param {Range} outerRange outer range + * @param {Range} arrayRange array range + * @param {Range | null} functionRange function range + * @param {Range | null} errorCallbackRange error callback range + */ + constructor(outerRange, arrayRange, functionRange, errorCallbackRange) { + super(); + + this.outerRange = outerRange; + this.arrayRange = arrayRange; + this.functionRange = functionRange; + this.errorCallbackRange = errorCallbackRange; + this.functionBindThis = false; + this.errorCallbackBindThis = false; + } + + get category() { + return "amd"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.outerRange); + write(this.arrayRange); + write(this.functionRange); + write(this.errorCallbackRange); + write(this.functionBindThis); + write(this.errorCallbackBindThis); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.outerRange = read(); + this.arrayRange = read(); + this.functionRange = read(); + this.errorCallbackRange = read(); + this.functionBindThis = read(); + this.errorCallbackBindThis = read(); + + super.deserialize(context); + } +} + +makeSerializable( + AMDRequireDependency, + "webpack/lib/dependencies/AMDRequireDependency" +); + +AMDRequireDependency.Template = class AMDRequireDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } + ) { + const dep = /** @type {AMDRequireDependency} */ (dependency); + const depBlock = /** @type {AsyncDependenciesBlock} */ ( + moduleGraph.getParentBlock(dep) + ); + const promise = runtimeTemplate.blockPromise({ + chunkGraph, + block: depBlock, + message: "AMD require", + runtimeRequirements + }); + + // has array range but no function range + if (dep.arrayRange && !dep.functionRange) { + const startBlock = `${promise}.then(function() {`; + const endBlock = `;})['catch'](${RuntimeGlobals.uncaughtErrorHandler})`; + runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler); + + source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock); + + source.replace(dep.arrayRange[1], dep.outerRange[1] - 1, endBlock); + + return; + } + + // has function range but no array range + if (dep.functionRange && !dep.arrayRange) { + const startBlock = `${promise}.then((`; + const endBlock = `).bind(exports, ${RuntimeGlobals.require}, exports, module))['catch'](${RuntimeGlobals.uncaughtErrorHandler})`; + runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler); + + source.replace(dep.outerRange[0], dep.functionRange[0] - 1, startBlock); + + source.replace(dep.functionRange[1], dep.outerRange[1] - 1, endBlock); + + return; + } + + // has array range, function range, and errorCallbackRange + if (dep.arrayRange && dep.functionRange && dep.errorCallbackRange) { + const startBlock = `${promise}.then(function() { `; + const errorRangeBlock = `}${ + dep.functionBindThis ? ".bind(this)" : "" + })['catch'](`; + const endBlock = `${dep.errorCallbackBindThis ? ".bind(this)" : ""})`; + + source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock); + + source.insert(dep.arrayRange[0], "var __WEBPACK_AMD_REQUIRE_ARRAY__ = "); + + source.replace(dep.arrayRange[1], dep.functionRange[0] - 1, "; ("); + + source.insert( + dep.functionRange[1], + ").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);" + ); + + source.replace( + dep.functionRange[1], + dep.errorCallbackRange[0] - 1, + errorRangeBlock + ); + + source.replace( + dep.errorCallbackRange[1], + dep.outerRange[1] - 1, + endBlock + ); + + return; + } + + // has array range, function range, but no errorCallbackRange + if (dep.arrayRange && dep.functionRange) { + const startBlock = `${promise}.then(function() { `; + const endBlock = `}${ + dep.functionBindThis ? ".bind(this)" : "" + })['catch'](${RuntimeGlobals.uncaughtErrorHandler})`; + runtimeRequirements.add(RuntimeGlobals.uncaughtErrorHandler); + + source.replace(dep.outerRange[0], dep.arrayRange[0] - 1, startBlock); + + source.insert(dep.arrayRange[0], "var __WEBPACK_AMD_REQUIRE_ARRAY__ = "); + + source.replace(dep.arrayRange[1], dep.functionRange[0] - 1, "; ("); + + source.insert( + dep.functionRange[1], + ").apply(null, __WEBPACK_AMD_REQUIRE_ARRAY__);" + ); + + source.replace(dep.functionRange[1], dep.outerRange[1] - 1, endBlock); + } + } +}; + +module.exports = AMDRequireDependency; diff --git a/node_modules/webpack/lib/dependencies/AMDRequireItemDependency.js b/node_modules/webpack/lib/dependencies/AMDRequireItemDependency.js new file mode 100644 index 00000000..614633ad --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDRequireItemDependency.js @@ -0,0 +1,41 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); +const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class AMDRequireItemDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range=} range location in source code + */ + constructor(request, range) { + super(request); + + this.range = range; + } + + get type() { + return "amd require"; + } + + get category() { + return "amd"; + } +} + +makeSerializable( + AMDRequireItemDependency, + "webpack/lib/dependencies/AMDRequireItemDependency" +); + +AMDRequireItemDependency.Template = ModuleDependencyTemplateAsRequireId; + +module.exports = AMDRequireItemDependency; diff --git a/node_modules/webpack/lib/dependencies/AMDRuntimeModules.js b/node_modules/webpack/lib/dependencies/AMDRuntimeModules.js new file mode 100644 index 00000000..cec00bb8 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/AMDRuntimeModules.js @@ -0,0 +1,48 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); +const Template = require("../Template"); + +class AMDDefineRuntimeModule extends RuntimeModule { + constructor() { + super("amd define"); + } + + /** + * @returns {string | null} runtime code + */ + generate() { + return Template.asString([ + `${RuntimeGlobals.amdDefine} = function () {`, + Template.indent("throw new Error('define cannot be used indirect');"), + "};" + ]); + } +} + +class AMDOptionsRuntimeModule extends RuntimeModule { + /** + * @param {Record<string, boolean | number | string>} options the AMD options + */ + constructor(options) { + super("amd options"); + this.options = options; + } + + /** + * @returns {string | null} runtime code + */ + generate() { + return Template.asString([ + `${RuntimeGlobals.amdOptions} = ${JSON.stringify(this.options)};` + ]); + } +} + +module.exports.AMDDefineRuntimeModule = AMDDefineRuntimeModule; +module.exports.AMDOptionsRuntimeModule = AMDOptionsRuntimeModule; diff --git a/node_modules/webpack/lib/dependencies/CachedConstDependency.js b/node_modules/webpack/lib/dependencies/CachedConstDependency.js new file mode 100644 index 00000000..60826f5a --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CachedConstDependency.js @@ -0,0 +1,127 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Florent Cailhol @ooflorent +*/ + +"use strict"; + +const DependencyTemplate = require("../DependencyTemplate"); +const InitFragment = require("../InitFragment"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../DependencyTemplates")} DependencyTemplates */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +class CachedConstDependency extends NullDependency { + /** + * @param {string} expression expression + * @param {Range} range range + * @param {string} identifier identifier + */ + constructor(expression, range, identifier) { + super(); + + this.expression = expression; + this.range = range; + this.identifier = identifier; + this._hashUpdate = undefined; + } + + /** + * @returns {string} hash update + */ + _createHashUpdate() { + return `${this.identifier}${this.range}${this.expression}`; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + if (this._hashUpdate === undefined) + this._hashUpdate = this._createHashUpdate(); + hash.update(this._hashUpdate); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.expression); + write(this.range); + write(this.identifier); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.expression = read(); + this.range = read(); + this.identifier = read(); + + super.deserialize(context); + } +} + +makeSerializable( + CachedConstDependency, + "webpack/lib/dependencies/CachedConstDependency" +); + +CachedConstDependency.Template = class CachedConstDependencyTemplate extends ( + DependencyTemplate +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { runtimeTemplate, dependencyTemplates, initFragments } + ) { + const dep = /** @type {CachedConstDependency} */ (dependency); + + initFragments.push( + new InitFragment( + `var ${dep.identifier} = ${dep.expression};\n`, + InitFragment.STAGE_CONSTANTS, + 0, + `const ${dep.identifier}` + ) + ); + + if (typeof dep.range === "number") { + source.insert(dep.range, dep.identifier); + + return; + } + + source.replace(dep.range[0], dep.range[1] - 1, dep.identifier); + } +}; + +module.exports = CachedConstDependency; diff --git a/node_modules/webpack/lib/dependencies/CommonJsDependencyHelpers.js b/node_modules/webpack/lib/dependencies/CommonJsDependencyHelpers.js new file mode 100644 index 00000000..0cd457ee --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsDependencyHelpers.js @@ -0,0 +1,63 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); + +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */ +/** @typedef {"exports" | "module.exports" | "this" | "Object.defineProperty(exports)" | "Object.defineProperty(module.exports)" | "Object.defineProperty(this)"} CommonJSDependencyBaseKeywords */ + +/** + * @param {CommonJSDependencyBaseKeywords} depBase commonjs dependency base + * @param {Module} module module + * @param {RuntimeRequirements} runtimeRequirements runtime requirements + * @returns {[string, string]} type and base + */ +module.exports.handleDependencyBase = ( + depBase, + module, + runtimeRequirements +) => { + let base; + let type; + switch (depBase) { + case "exports": + runtimeRequirements.add(RuntimeGlobals.exports); + base = module.exportsArgument; + type = "expression"; + break; + case "module.exports": + runtimeRequirements.add(RuntimeGlobals.module); + base = `${module.moduleArgument}.exports`; + type = "expression"; + break; + case "this": + runtimeRequirements.add(RuntimeGlobals.thisAsExports); + base = "this"; + type = "expression"; + break; + case "Object.defineProperty(exports)": + runtimeRequirements.add(RuntimeGlobals.exports); + base = module.exportsArgument; + type = "Object.defineProperty"; + break; + case "Object.defineProperty(module.exports)": + runtimeRequirements.add(RuntimeGlobals.module); + base = `${module.moduleArgument}.exports`; + type = "Object.defineProperty"; + break; + case "Object.defineProperty(this)": + runtimeRequirements.add(RuntimeGlobals.thisAsExports); + base = "this"; + type = "Object.defineProperty"; + break; + default: + throw new Error(`Unsupported base ${depBase}`); + } + + return [type, base]; +}; diff --git a/node_modules/webpack/lib/dependencies/CommonJsExportRequireDependency.js b/node_modules/webpack/lib/dependencies/CommonJsExportRequireDependency.js new file mode 100644 index 00000000..d4f7a73c --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsExportRequireDependency.js @@ -0,0 +1,404 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const { UsageState } = require("../ExportsInfo"); +const Template = require("../Template"); +const { equals } = require("../util/ArrayHelpers"); +const makeSerializable = require("../util/makeSerializable"); +const propertyAccess = require("../util/propertyAccess"); +const { handleDependencyBase } = require("./CommonJsDependencyHelpers"); +const ModuleDependency = require("./ModuleDependency"); +const processExportInfo = require("./processExportInfo"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ExportsInfo")} ExportsInfo */ +/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */ + +const idsSymbol = Symbol("CommonJsExportRequireDependency.ids"); + +const EMPTY_OBJECT = {}; + +class CommonJsExportRequireDependency extends ModuleDependency { + /** + * @param {Range} range range + * @param {Range | null} valueRange value range + * @param {CommonJSDependencyBaseKeywords} base base + * @param {string[]} names names + * @param {string} request request + * @param {string[]} ids ids + * @param {boolean} resultUsed true, when the result is used + */ + constructor(range, valueRange, base, names, request, ids, resultUsed) { + super(request); + this.range = range; + this.valueRange = valueRange; + this.base = base; + this.names = names; + this.ids = ids; + this.resultUsed = resultUsed; + this.asiSafe = undefined; + } + + get type() { + return "cjs export require"; + } + + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return Dependency.TRANSITIVE; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {string[]} the imported id + */ + getIds(moduleGraph) { + return ( + /** @type {TODO} */ (moduleGraph.getMeta(this))[idsSymbol] || this.ids + ); + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @param {string[]} ids the imported ids + * @returns {void} + */ + setIds(moduleGraph, ids) { + /** @type {TODO} */ (moduleGraph.getMeta(this))[idsSymbol] = ids; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + const ids = this.getIds(moduleGraph); + const getFullResult = () => { + if (ids.length === 0) { + return Dependency.EXPORTS_OBJECT_REFERENCED; + } + return [ + { + name: ids, + canMangle: false + } + ]; + }; + if (this.resultUsed) return getFullResult(); + /** @type {ExportsInfo | undefined} */ + let exportsInfo = moduleGraph.getExportsInfo( + /** @type {Module} */ (moduleGraph.getParentModule(this)) + ); + for (const name of this.names) { + const exportInfo = /** @type {ExportInfo} */ ( + exportsInfo.getReadOnlyExportInfo(name) + ); + const used = exportInfo.getUsed(runtime); + if (used === UsageState.Unused) return Dependency.NO_EXPORTS_REFERENCED; + if (used !== UsageState.OnlyPropertiesUsed) return getFullResult(); + exportsInfo = exportInfo.exportsInfo; + if (!exportsInfo) return getFullResult(); + } + if (exportsInfo.otherExportsInfo.getUsed(runtime) !== UsageState.Unused) { + return getFullResult(); + } + /** @type {string[][]} */ + const referencedExports = []; + for (const exportInfo of exportsInfo.orderedExports) { + processExportInfo( + runtime, + referencedExports, + ids.concat(exportInfo.name), + exportInfo, + false + ); + } + return referencedExports.map(name => ({ + name, + canMangle: false + })); + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + if (this.names.length === 1) { + const ids = this.getIds(moduleGraph); + const name = this.names[0]; + const from = moduleGraph.getConnection(this); + if (!from) return; + return { + exports: [ + { + name, + from, + export: ids.length === 0 ? null : ids, + // we can't mangle names that are in an empty object + // because one could access the prototype property + // when export isn't set yet + canMangle: !(name in EMPTY_OBJECT) && false + } + ], + dependencies: [from.module] + }; + } else if (this.names.length > 0) { + const name = this.names[0]; + return { + exports: [ + { + name, + // we can't mangle names that are in an empty object + // because one could access the prototype property + // when export isn't set yet + canMangle: !(name in EMPTY_OBJECT) && false + } + ], + dependencies: undefined + }; + } + const from = moduleGraph.getConnection(this); + if (!from) return; + const reexportInfo = this.getStarReexports( + moduleGraph, + undefined, + from.module + ); + const ids = this.getIds(moduleGraph); + if (reexportInfo) { + return { + exports: Array.from( + /** @type {TODO} */ (reexportInfo).exports, + name => ({ + name, + from, + export: ids.concat(name), + canMangle: !(name in EMPTY_OBJECT) && false + }) + ), + // TODO handle deep reexports + dependencies: [from.module] + }; + } + return { + exports: true, + from: ids.length === 0 ? from : undefined, + canMangle: false, + dependencies: [from.module] + }; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @param {RuntimeSpec} runtime the runtime + * @param {Module} importedModule the imported module (optional) + * @returns {{exports?: Set<string>, checked?: Set<string>} | undefined} information + */ + getStarReexports( + moduleGraph, + runtime, + importedModule = /** @type {Module} */ (moduleGraph.getModule(this)) + ) { + /** @type {ExportsInfo | undefined} */ + let importedExportsInfo = moduleGraph.getExportsInfo(importedModule); + const ids = this.getIds(moduleGraph); + if (ids.length > 0) + importedExportsInfo = importedExportsInfo.getNestedExportsInfo(ids); + /** @type {ExportsInfo | undefined} */ + let exportsInfo = moduleGraph.getExportsInfo( + /** @type {Module} */ (moduleGraph.getParentModule(this)) + ); + if (this.names.length > 0) + exportsInfo = exportsInfo.getNestedExportsInfo(this.names); + + const noExtraExports = + importedExportsInfo && + importedExportsInfo.otherExportsInfo.provided === false; + const noExtraImports = + exportsInfo && + exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused; + + if (!noExtraExports && !noExtraImports) { + return; + } + + const isNamespaceImport = + importedModule.getExportsType(moduleGraph, false) === "namespace"; + + /** @type {Set<string>} */ + const exports = new Set(); + /** @type {Set<string>} */ + const checked = new Set(); + + if (noExtraImports) { + for (const exportInfo of /** @type {ExportsInfo} */ (exportsInfo) + .orderedExports) { + const name = exportInfo.name; + if (exportInfo.getUsed(runtime) === UsageState.Unused) continue; + if (name === "__esModule" && isNamespaceImport) { + exports.add(name); + } else if (importedExportsInfo) { + const importedExportInfo = + importedExportsInfo.getReadOnlyExportInfo(name); + if (importedExportInfo.provided === false) continue; + exports.add(name); + if (importedExportInfo.provided === true) continue; + checked.add(name); + } else { + exports.add(name); + checked.add(name); + } + } + } else if (noExtraExports) { + for (const importedExportInfo of /** @type {ExportsInfo} */ ( + importedExportsInfo + ).orderedExports) { + const name = importedExportInfo.name; + if (importedExportInfo.provided === false) continue; + if (exportsInfo) { + const exportInfo = exportsInfo.getReadOnlyExportInfo(name); + if (exportInfo.getUsed(runtime) === UsageState.Unused) continue; + } + exports.add(name); + if (importedExportInfo.provided === true) continue; + checked.add(name); + } + if (isNamespaceImport) { + exports.add("__esModule"); + checked.delete("__esModule"); + } + } + + return { exports, checked }; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.asiSafe); + write(this.range); + write(this.valueRange); + write(this.base); + write(this.names); + write(this.ids); + write(this.resultUsed); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.asiSafe = read(); + this.range = read(); + this.valueRange = read(); + this.base = read(); + this.names = read(); + this.ids = read(); + this.resultUsed = read(); + super.deserialize(context); + } +} + +makeSerializable( + CommonJsExportRequireDependency, + "webpack/lib/dependencies/CommonJsExportRequireDependency" +); + +CommonJsExportRequireDependency.Template = class CommonJsExportRequireDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { + module, + runtimeTemplate, + chunkGraph, + moduleGraph, + runtimeRequirements, + runtime + } + ) { + const dep = /** @type {CommonJsExportRequireDependency} */ (dependency); + const used = moduleGraph + .getExportsInfo(module) + .getUsedName(dep.names, runtime); + + const [type, base] = handleDependencyBase( + dep.base, + module, + runtimeRequirements + ); + + const importedModule = moduleGraph.getModule(dep); + let requireExpr = runtimeTemplate.moduleExports({ + module: importedModule, + chunkGraph, + request: dep.request, + weak: dep.weak, + runtimeRequirements + }); + if (importedModule) { + const ids = dep.getIds(moduleGraph); + const usedImported = moduleGraph + .getExportsInfo(importedModule) + .getUsedName(ids, runtime); + if (usedImported) { + const comment = equals(usedImported, ids) + ? "" + : `${Template.toNormalComment(propertyAccess(ids))} `; + requireExpr += `${comment}${propertyAccess(usedImported)}`; + } + } + + switch (type) { + case "expression": + source.replace( + dep.range[0], + dep.range[1] - 1, + used + ? `${base}${propertyAccess(used)} = ${requireExpr}` + : `/* unused reexport */ ${requireExpr}` + ); + return; + case "Object.defineProperty": + throw new Error("TODO"); + default: + throw new Error("Unexpected type"); + } + } +}; + +module.exports = CommonJsExportRequireDependency; diff --git a/node_modules/webpack/lib/dependencies/CommonJsExportsDependency.js b/node_modules/webpack/lib/dependencies/CommonJsExportsDependency.js new file mode 100644 index 00000000..93c831b5 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsExportsDependency.js @@ -0,0 +1,183 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const InitFragment = require("../InitFragment"); +const makeSerializable = require("../util/makeSerializable"); +const propertyAccess = require("../util/propertyAccess"); +const { handleDependencyBase } = require("./CommonJsDependencyHelpers"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */ + +const EMPTY_OBJECT = {}; + +class CommonJsExportsDependency extends NullDependency { + /** + * @param {Range} range range + * @param {Range | null} valueRange value range + * @param {CommonJSDependencyBaseKeywords} base base + * @param {string[]} names names + */ + constructor(range, valueRange, base, names) { + super(); + this.range = range; + this.valueRange = valueRange; + this.base = base; + this.names = names; + } + + get type() { + return "cjs exports"; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + const name = this.names[0]; + return { + exports: [ + { + name, + // we can't mangle names that are in an empty object + // because one could access the prototype property + // when export isn't set yet + canMangle: !(name in EMPTY_OBJECT) + } + ], + dependencies: undefined + }; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + write(this.valueRange); + write(this.base); + write(this.names); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.range = read(); + this.valueRange = read(); + this.base = read(); + this.names = read(); + super.deserialize(context); + } +} + +makeSerializable( + CommonJsExportsDependency, + "webpack/lib/dependencies/CommonJsExportsDependency" +); + +CommonJsExportsDependency.Template = class CommonJsExportsDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { module, moduleGraph, initFragments, runtimeRequirements, runtime } + ) { + const dep = /** @type {CommonJsExportsDependency} */ (dependency); + const used = moduleGraph + .getExportsInfo(module) + .getUsedName(dep.names, runtime); + + const [type, base] = handleDependencyBase( + dep.base, + module, + runtimeRequirements + ); + + switch (type) { + case "expression": + if (!used) { + initFragments.push( + new InitFragment( + "var __webpack_unused_export__;\n", + InitFragment.STAGE_CONSTANTS, + 0, + "__webpack_unused_export__" + ) + ); + source.replace( + dep.range[0], + dep.range[1] - 1, + "__webpack_unused_export__" + ); + return; + } + source.replace( + dep.range[0], + dep.range[1] - 1, + `${base}${propertyAccess(used)}` + ); + return; + case "Object.defineProperty": + if (!used) { + initFragments.push( + new InitFragment( + "var __webpack_unused_export__;\n", + InitFragment.STAGE_CONSTANTS, + 0, + "__webpack_unused_export__" + ) + ); + source.replace( + dep.range[0], + /** @type {Range} */ (dep.valueRange)[0] - 1, + "__webpack_unused_export__ = (" + ); + source.replace( + /** @type {Range} */ (dep.valueRange)[1], + dep.range[1] - 1, + ")" + ); + return; + } + source.replace( + dep.range[0], + /** @type {Range} */ (dep.valueRange)[0] - 1, + `Object.defineProperty(${base}${propertyAccess( + used.slice(0, -1) + )}, ${JSON.stringify(used[used.length - 1])}, (` + ); + source.replace( + /** @type {Range} */ (dep.valueRange)[1], + dep.range[1] - 1, + "))" + ); + } + } +}; + +module.exports = CommonJsExportsDependency; diff --git a/node_modules/webpack/lib/dependencies/CommonJsExportsParserPlugin.js b/node_modules/webpack/lib/dependencies/CommonJsExportsParserPlugin.js new file mode 100644 index 00000000..2e04a494 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsExportsParserPlugin.js @@ -0,0 +1,408 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const formatLocation = require("../formatLocation"); +const { evaluateToString } = require("../javascript/JavascriptParserHelpers"); +const propertyAccess = require("../util/propertyAccess"); +const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency"); +const CommonJsExportsDependency = require("./CommonJsExportsDependency"); +const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency"); +const DynamicExports = require("./DynamicExports"); +const HarmonyExports = require("./HarmonyExports"); +const ModuleDecoratorDependency = require("./ModuleDecoratorDependency"); + +/** @typedef {import("estree").AssignmentExpression} AssignmentExpression */ +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").Super} Super */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../NormalModule")} NormalModule */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */ + +/** + * This function takes a generic expression and detects whether it is an ObjectExpression. + * This is used in the context of parsing CommonJS exports to get the value of the property descriptor + * when the `exports` object is assigned to `Object.defineProperty`. + * + * In CommonJS modules, the `exports` object can be assigned to `Object.defineProperty` and therefore + * webpack has to detect this case and get the value key of the property descriptor. See the following example + * for more information: https://astexplorer.net/#/gist/83ce51a4e96e59d777df315a6d111da6/8058ead48a1bb53c097738225db0967ef7f70e57 + * + * This would be an example of a CommonJS module that exports an object with a property descriptor: + * ```js + * Object.defineProperty(exports, "__esModule", { value: true }); + * exports.foo = void 0; + * exports.foo = "bar"; + * ``` + * @param {TODO} expr expression + * @returns {Expression | undefined} returns the value of property descriptor + */ +const getValueOfPropertyDescription = expr => { + if (expr.type !== "ObjectExpression") return; + for (const property of expr.properties) { + if (property.computed) continue; + const key = property.key; + if (key.type !== "Identifier" || key.name !== "value") continue; + return property.value; + } +}; + +/** + * The purpose of this function is to check whether an expression is a truthy literal or not. This is + * useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy + * values like `null` and `false`. However, exports should only be created if the exported value is truthy. + * @param {Expression} expr expression being checked + * @returns {boolean} true, when the expression is a truthy literal + */ +const isTruthyLiteral = expr => { + switch (expr.type) { + case "Literal": + return Boolean(expr.value); + case "UnaryExpression": + if (expr.operator === "!") return isFalsyLiteral(expr.argument); + } + return false; +}; + +/** + * The purpose of this function is to check whether an expression is a falsy literal or not. This is + * useful when parsing CommonJS exports, because CommonJS modules can export any value, including falsy + * values like `null` and `false`. However, exports should only be created if the exported value is truthy. + * @param {Expression} expr expression being checked + * @returns {boolean} true, when the expression is a falsy literal + */ +const isFalsyLiteral = expr => { + switch (expr.type) { + case "Literal": + return !expr.value; + case "UnaryExpression": + if (expr.operator === "!") return isTruthyLiteral(expr.argument); + } + return false; +}; + +/** + * @param {JavascriptParser} parser the parser + * @param {Expression} expr expression + * @returns {{ argument: BasicEvaluatedExpression, ids: string[] } | undefined} parsed call + */ +const parseRequireCall = (parser, expr) => { + const ids = []; + while (expr.type === "MemberExpression") { + if (expr.object.type === "Super") return; + if (!expr.property) return; + const prop = expr.property; + if (expr.computed) { + if (prop.type !== "Literal") return; + ids.push(`${prop.value}`); + } else { + if (prop.type !== "Identifier") return; + ids.push(prop.name); + } + expr = expr.object; + } + if (expr.type !== "CallExpression" || expr.arguments.length !== 1) return; + const callee = expr.callee; + if ( + callee.type !== "Identifier" || + parser.getVariableInfo(callee.name) !== "require" + ) { + return; + } + const arg = expr.arguments[0]; + if (arg.type === "SpreadElement") return; + const argValue = parser.evaluateExpression(arg); + return { argument: argValue, ids: ids.reverse() }; +}; + +class CommonJsExportsParserPlugin { + /** + * @param {ModuleGraph} moduleGraph module graph + */ + constructor(moduleGraph) { + this.moduleGraph = moduleGraph; + } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + const enableStructuredExports = () => { + DynamicExports.enable(parser.state); + }; + + /** + * @param {boolean} topLevel true, when the export is on top level + * @param {string[]} members members of the export + * @param {Expression | undefined} valueExpr expression for the value + * @returns {void} + */ + const checkNamespace = (topLevel, members, valueExpr) => { + if (!DynamicExports.isEnabled(parser.state)) return; + if (members.length > 0 && members[0] === "__esModule") { + if (valueExpr && isTruthyLiteral(valueExpr) && topLevel) { + DynamicExports.setFlagged(parser.state); + } else { + DynamicExports.setDynamic(parser.state); + } + } + }; + /** + * @param {string=} reason reason + */ + const bailout = reason => { + DynamicExports.bailout(parser.state); + if (reason) bailoutHint(reason); + }; + /** + * @param {string} reason reason + */ + const bailoutHint = reason => { + this.moduleGraph + .getOptimizationBailout(parser.state.module) + .push(`CommonJS bailout: ${reason}`); + }; + + // metadata // + parser.hooks.evaluateTypeof + .for("module") + .tap("CommonJsExportsParserPlugin", evaluateToString("object")); + parser.hooks.evaluateTypeof + .for("exports") + .tap("CommonJsPlugin", evaluateToString("object")); + + // exporting // + + /** + * @param {AssignmentExpression} expr expression + * @param {CommonJSDependencyBaseKeywords} base commonjs base keywords + * @param {string[]} members members of the export + * @returns {boolean | undefined} true, when the expression was handled + */ + const handleAssignExport = (expr, base, members) => { + if (HarmonyExports.isEnabled(parser.state)) return; + // Handle reexporting + const requireCall = parseRequireCall(parser, expr.right); + if ( + requireCall && + requireCall.argument.isString() && + (members.length === 0 || members[0] !== "__esModule") + ) { + enableStructuredExports(); + // It's possible to reexport __esModule, so we must convert to a dynamic module + if (members.length === 0) DynamicExports.setDynamic(parser.state); + const dep = new CommonJsExportRequireDependency( + /** @type {Range} */ (expr.range), + null, + base, + members, + /** @type {string} */ (requireCall.argument.string), + requireCall.ids, + !parser.isStatementLevelExpression(expr) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.module.addDependency(dep); + return true; + } + if (members.length === 0) return; + enableStructuredExports(); + const remainingMembers = members; + checkNamespace( + parser.statementPath.length === 1 && + parser.isStatementLevelExpression(expr), + remainingMembers, + expr.right + ); + const dep = new CommonJsExportsDependency( + /** @type {Range} */ (expr.left.range), + null, + base, + remainingMembers + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + parser.walkExpression(expr.right); + return true; + }; + parser.hooks.assignMemberChain + .for("exports") + .tap("CommonJsExportsParserPlugin", (expr, members) => + handleAssignExport(expr, "exports", members) + ); + parser.hooks.assignMemberChain + .for("this") + .tap("CommonJsExportsParserPlugin", (expr, members) => { + if (!parser.scope.topLevelScope) return; + return handleAssignExport(expr, "this", members); + }); + parser.hooks.assignMemberChain + .for("module") + .tap("CommonJsExportsParserPlugin", (expr, members) => { + if (members[0] !== "exports") return; + return handleAssignExport(expr, "module.exports", members.slice(1)); + }); + parser.hooks.call + .for("Object.defineProperty") + .tap("CommonJsExportsParserPlugin", expression => { + const expr = /** @type {CallExpression} */ (expression); + if (!parser.isStatementLevelExpression(expr)) return; + if (expr.arguments.length !== 3) return; + if (expr.arguments[0].type === "SpreadElement") return; + if (expr.arguments[1].type === "SpreadElement") return; + if (expr.arguments[2].type === "SpreadElement") return; + const exportsArg = parser.evaluateExpression(expr.arguments[0]); + if (!exportsArg.isIdentifier()) return; + if ( + exportsArg.identifier !== "exports" && + exportsArg.identifier !== "module.exports" && + (exportsArg.identifier !== "this" || !parser.scope.topLevelScope) + ) { + return; + } + const propertyArg = parser.evaluateExpression(expr.arguments[1]); + const property = propertyArg.asString(); + if (typeof property !== "string") return; + enableStructuredExports(); + const descArg = expr.arguments[2]; + checkNamespace( + parser.statementPath.length === 1, + [property], + getValueOfPropertyDescription(descArg) + ); + const dep = new CommonJsExportsDependency( + /** @type {Range} */ (expr.range), + /** @type {Range} */ (expr.arguments[2].range), + `Object.defineProperty(${exportsArg.identifier})`, + [property] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + + parser.walkExpression(expr.arguments[2]); + return true; + }); + + // Self reference // + + /** + * @param {Expression | Super} expr expression + * @param {CommonJSDependencyBaseKeywords} base commonjs base keywords + * @param {string[]} members members of the export + * @param {CallExpression=} call call expression + * @returns {boolean | void} true, when the expression was handled + */ + const handleAccessExport = (expr, base, members, call) => { + if (HarmonyExports.isEnabled(parser.state)) return; + if (members.length === 0) { + bailout( + `${base} is used directly at ${formatLocation( + /** @type {DependencyLocation} */ (expr.loc) + )}` + ); + } + if (call && members.length === 1) { + bailoutHint( + `${base}${propertyAccess( + members + )}(...) prevents optimization as ${base} is passed as call context at ${formatLocation( + /** @type {DependencyLocation} */ (expr.loc) + )}` + ); + } + const dep = new CommonJsSelfReferenceDependency( + /** @type {Range} */ (expr.range), + base, + members, + Boolean(call) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + if (call) { + parser.walkExpressions(call.arguments); + } + return true; + }; + parser.hooks.callMemberChain + .for("exports") + .tap("CommonJsExportsParserPlugin", (expr, members) => + handleAccessExport(expr.callee, "exports", members, expr) + ); + parser.hooks.expressionMemberChain + .for("exports") + .tap("CommonJsExportsParserPlugin", (expr, members) => + handleAccessExport(expr, "exports", members) + ); + parser.hooks.expression + .for("exports") + .tap("CommonJsExportsParserPlugin", expr => + handleAccessExport(expr, "exports", []) + ); + parser.hooks.callMemberChain + .for("module") + .tap("CommonJsExportsParserPlugin", (expr, members) => { + if (members[0] !== "exports") return; + return handleAccessExport( + expr.callee, + "module.exports", + members.slice(1), + expr + ); + }); + parser.hooks.expressionMemberChain + .for("module") + .tap("CommonJsExportsParserPlugin", (expr, members) => { + if (members[0] !== "exports") return; + return handleAccessExport(expr, "module.exports", members.slice(1)); + }); + parser.hooks.expression + .for("module.exports") + .tap("CommonJsExportsParserPlugin", expr => + handleAccessExport(expr, "module.exports", []) + ); + parser.hooks.callMemberChain + .for("this") + .tap("CommonJsExportsParserPlugin", (expr, members) => { + if (!parser.scope.topLevelScope) return; + return handleAccessExport(expr.callee, "this", members, expr); + }); + parser.hooks.expressionMemberChain + .for("this") + .tap("CommonJsExportsParserPlugin", (expr, members) => { + if (!parser.scope.topLevelScope) return; + return handleAccessExport(expr, "this", members); + }); + parser.hooks.expression + .for("this") + .tap("CommonJsExportsParserPlugin", expr => { + if (!parser.scope.topLevelScope) return; + return handleAccessExport(expr, "this", []); + }); + + // Bailouts // + parser.hooks.expression.for("module").tap("CommonJsPlugin", expr => { + bailout(); + const isHarmony = HarmonyExports.isEnabled(parser.state); + const dep = new ModuleDecoratorDependency( + isHarmony + ? RuntimeGlobals.harmonyModuleDecorator + : RuntimeGlobals.nodeModuleDecorator, + !isHarmony + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + return true; + }); + } +} +module.exports = CommonJsExportsParserPlugin; diff --git a/node_modules/webpack/lib/dependencies/CommonJsFullRequireDependency.js b/node_modules/webpack/lib/dependencies/CommonJsFullRequireDependency.js new file mode 100644 index 00000000..1164eee1 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsFullRequireDependency.js @@ -0,0 +1,166 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Template = require("../Template"); +const { equals } = require("../util/ArrayHelpers"); +const { getTrimmedIdsAndRange } = require("../util/chainedImports"); +const makeSerializable = require("../util/makeSerializable"); +const propertyAccess = require("../util/propertyAccess"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class CommonJsFullRequireDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + * @param {string[]} names accessed properties on module + * @param {Range[]=} idRanges ranges for members of ids; the two arrays are right-aligned + */ + constructor( + request, + range, + names, + idRanges /* TODO webpack 6 make this non-optional. It must always be set to properly trim ids. */ + ) { + super(request); + this.range = range; + this.names = names; + this.idRanges = idRanges; + this.call = false; + this.asiSafe = undefined; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + if (this.call) { + const importedModule = moduleGraph.getModule(this); + if ( + !importedModule || + importedModule.getExportsType(moduleGraph, false) !== "namespace" + ) { + return [this.names.slice(0, -1)]; + } + } + return [this.names]; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.names); + write(this.idRanges); + write(this.call); + write(this.asiSafe); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.names = read(); + this.idRanges = read(); + this.call = read(); + this.asiSafe = read(); + super.deserialize(context); + } + + get type() { + return "cjs full require"; + } + + get category() { + return "commonjs"; + } +} + +CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { + module, + runtimeTemplate, + moduleGraph, + chunkGraph, + runtimeRequirements, + runtime, + initFragments + } + ) { + const dep = /** @type {CommonJsFullRequireDependency} */ (dependency); + if (!dep.range) return; + const importedModule = moduleGraph.getModule(dep); + let requireExpr = runtimeTemplate.moduleExports({ + module: importedModule, + chunkGraph, + request: dep.request, + weak: dep.weak, + runtimeRequirements + }); + + const { + trimmedRange: [trimmedRangeStart, trimmedRangeEnd], + trimmedIds + } = getTrimmedIdsAndRange( + dep.names, + dep.range, + dep.idRanges, + moduleGraph, + dep + ); + + if (importedModule) { + const usedImported = moduleGraph + .getExportsInfo(importedModule) + .getUsedName(trimmedIds, runtime); + if (usedImported) { + const comment = equals(usedImported, trimmedIds) + ? "" + : `${Template.toNormalComment(propertyAccess(trimmedIds))} `; + const access = `${comment}${propertyAccess(usedImported)}`; + requireExpr = + dep.asiSafe === true + ? `(${requireExpr}${access})` + : `${requireExpr}${access}`; + } + } + source.replace(trimmedRangeStart, trimmedRangeEnd - 1, requireExpr); + } +}; + +makeSerializable( + CommonJsFullRequireDependency, + "webpack/lib/dependencies/CommonJsFullRequireDependency" +); + +module.exports = CommonJsFullRequireDependency; diff --git a/node_modules/webpack/lib/dependencies/CommonJsImportsParserPlugin.js b/node_modules/webpack/lib/dependencies/CommonJsImportsParserPlugin.js new file mode 100644 index 00000000..5044bced --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsImportsParserPlugin.js @@ -0,0 +1,786 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { fileURLToPath } = require("url"); +const CommentCompilationWarning = require("../CommentCompilationWarning"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); +const WebpackError = require("../WebpackError"); +const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression"); +const { + evaluateToIdentifier, + evaluateToString, + expressionIsUnsupported, + toConstantDependency +} = require("../javascript/JavascriptParserHelpers"); +const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency"); +const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency"); +const CommonJsRequireDependency = require("./CommonJsRequireDependency"); +const ConstDependency = require("./ConstDependency"); +const ContextDependencyHelpers = require("./ContextDependencyHelpers"); +const LocalModuleDependency = require("./LocalModuleDependency"); +const { getLocalModule } = require("./LocalModulesHelpers"); +const RequireHeaderDependency = require("./RequireHeaderDependency"); +const RequireResolveContextDependency = require("./RequireResolveContextDependency"); +const RequireResolveDependency = require("./RequireResolveDependency"); +const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency"); + +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").NewExpression} NewExpression */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").ImportSource} ImportSource */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const createRequireSpecifierTag = Symbol("createRequire"); +const createdRequireIdentifierTag = Symbol("createRequire()"); + +class CommonJsImportsParserPlugin { + /** + * @param {JavascriptParserOptions} options parser options + */ + constructor(options) { + this.options = options; + } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + const options = this.options; + + const getContext = () => { + if (parser.currentTagData) { + const { context } = parser.currentTagData; + return context; + } + }; + + // #region metadata + /** + * @param {string} expression expression + * @param {() => string[]} getMembers get members + */ + const tapRequireExpression = (expression, getMembers) => { + parser.hooks.typeof + .for(expression) + .tap( + "CommonJsImportsParserPlugin", + toConstantDependency(parser, JSON.stringify("function")) + ); + parser.hooks.evaluateTypeof + .for(expression) + .tap("CommonJsImportsParserPlugin", evaluateToString("function")); + parser.hooks.evaluateIdentifier + .for(expression) + .tap( + "CommonJsImportsParserPlugin", + evaluateToIdentifier(expression, "require", getMembers, true) + ); + }; + /** + * @param {string | symbol} tag tag + */ + const tapRequireExpressionTag = tag => { + parser.hooks.typeof + .for(tag) + .tap( + "CommonJsImportsParserPlugin", + toConstantDependency(parser, JSON.stringify("function")) + ); + parser.hooks.evaluateTypeof + .for(tag) + .tap("CommonJsImportsParserPlugin", evaluateToString("function")); + }; + tapRequireExpression("require", () => []); + tapRequireExpression("require.resolve", () => ["resolve"]); + tapRequireExpression("require.resolveWeak", () => ["resolveWeak"]); + // #endregion + + // Weird stuff // + parser.hooks.assign + .for("require") + .tap("CommonJsImportsParserPlugin", expr => { + // to not leak to global "require", we need to define a local require here. + const dep = new ConstDependency("var require;", 0); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + + // #region Unsupported + parser.hooks.expression + .for("require.main") + .tap( + "CommonJsImportsParserPlugin", + expressionIsUnsupported( + parser, + "require.main is not supported by webpack." + ) + ); + parser.hooks.call + .for("require.main.require") + .tap( + "CommonJsImportsParserPlugin", + expressionIsUnsupported( + parser, + "require.main.require is not supported by webpack." + ) + ); + parser.hooks.expression + .for("module.parent.require") + .tap( + "CommonJsImportsParserPlugin", + expressionIsUnsupported( + parser, + "module.parent.require is not supported by webpack." + ) + ); + parser.hooks.call + .for("module.parent.require") + .tap( + "CommonJsImportsParserPlugin", + expressionIsUnsupported( + parser, + "module.parent.require is not supported by webpack." + ) + ); + // #endregion + + // #region Renaming + /** + * @param {Expression} expr expression + * @returns {boolean} true when set undefined + */ + const defineUndefined = expr => { + // To avoid "not defined" error, replace the value with undefined + const dep = new ConstDependency( + "undefined", + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return false; + }; + parser.hooks.canRename + .for("require") + .tap("CommonJsImportsParserPlugin", () => true); + parser.hooks.rename + .for("require") + .tap("CommonJsImportsParserPlugin", defineUndefined); + // #endregion + + // #region Inspection + const requireCache = toConstantDependency( + parser, + RuntimeGlobals.moduleCache, + [ + RuntimeGlobals.moduleCache, + RuntimeGlobals.moduleId, + RuntimeGlobals.moduleLoaded + ] + ); + + parser.hooks.expression + .for("require.cache") + .tap("CommonJsImportsParserPlugin", requireCache); + // #endregion + + // #region Require as expression + /** + * @param {Expression} expr expression + * @returns {boolean} true when handled + */ + const requireAsExpressionHandler = expr => { + const dep = new CommonJsRequireContextDependency( + { + request: options.unknownContextRequest, + recursive: options.unknownContextRecursive, + regExp: options.unknownContextRegExp, + mode: "sync" + }, + /** @type {Range} */ (expr.range), + undefined, + parser.scope.inShorthand, + getContext() + ); + dep.critical = + options.unknownContextCritical && + "require function is used in a way in which dependencies cannot be statically extracted"; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + }; + parser.hooks.expression + .for("require") + .tap("CommonJsImportsParserPlugin", requireAsExpressionHandler); + // #endregion + + // #region Require + /** + * @param {CallExpression | NewExpression} expr expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | void} true when handled + */ + const processRequireItem = (expr, param) => { + if (param.isString()) { + const dep = new CommonJsRequireDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (param.range), + getContext() + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + } + }; + /** + * @param {CallExpression | NewExpression} expr expression + * @param {BasicEvaluatedExpression} param param + * @returns {boolean | void} true when handled + */ + const processRequireContext = (expr, param) => { + const dep = ContextDependencyHelpers.create( + CommonJsRequireContextDependency, + /** @type {Range} */ (expr.range), + param, + expr, + options, + { + category: "commonjs" + }, + parser, + undefined, + getContext() + ); + if (!dep) return; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + }; + /** + * @param {boolean} callNew true, when require is called with new + * @returns {(expr: CallExpression | NewExpression) => (boolean | void)} handler + */ + const createRequireHandler = callNew => expr => { + if (options.commonjsMagicComments) { + const { options: requireOptions, errors: commentErrors } = + parser.parseCommentOptions(/** @type {Range} */ (expr.range)); + + if (commentErrors) { + for (const e of commentErrors) { + const { comment } = e; + parser.state.module.addWarning( + new CommentCompilationWarning( + `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`, + comment.loc + ) + ); + } + } + if (requireOptions && requireOptions.webpackIgnore !== undefined) { + if (typeof requireOptions.webpackIgnore !== "boolean") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackIgnore\` expected a boolean, but received: ${requireOptions.webpackIgnore}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else if (requireOptions.webpackIgnore) { + // Do not instrument `require()` if `webpackIgnore` is `true` + return true; + } + } + } + + if (expr.arguments.length !== 1) return; + let localModule; + const param = parser.evaluateExpression(expr.arguments[0]); + if (param.isConditional()) { + let isExpression = false; + for (const p of /** @type {BasicEvaluatedExpression[]} */ ( + param.options + )) { + const result = processRequireItem(expr, p); + if (result === undefined) { + isExpression = true; + } + } + if (!isExpression) { + const dep = new RequireHeaderDependency( + /** @type {Range} */ (expr.callee.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + } + } + if ( + param.isString() && + (localModule = getLocalModule( + parser.state, + /** @type {string} */ (param.string) + )) + ) { + localModule.flagUsed(); + const dep = new LocalModuleDependency( + localModule, + /** @type {Range} */ (expr.range), + callNew + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + } else { + const result = processRequireItem(expr, param); + if (result === undefined) { + processRequireContext(expr, param); + } else { + const dep = new RequireHeaderDependency( + /** @type {Range} */ (expr.callee.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + } + } + return true; + }; + parser.hooks.call + .for("require") + .tap("CommonJsImportsParserPlugin", createRequireHandler(false)); + parser.hooks.new + .for("require") + .tap("CommonJsImportsParserPlugin", createRequireHandler(true)); + parser.hooks.call + .for("module.require") + .tap("CommonJsImportsParserPlugin", createRequireHandler(false)); + parser.hooks.new + .for("module.require") + .tap("CommonJsImportsParserPlugin", createRequireHandler(true)); + // #endregion + + // #region Require with property access + /** + * @param {Expression} expr expression + * @param {string[]} calleeMembers callee members + * @param {CallExpression} callExpr call expression + * @param {string[]} members members + * @param {Range[]} memberRanges member ranges + * @returns {boolean | void} true when handled + */ + const chainHandler = ( + expr, + calleeMembers, + callExpr, + members, + memberRanges + ) => { + if (callExpr.arguments.length !== 1) return; + const param = parser.evaluateExpression(callExpr.arguments[0]); + if ( + param.isString() && + !getLocalModule(parser.state, /** @type {string} */ (param.string)) + ) { + const dep = new CommonJsFullRequireDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range), + members, + /** @type {Range[]} */ memberRanges + ); + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] + ); + dep.optional = Boolean(parser.scope.inTry); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.current.addDependency(dep); + return true; + } + }; + /** + * @param {CallExpression} expr expression + * @param {string[]} calleeMembers callee members + * @param {CallExpression} callExpr call expression + * @param {string[]} members members + * @param {Range[]} memberRanges member ranges + * @returns {boolean | void} true when handled + */ + const callChainHandler = ( + expr, + calleeMembers, + callExpr, + members, + memberRanges + ) => { + if (callExpr.arguments.length !== 1) return; + const param = parser.evaluateExpression(callExpr.arguments[0]); + if ( + param.isString() && + !getLocalModule(parser.state, /** @type {string} */ (param.string)) + ) { + const dep = new CommonJsFullRequireDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.callee.range), + members, + /** @type {Range[]} */ memberRanges + ); + dep.call = true; + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] + ); + dep.optional = Boolean(parser.scope.inTry); + dep.loc = /** @type {DependencyLocation} */ (expr.callee.loc); + parser.state.current.addDependency(dep); + parser.walkExpressions(expr.arguments); + return true; + } + }; + parser.hooks.memberChainOfCallMemberChain + .for("require") + .tap("CommonJsImportsParserPlugin", chainHandler); + parser.hooks.memberChainOfCallMemberChain + .for("module.require") + .tap("CommonJsImportsParserPlugin", chainHandler); + parser.hooks.callMemberChainOfCallMemberChain + .for("require") + .tap("CommonJsImportsParserPlugin", callChainHandler); + parser.hooks.callMemberChainOfCallMemberChain + .for("module.require") + .tap("CommonJsImportsParserPlugin", callChainHandler); + // #endregion + + // #region Require.resolve + /** + * @param {CallExpression} expr call expression + * @param {boolean} weak weak + * @returns {boolean | void} true when handled + */ + const processResolve = (expr, weak) => { + if (expr.arguments.length !== 1) return; + const param = parser.evaluateExpression(expr.arguments[0]); + if (param.isConditional()) { + for (const option of /** @type {BasicEvaluatedExpression[]} */ ( + param.options + )) { + const result = processResolveItem(expr, option, weak); + if (result === undefined) { + processResolveContext(expr, option, weak); + } + } + const dep = new RequireResolveHeaderDependency( + /** @type {Range} */ (expr.callee.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + } + const result = processResolveItem(expr, param, weak); + if (result === undefined) { + processResolveContext(expr, param, weak); + } + const dep = new RequireResolveHeaderDependency( + /** @type {Range} */ (expr.callee.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }; + /** + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @param {boolean} weak weak + * @returns {boolean | void} true when handled + */ + const processResolveItem = (expr, param, weak) => { + if (param.isString()) { + const dep = new RequireResolveDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (param.range), + getContext() + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + dep.weak = weak; + parser.state.current.addDependency(dep); + return true; + } + }; + /** + * @param {CallExpression} expr call expression + * @param {BasicEvaluatedExpression} param param + * @param {boolean} weak weak + * @returns {boolean | void} true when handled + */ + const processResolveContext = (expr, param, weak) => { + const dep = ContextDependencyHelpers.create( + RequireResolveContextDependency, + /** @type {Range} */ (param.range), + param, + expr, + options, + { + category: "commonjs", + mode: weak ? "weak" : "sync" + }, + parser, + getContext() + ); + if (!dep) return; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + }; + + parser.hooks.call + .for("require.resolve") + .tap("CommonJsImportsParserPlugin", expr => processResolve(expr, false)); + parser.hooks.call + .for("require.resolveWeak") + .tap("CommonJsImportsParserPlugin", expr => processResolve(expr, true)); + // #endregion + + // #region Create require + + if (!options.createRequire) return; + + /** @type {ImportSource[]} */ + let moduleName = []; + /** @type {string | undefined} */ + let specifierName; + + if (options.createRequire === true) { + moduleName = ["module", "node:module"]; + specifierName = "createRequire"; + } else { + let moduleName; + const match = /^(.*) from (.*)$/.exec(options.createRequire); + if (match) { + [, specifierName, moduleName] = match; + } + if (!specifierName || !moduleName) { + const err = new WebpackError( + `Parsing javascript parser option "createRequire" failed, got ${JSON.stringify( + options.createRequire + )}` + ); + err.details = + 'Expected string in format "createRequire from module", where "createRequire" is specifier name and "module" name of the module'; + throw err; + } + } + + tapRequireExpressionTag(createdRequireIdentifierTag); + tapRequireExpressionTag(createRequireSpecifierTag); + parser.hooks.evaluateCallExpression + .for(createRequireSpecifierTag) + .tap("CommonJsImportsParserPlugin", expr => { + const context = parseCreateRequireArguments(expr); + if (context === undefined) return; + const ident = parser.evaluatedVariable({ + tag: createdRequireIdentifierTag, + data: { context }, + next: undefined + }); + return new BasicEvaluatedExpression() + .setIdentifier( + /** @type {TODO} */ (ident), + /** @type {TODO} */ (ident), + () => [] + ) + .setSideEffects(false) + .setRange(/** @type {Range} */ (expr.range)); + }); + parser.hooks.unhandledExpressionMemberChain + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", (expr, members) => + expressionIsUnsupported( + parser, + `createRequire().${members.join(".")} is not supported by webpack.` + )(expr) + ); + parser.hooks.canRename + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", () => true); + parser.hooks.canRename + .for(createRequireSpecifierTag) + .tap("CommonJsImportsParserPlugin", () => true); + parser.hooks.rename + .for(createRequireSpecifierTag) + .tap("CommonJsImportsParserPlugin", defineUndefined); + parser.hooks.expression + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", requireAsExpressionHandler); + parser.hooks.call + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", createRequireHandler(false)); + /** + * @param {CallExpression} expr call expression + * @returns {string | void} context + */ + const parseCreateRequireArguments = expr => { + const args = expr.arguments; + if (args.length !== 1) { + const err = new WebpackError( + "module.createRequire supports only one argument." + ); + err.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addWarning(err); + return; + } + const arg = args[0]; + const evaluated = parser.evaluateExpression(arg); + if (!evaluated.isString()) { + const err = new WebpackError( + "module.createRequire failed parsing argument." + ); + err.loc = /** @type {DependencyLocation} */ (arg.loc); + parser.state.module.addWarning(err); + return; + } + const ctx = /** @type {string} */ (evaluated.string).startsWith("file://") + ? fileURLToPath(/** @type {string} */ (evaluated.string)) + : /** @type {string} */ (evaluated.string); + // argument always should be a filename + return ctx.slice(0, ctx.lastIndexOf(ctx.startsWith("/") ? "/" : "\\")); + }; + + parser.hooks.import.tap( + { + name: "CommonJsImportsParserPlugin", + stage: -10 + }, + (statement, source) => { + if ( + !moduleName.includes(source) || + statement.specifiers.length !== 1 || + statement.specifiers[0].type !== "ImportSpecifier" || + statement.specifiers[0].imported.type !== "Identifier" || + statement.specifiers[0].imported.name !== specifierName + ) + return; + // clear for 'import { createRequire as x } from "module"' + // if any other specifier was used import module + const clearDep = new ConstDependency( + parser.isAsiPosition(/** @type {Range} */ (statement.range)[0]) + ? ";" + : "", + /** @type {Range} */ (statement.range) + ); + clearDep.loc = /** @type {DependencyLocation} */ (statement.loc); + parser.state.module.addPresentationalDependency(clearDep); + parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]); + return true; + } + ); + parser.hooks.importSpecifier.tap( + { + name: "CommonJsImportsParserPlugin", + stage: -10 + }, + (statement, source, id, name) => { + if (!moduleName.includes(source) || id !== specifierName) return; + parser.tagVariable(name, createRequireSpecifierTag); + return true; + } + ); + parser.hooks.preDeclarator.tap( + "CommonJsImportsParserPlugin", + declarator => { + if ( + declarator.id.type !== "Identifier" || + !declarator.init || + declarator.init.type !== "CallExpression" || + declarator.init.callee.type !== "Identifier" + ) + return; + const variableInfo = + /** @type {TODO} */ + (parser.getVariableInfo(declarator.init.callee.name)); + if ( + variableInfo && + variableInfo.tagInfo && + variableInfo.tagInfo.tag === createRequireSpecifierTag + ) { + const context = parseCreateRequireArguments(declarator.init); + if (context === undefined) return; + parser.tagVariable(declarator.id.name, createdRequireIdentifierTag, { + name: declarator.id.name, + context + }); + return true; + } + } + ); + + parser.hooks.memberChainOfCallMemberChain + .for(createRequireSpecifierTag) + .tap( + "CommonJsImportsParserPlugin", + (expr, calleeMembers, callExpr, members) => { + if ( + calleeMembers.length !== 0 || + members.length !== 1 || + members[0] !== "cache" + ) + return; + // createRequire().cache + const context = parseCreateRequireArguments(callExpr); + if (context === undefined) return; + return requireCache(expr); + } + ); + parser.hooks.callMemberChainOfCallMemberChain + .for(createRequireSpecifierTag) + .tap( + "CommonJsImportsParserPlugin", + (expr, calleeMembers, innerCallExpression, members) => { + if ( + calleeMembers.length !== 0 || + members.length !== 1 || + members[0] !== "resolve" + ) + return; + // createRequire().resolve() + return processResolve(expr, false); + } + ); + parser.hooks.expressionMemberChain + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", (expr, members) => { + // require.cache + if (members.length === 1 && members[0] === "cache") { + return requireCache(expr); + } + }); + parser.hooks.callMemberChain + .for(createdRequireIdentifierTag) + .tap("CommonJsImportsParserPlugin", (expr, members) => { + // require.resolve() + if (members.length === 1 && members[0] === "resolve") { + return processResolve(expr, false); + } + }); + parser.hooks.call + .for(createRequireSpecifierTag) + .tap("CommonJsImportsParserPlugin", expr => { + const clearDep = new ConstDependency( + "/* createRequire() */ undefined", + /** @type {Range} */ (expr.range) + ); + clearDep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(clearDep); + return true; + }); + // #endregion + } +} +module.exports = CommonJsImportsParserPlugin; diff --git a/node_modules/webpack/lib/dependencies/CommonJsPlugin.js b/node_modules/webpack/lib/dependencies/CommonJsPlugin.js new file mode 100644 index 00000000..b148b17b --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsPlugin.js @@ -0,0 +1,305 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); +const SelfModuleFactory = require("../SelfModuleFactory"); +const Template = require("../Template"); +const CommonJsExportsDependency = require("./CommonJsExportsDependency"); +const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency"); +const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency"); +const CommonJsRequireDependency = require("./CommonJsRequireDependency"); +const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency"); +const ModuleDecoratorDependency = require("./ModuleDecoratorDependency"); +const RequireHeaderDependency = require("./RequireHeaderDependency"); +const RequireResolveContextDependency = require("./RequireResolveContextDependency"); +const RequireResolveDependency = require("./RequireResolveDependency"); +const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency"); +const RuntimeRequirementsDependency = require("./RuntimeRequirementsDependency"); + +const CommonJsExportsParserPlugin = require("./CommonJsExportsParserPlugin"); +const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin"); + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); +const { + evaluateToIdentifier, + toConstantDependency +} = require("../javascript/JavascriptParserHelpers"); +const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "CommonJsPlugin"; + +class CommonJsPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { contextModuleFactory, normalModuleFactory }) => { + compilation.dependencyFactories.set( + CommonJsRequireDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + CommonJsRequireDependency, + new CommonJsRequireDependency.Template() + ); + + compilation.dependencyFactories.set( + CommonJsFullRequireDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + CommonJsFullRequireDependency, + new CommonJsFullRequireDependency.Template() + ); + + compilation.dependencyFactories.set( + CommonJsRequireContextDependency, + contextModuleFactory + ); + compilation.dependencyTemplates.set( + CommonJsRequireContextDependency, + new CommonJsRequireContextDependency.Template() + ); + + compilation.dependencyFactories.set( + RequireResolveDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + RequireResolveDependency, + new RequireResolveDependency.Template() + ); + + compilation.dependencyFactories.set( + RequireResolveContextDependency, + contextModuleFactory + ); + compilation.dependencyTemplates.set( + RequireResolveContextDependency, + new RequireResolveContextDependency.Template() + ); + + compilation.dependencyTemplates.set( + RequireResolveHeaderDependency, + new RequireResolveHeaderDependency.Template() + ); + + compilation.dependencyTemplates.set( + RequireHeaderDependency, + new RequireHeaderDependency.Template() + ); + + compilation.dependencyTemplates.set( + CommonJsExportsDependency, + new CommonJsExportsDependency.Template() + ); + + compilation.dependencyFactories.set( + CommonJsExportRequireDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + CommonJsExportRequireDependency, + new CommonJsExportRequireDependency.Template() + ); + + const selfFactory = new SelfModuleFactory(compilation.moduleGraph); + + compilation.dependencyFactories.set( + CommonJsSelfReferenceDependency, + selfFactory + ); + compilation.dependencyTemplates.set( + CommonJsSelfReferenceDependency, + new CommonJsSelfReferenceDependency.Template() + ); + + compilation.dependencyFactories.set( + ModuleDecoratorDependency, + selfFactory + ); + compilation.dependencyTemplates.set( + ModuleDecoratorDependency, + new ModuleDecoratorDependency.Template() + ); + + compilation.hooks.runtimeRequirementInModule + .for(RuntimeGlobals.harmonyModuleDecorator) + .tap(PLUGIN_NAME, (module, set) => { + set.add(RuntimeGlobals.module); + set.add(RuntimeGlobals.requireScope); + }); + + compilation.hooks.runtimeRequirementInModule + .for(RuntimeGlobals.nodeModuleDecorator) + .tap(PLUGIN_NAME, (module, set) => { + set.add(RuntimeGlobals.module); + set.add(RuntimeGlobals.requireScope); + }); + + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.harmonyModuleDecorator) + .tap(PLUGIN_NAME, (chunk, set) => { + compilation.addRuntimeModule( + chunk, + new HarmonyModuleDecoratorRuntimeModule() + ); + }); + + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.nodeModuleDecorator) + .tap(PLUGIN_NAME, (chunk, set) => { + compilation.addRuntimeModule( + chunk, + new NodeModuleDecoratorRuntimeModule() + ); + }); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + if (parserOptions.commonjs !== undefined && !parserOptions.commonjs) + return; + parser.hooks.typeof + .for("module") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("object")) + ); + + parser.hooks.expression + .for("require.main") + .tap( + PLUGIN_NAME, + toConstantDependency( + parser, + `${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}]`, + [RuntimeGlobals.moduleCache, RuntimeGlobals.entryModuleId] + ) + ); + parser.hooks.expression + .for(RuntimeGlobals.moduleLoaded) + .tap(PLUGIN_NAME, expr => { + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).moduleConcatenationBailout = + RuntimeGlobals.moduleLoaded; + const dep = new RuntimeRequirementsDependency([ + RuntimeGlobals.moduleLoaded + ]); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + + parser.hooks.expression + .for(RuntimeGlobals.moduleId) + .tap(PLUGIN_NAME, expr => { + /** @type {BuildInfo} */ + (parser.state.module.buildInfo).moduleConcatenationBailout = + RuntimeGlobals.moduleId; + const dep = new RuntimeRequirementsDependency([ + RuntimeGlobals.moduleId + ]); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + + parser.hooks.evaluateIdentifier.for("module.hot").tap( + PLUGIN_NAME, + evaluateToIdentifier("module.hot", "module", () => ["hot"], null) + ); + + new CommonJsImportsParserPlugin(parserOptions).apply(parser); + new CommonJsExportsParserPlugin(compilation.moduleGraph).apply( + parser + ); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); + } + ); + } +} + +class HarmonyModuleDecoratorRuntimeModule extends RuntimeModule { + constructor() { + super("harmony module decorator"); + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const { runtimeTemplate } = /** @type {Compilation} */ (this.compilation); + return Template.asString([ + `${ + RuntimeGlobals.harmonyModuleDecorator + } = ${runtimeTemplate.basicFunction("module", [ + "module = Object.create(module);", + "if (!module.children) module.children = [];", + "Object.defineProperty(module, 'exports', {", + Template.indent([ + "enumerable: true,", + `set: ${runtimeTemplate.basicFunction("", [ + "throw new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);" + ])}` + ]), + "});", + "return module;" + ])};` + ]); + } +} + +class NodeModuleDecoratorRuntimeModule extends RuntimeModule { + constructor() { + super("node module decorator"); + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const { runtimeTemplate } = /** @type {Compilation} */ (this.compilation); + return Template.asString([ + `${RuntimeGlobals.nodeModuleDecorator} = ${runtimeTemplate.basicFunction( + "module", + [ + "module.paths = [];", + "if (!module.children) module.children = [];", + "return module;" + ] + )};` + ]); + } +} + +module.exports = CommonJsPlugin; diff --git a/node_modules/webpack/lib/dependencies/CommonJsRequireContextDependency.js b/node_modules/webpack/lib/dependencies/CommonJsRequireContextDependency.js new file mode 100644 index 00000000..14e64285 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsRequireContextDependency.js @@ -0,0 +1,72 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ContextDependency = require("./ContextDependency"); +const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class CommonJsRequireContextDependency extends ContextDependency { + /** + * @param {TODO} options options for the context module + * @param {Range} range location in source code + * @param {Range | undefined} valueRange location of the require call + * @param {boolean | string } inShorthand true or name + * @param {string} context context + */ + constructor(options, range, valueRange, inShorthand, context) { + super(options, context); + + this.range = range; + this.valueRange = valueRange; + // inShorthand must be serialized by subclasses that use it + this.inShorthand = inShorthand; + } + + get type() { + return "cjs require context"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.range); + write(this.valueRange); + write(this.inShorthand); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.range = read(); + this.valueRange = read(); + this.inShorthand = read(); + + super.deserialize(context); + } +} + +makeSerializable( + CommonJsRequireContextDependency, + "webpack/lib/dependencies/CommonJsRequireContextDependency" +); + +CommonJsRequireContextDependency.Template = + ContextDependencyTemplateAsRequireCall; + +module.exports = CommonJsRequireContextDependency; diff --git a/node_modules/webpack/lib/dependencies/CommonJsRequireDependency.js b/node_modules/webpack/lib/dependencies/CommonJsRequireDependency.js new file mode 100644 index 00000000..09545a86 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsRequireDependency.js @@ -0,0 +1,42 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); +const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class CommonJsRequireDependency extends ModuleDependency { + /** + * @param {string} request request + * @param {Range=} range location in source code + * @param {string=} context request context + */ + constructor(request, range, context) { + super(request); + this.range = range; + this._context = context; + } + + get type() { + return "cjs require"; + } + + get category() { + return "commonjs"; + } +} + +CommonJsRequireDependency.Template = ModuleDependencyTemplateAsId; + +makeSerializable( + CommonJsRequireDependency, + "webpack/lib/dependencies/CommonJsRequireDependency" +); + +module.exports = CommonJsRequireDependency; diff --git a/node_modules/webpack/lib/dependencies/CommonJsSelfReferenceDependency.js b/node_modules/webpack/lib/dependencies/CommonJsSelfReferenceDependency.js new file mode 100644 index 00000000..b1b368ea --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CommonJsSelfReferenceDependency.js @@ -0,0 +1,155 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const { equals } = require("../util/ArrayHelpers"); +const makeSerializable = require("../util/makeSerializable"); +const propertyAccess = require("../util/propertyAccess"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {import("./CommonJsDependencyHelpers").CommonJSDependencyBaseKeywords} CommonJSDependencyBaseKeywords */ + +class CommonJsSelfReferenceDependency extends NullDependency { + /** + * @param {Range} range range + * @param {CommonJSDependencyBaseKeywords} base base + * @param {string[]} names names + * @param {boolean} call is a call + */ + constructor(range, base, names, call) { + super(); + this.range = range; + this.base = base; + this.names = names; + this.call = call; + } + + get type() { + return "cjs self exports reference"; + } + + get category() { + return "self"; + } + + /** + * @returns {string | null} an identifier to merge equal requests + */ + getResourceIdentifier() { + return "self"; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + return [this.call ? this.names.slice(0, -1) : this.names]; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + write(this.base); + write(this.names); + write(this.call); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.range = read(); + this.base = read(); + this.names = read(); + this.call = read(); + super.deserialize(context); + } +} + +makeSerializable( + CommonJsSelfReferenceDependency, + "webpack/lib/dependencies/CommonJsSelfReferenceDependency" +); + +CommonJsSelfReferenceDependency.Template = class CommonJsSelfReferenceDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { module, moduleGraph, runtime, runtimeRequirements } + ) { + const dep = /** @type {CommonJsSelfReferenceDependency} */ (dependency); + const used = + dep.names.length === 0 + ? dep.names + : moduleGraph.getExportsInfo(module).getUsedName(dep.names, runtime); + if (!used) { + throw new Error( + "Self-reference dependency has unused export name: This should not happen" + ); + } + + let base; + switch (dep.base) { + case "exports": + runtimeRequirements.add(RuntimeGlobals.exports); + base = module.exportsArgument; + break; + case "module.exports": + runtimeRequirements.add(RuntimeGlobals.module); + base = `${module.moduleArgument}.exports`; + break; + case "this": + runtimeRequirements.add(RuntimeGlobals.thisAsExports); + base = "this"; + break; + default: + throw new Error(`Unsupported base ${dep.base}`); + } + + if (base === dep.base && equals(used, dep.names)) { + // Nothing has to be changed + // We don't use a replacement for compat reasons + // for plugins that update `module._source` which they + // shouldn't do! + return; + } + + source.replace( + dep.range[0], + dep.range[1] - 1, + `${base}${propertyAccess(used)}` + ); + } +}; + +module.exports = CommonJsSelfReferenceDependency; diff --git a/node_modules/webpack/lib/dependencies/ConstDependency.js b/node_modules/webpack/lib/dependencies/ConstDependency.js new file mode 100644 index 00000000..e41acef3 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ConstDependency.js @@ -0,0 +1,117 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +class ConstDependency extends NullDependency { + /** + * @param {string} expression the expression + * @param {number | Range} range the source range + * @param {(string[] | null)=} runtimeRequirements runtime requirements + */ + constructor(expression, range, runtimeRequirements) { + super(); + this.expression = expression; + this.range = range; + this.runtimeRequirements = runtimeRequirements + ? new Set(runtimeRequirements) + : null; + this._hashUpdate = undefined; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + if (this._hashUpdate === undefined) { + let hashUpdate = `${this.range}|${this.expression}`; + if (this.runtimeRequirements) { + for (const item of this.runtimeRequirements) { + hashUpdate += "|"; + hashUpdate += item; + } + } + this._hashUpdate = hashUpdate; + } + hash.update(this._hashUpdate); + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {ConnectionState} how this dependency connects the module to referencing modules + */ + getModuleEvaluationSideEffectsState(moduleGraph) { + return false; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.expression); + write(this.range); + write(this.runtimeRequirements); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.expression = read(); + this.range = read(); + this.runtimeRequirements = read(); + super.deserialize(context); + } +} + +makeSerializable(ConstDependency, "webpack/lib/dependencies/ConstDependency"); + +ConstDependency.Template = class ConstDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {ConstDependency} */ (dependency); + if (dep.runtimeRequirements) { + for (const req of dep.runtimeRequirements) { + templateContext.runtimeRequirements.add(req); + } + } + if (typeof dep.range === "number") { + source.insert(dep.range, dep.expression); + return; + } + + source.replace(dep.range[0], dep.range[1] - 1, dep.expression); + } +}; + +module.exports = ConstDependency; diff --git a/node_modules/webpack/lib/dependencies/ContextDependency.js b/node_modules/webpack/lib/dependencies/ContextDependency.js new file mode 100644 index 00000000..fb12467d --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ContextDependency.js @@ -0,0 +1,173 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const DependencyTemplate = require("../DependencyTemplate"); +const makeSerializable = require("../util/makeSerializable"); +const memoize = require("../util/memoize"); + +/** @typedef {import("../ContextModule").ContextOptions} ContextOptions */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +const getCriticalDependencyWarning = memoize(() => + require("./CriticalDependencyWarning") +); + +/** @typedef {ContextOptions & { request: string }} ContextDependencyOptions */ + +/** + * @param {RegExp | null | undefined} r regexp + * @returns {string} stringified regexp + */ +const regExpToString = r => (r ? String(r) : ""); + +class ContextDependency extends Dependency { + /** + * @param {ContextDependencyOptions} options options for the context module + * @param {string=} context request context + */ + constructor(options, context) { + super(); + + this.options = options; + this.userRequest = this.options && this.options.request; + /** @type {false | undefined | string} */ + this.critical = false; + this.hadGlobalOrStickyRegExp = false; + + if ( + this.options && + (this.options.regExp.global || this.options.regExp.sticky) + ) { + this.options = { ...this.options, regExp: null }; + this.hadGlobalOrStickyRegExp = true; + } + + this.request = undefined; + this.range = undefined; + this.valueRange = undefined; + /** @type {boolean | string | undefined} */ + this.inShorthand = undefined; + // TODO refactor this + this.replaces = undefined; + this._requestContext = context; + } + + /** + * @returns {string | undefined} a request context + */ + getContext() { + return this._requestContext; + } + + get category() { + return "commonjs"; + } + + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return true; + } + + /** + * @returns {string | null} an identifier to merge equal requests + */ + getResourceIdentifier() { + return ( + `context${this._requestContext || ""}|ctx request${ + this.options.request + } ${this.options.recursive} ` + + `${regExpToString(this.options.regExp)} ${regExpToString( + this.options.include + )} ${regExpToString(this.options.exclude)} ` + + `${this.options.mode} ${this.options.chunkName} ` + + `${JSON.stringify(this.options.groupOptions)}` + ); + } + + /** + * Returns warnings + * @param {ModuleGraph} moduleGraph module graph + * @returns {WebpackError[] | null | undefined} warnings + */ + getWarnings(moduleGraph) { + let warnings = super.getWarnings(moduleGraph); + + if (this.critical) { + if (!warnings) warnings = []; + const CriticalDependencyWarning = getCriticalDependencyWarning(); + warnings.push(new CriticalDependencyWarning(this.critical)); + } + + if (this.hadGlobalOrStickyRegExp) { + if (!warnings) warnings = []; + const CriticalDependencyWarning = getCriticalDependencyWarning(); + warnings.push( + new CriticalDependencyWarning( + "Contexts can't use RegExps with the 'g' or 'y' flags." + ) + ); + } + + return warnings; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.options); + write(this.userRequest); + write(this.critical); + write(this.hadGlobalOrStickyRegExp); + write(this.request); + write(this._requestContext); + write(this.range); + write(this.valueRange); + write(this.prepend); + write(this.replaces); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.options = read(); + this.userRequest = read(); + this.critical = read(); + this.hadGlobalOrStickyRegExp = read(); + this.request = read(); + this._requestContext = read(); + this.range = read(); + this.valueRange = read(); + this.prepend = read(); + this.replaces = read(); + + super.deserialize(context); + } +} + +makeSerializable( + ContextDependency, + "webpack/lib/dependencies/ContextDependency" +); + +ContextDependency.Template = DependencyTemplate; + +module.exports = ContextDependency; diff --git a/node_modules/webpack/lib/dependencies/ContextDependencyHelpers.js b/node_modules/webpack/lib/dependencies/ContextDependencyHelpers.js new file mode 100644 index 00000000..ed635328 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ContextDependencyHelpers.js @@ -0,0 +1,262 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { parseResource } = require("../util/identifier"); + +/** @typedef {import("estree").Node} EsTreeNode */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("./ContextDependency")} ContextDependency */ +/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */ + +/** + * Escapes regular expression metacharacters + * @param {string} str String to quote + * @returns {string} Escaped string + */ +const quoteMeta = str => str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&"); + +/** + * @param {string} prefix prefix + * @returns {{prefix: string, context: string}} result + */ +const splitContextFromPrefix = prefix => { + const idx = prefix.lastIndexOf("/"); + let context = "."; + if (idx >= 0) { + context = prefix.slice(0, idx); + prefix = `.${prefix.slice(idx)}`; + } + return { + context, + prefix + }; +}; + +/** @typedef {Partial<Omit<ContextDependencyOptions, "resource">>} PartialContextDependencyOptions */ +/** @typedef {{ new(options: ContextDependencyOptions, range: Range, valueRange: [number, number], ...args: any[]): ContextDependency }} ContextDependencyConstructor */ + +/** + * @param {ContextDependencyConstructor} Dep the Dependency class + * @param {Range} range source range + * @param {BasicEvaluatedExpression} param context param + * @param {EsTreeNode} expr expr + * @param {Pick<JavascriptParserOptions, `${"expr"|"wrapped"}Context${"Critical"|"Recursive"|"RegExp"}` | "exprContextRequest">} options options for context creation + * @param {PartialContextDependencyOptions} contextOptions options for the ContextModule + * @param {JavascriptParser} parser the parser + * @param {...any} depArgs depArgs + * @returns {ContextDependency} the created Dependency + */ +module.exports.create = ( + Dep, + range, + param, + expr, + options, + contextOptions, + parser, + ...depArgs +) => { + if (param.isTemplateString()) { + const quasis = /** @type {BasicEvaluatedExpression[]} */ (param.quasis); + const prefixRaw = /** @type {string} */ (quasis[0].string); + const postfixRaw = + /** @type {string} */ + (quasis.length > 1 ? quasis[quasis.length - 1].string : ""); + + const valueRange = /** @type {Range} */ (param.range); + const { context, prefix } = splitContextFromPrefix(prefixRaw); + const { + path: postfix, + query, + fragment + } = parseResource(postfixRaw, parser); + + // When there are more than two quasis, the generated RegExp can be more precise + // We join the quasis with the expression regexp + const innerQuasis = quasis.slice(1, -1); + const innerRegExp = + /** @type {RegExp} */ (options.wrappedContextRegExp).source + + innerQuasis + .map( + q => + quoteMeta(/** @type {string} */ (q.string)) + + /** @type {RegExp} */ (options.wrappedContextRegExp).source + ) + .join(""); + + // Example: `./context/pre${e}inner${e}inner2${e}post?query#frag` + // context: "./context" + // prefix: "./pre" + // innerQuasis: [BEE("inner"), BEE("inner2")] + // (BEE = BasicEvaluatedExpression) + // postfix: "post" + // query: "?query" + // fragment: "#frag" + // regExp: /^\.\/pre.*inner.*inner2.*post$/ + const regExp = new RegExp( + `^${quoteMeta(prefix)}${innerRegExp}${quoteMeta(postfix)}$` + ); + const dep = new Dep( + { + request: context + query + fragment, + recursive: /** @type {boolean} */ (options.wrappedContextRecursive), + regExp, + mode: "sync", + ...contextOptions + }, + range, + valueRange, + ...depArgs + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + + /** @type {{ value: string, range: Range }[]} */ + const replaces = []; + const parts = /** @type {BasicEvaluatedExpression[]} */ (param.parts); + + for (const [i, part] of parts.entries()) { + if (i % 2 === 0) { + // Quasis or merged quasi + let range = /** @type {Range} */ (part.range); + let value = /** @type {string} */ (part.string); + if (param.templateStringKind === "cooked") { + value = JSON.stringify(value); + value = value.slice(1, -1); + } + if (i === 0) { + // prefix + value = prefix; + range = [ + /** @type {Range} */ (param.range)[0], + /** @type {Range} */ (part.range)[1] + ]; + value = + (param.templateStringKind === "cooked" ? "`" : "String.raw`") + + value; + } else if (i === parts.length - 1) { + // postfix + value = postfix; + range = [ + /** @type {Range} */ (part.range)[0], + /** @type {Range} */ (param.range)[1] + ]; + value = `${value}\``; + } else if ( + part.expression && + part.expression.type === "TemplateElement" && + part.expression.value.raw === value + ) { + // Shortcut when it's a single quasi and doesn't need to be replaced + continue; + } + replaces.push({ + range, + value + }); + } else { + // Expression + parser.walkExpression(part.expression); + } + } + + dep.replaces = replaces; + dep.critical = + options.wrappedContextCritical && + "a part of the request of a dependency is an expression"; + return dep; + } else if ( + param.isWrapped() && + ((param.prefix && param.prefix.isString()) || + (param.postfix && param.postfix.isString())) + ) { + const prefixRaw = + /** @type {string} */ + (param.prefix && param.prefix.isString() ? param.prefix.string : ""); + const postfixRaw = + /** @type {string} */ + (param.postfix && param.postfix.isString() ? param.postfix.string : ""); + const prefixRange = + param.prefix && param.prefix.isString() ? param.prefix.range : null; + const postfixRange = + param.postfix && param.postfix.isString() ? param.postfix.range : null; + const valueRange = /** @type {Range} */ (param.range); + const { context, prefix } = splitContextFromPrefix(prefixRaw); + const { + path: postfix, + query, + fragment + } = parseResource(postfixRaw, parser); + const regExp = new RegExp( + `^${quoteMeta(prefix)}${ + /** @type {RegExp} */ (options.wrappedContextRegExp).source + }${quoteMeta(postfix)}$` + ); + const dep = new Dep( + { + request: context + query + fragment, + recursive: /** @type {boolean} */ (options.wrappedContextRecursive), + regExp, + mode: "sync", + ...contextOptions + }, + range, + valueRange, + ...depArgs + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + const replaces = []; + if (prefixRange) { + replaces.push({ + range: prefixRange, + value: JSON.stringify(prefix) + }); + } + if (postfixRange) { + replaces.push({ + range: postfixRange, + value: JSON.stringify(postfix) + }); + } + dep.replaces = replaces; + dep.critical = + options.wrappedContextCritical && + "a part of the request of a dependency is an expression"; + + if (parser && param.wrappedInnerExpressions) { + for (const part of param.wrappedInnerExpressions) { + if (part.expression) parser.walkExpression(part.expression); + } + } + + return dep; + } + const dep = new Dep( + { + request: /** @type {string} */ (options.exprContextRequest), + recursive: /** @type {boolean} */ (options.exprContextRecursive), + regExp: /** @type {RegExp} */ (options.exprContextRegExp), + mode: "sync", + ...contextOptions + }, + range, + /** @type {Range} */ (param.range), + ...depArgs + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.critical = + options.exprContextCritical && + "the request of a dependency is an expression"; + + parser.walkExpression(param.expression); + + return dep; +}; diff --git a/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsId.js b/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsId.js new file mode 100644 index 00000000..c5d9a5a8 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsId.js @@ -0,0 +1,61 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ContextDependency = require("./ContextDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ + +class ContextDependencyTemplateAsId extends ContextDependency.Template { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } + ) { + const dep = /** @type {ContextDependency} */ (dependency); + const moduleExports = runtimeTemplate.moduleExports({ + module: moduleGraph.getModule(dep), + chunkGraph, + request: dep.request, + weak: dep.weak, + runtimeRequirements + }); + + if (moduleGraph.getModule(dep)) { + if (dep.valueRange) { + if (Array.isArray(dep.replaces)) { + for (let i = 0; i < dep.replaces.length; i++) { + const rep = dep.replaces[i]; + source.replace(rep.range[0], rep.range[1] - 1, rep.value); + } + } + source.replace(dep.valueRange[1], dep.range[1] - 1, ")"); + source.replace( + dep.range[0], + dep.valueRange[0] - 1, + `${moduleExports}.resolve(` + ); + } else { + source.replace( + dep.range[0], + dep.range[1] - 1, + `${moduleExports}.resolve` + ); + } + } else { + source.replace(dep.range[0], dep.range[1] - 1, moduleExports); + } + } +} +module.exports = ContextDependencyTemplateAsId; diff --git a/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsRequireCall.js b/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsRequireCall.js new file mode 100644 index 00000000..8907f9f5 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ContextDependencyTemplateAsRequireCall.js @@ -0,0 +1,59 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ContextDependency = require("./ContextDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ + +class ContextDependencyTemplateAsRequireCall extends ContextDependency.Template { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } + ) { + const dep = /** @type {ContextDependency} */ (dependency); + let moduleExports = runtimeTemplate.moduleExports({ + module: moduleGraph.getModule(dep), + chunkGraph, + request: dep.request, + runtimeRequirements + }); + + if (dep.inShorthand) { + moduleExports = `${dep.inShorthand}: ${moduleExports}`; + } + if (moduleGraph.getModule(dep)) { + if (dep.valueRange) { + if (Array.isArray(dep.replaces)) { + for (let i = 0; i < dep.replaces.length; i++) { + const rep = dep.replaces[i]; + source.replace(rep.range[0], rep.range[1] - 1, rep.value); + } + } + source.replace(dep.valueRange[1], dep.range[1] - 1, ")"); + source.replace( + dep.range[0], + dep.valueRange[0] - 1, + `${moduleExports}(` + ); + } else { + source.replace(dep.range[0], dep.range[1] - 1, moduleExports); + } + } else { + source.replace(dep.range[0], dep.range[1] - 1, moduleExports); + } + } +} +module.exports = ContextDependencyTemplateAsRequireCall; diff --git a/node_modules/webpack/lib/dependencies/ContextElementDependency.js b/node_modules/webpack/lib/dependencies/ContextElementDependency.js new file mode 100644 index 00000000..448ef7c2 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ContextElementDependency.js @@ -0,0 +1,108 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class ContextElementDependency extends ModuleDependency { + /** + * @param {string} request request + * @param {string|undefined} userRequest user request + * @param {string | undefined} typePrefix type prefix + * @param {string} category category + * @param {(string[][] | null)=} referencedExports referenced exports + * @param {string=} context context + * @param {ImportAttributes=} attributes import assertions + */ + constructor( + request, + userRequest, + typePrefix, + category, + referencedExports, + context, + attributes + ) { + super(request); + this.referencedExports = referencedExports; + this._typePrefix = typePrefix; + this._category = category; + this._context = context || undefined; + + if (userRequest) { + this.userRequest = userRequest; + } + + this.assertions = attributes; + } + + get type() { + if (this._typePrefix) { + return `${this._typePrefix} context element`; + } + + return "context element"; + } + + get category() { + return this._category; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + return this.referencedExports + ? this.referencedExports.map(e => ({ + name: e, + canMangle: false + })) + : Dependency.EXPORTS_OBJECT_REFERENCED; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this._typePrefix); + write(this._category); + write(this.referencedExports); + write(this.assertions); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this._typePrefix = read(); + this._category = read(); + this.referencedExports = read(); + this.assertions = read(); + super.deserialize(context); + } +} + +makeSerializable( + ContextElementDependency, + "webpack/lib/dependencies/ContextElementDependency" +); + +module.exports = ContextElementDependency; diff --git a/node_modules/webpack/lib/dependencies/CreateScriptUrlDependency.js b/node_modules/webpack/lib/dependencies/CreateScriptUrlDependency.js new file mode 100644 index 00000000..9abb5c50 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CreateScriptUrlDependency.js @@ -0,0 +1,75 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class CreateScriptUrlDependency extends NullDependency { + /** + * @param {Range} range range + */ + constructor(range) { + super(); + this.range = range; + } + + get type() { + return "create script url"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.range = read(); + super.deserialize(context); + } +} + +CreateScriptUrlDependency.Template = class CreateScriptUrlDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { runtimeRequirements }) { + const dep = /** @type {CreateScriptUrlDependency} */ (dependency); + + runtimeRequirements.add(RuntimeGlobals.createScriptUrl); + + source.insert(dep.range[0], `${RuntimeGlobals.createScriptUrl}(`); + source.insert(dep.range[1], ")"); + } +}; + +makeSerializable( + CreateScriptUrlDependency, + "webpack/lib/dependencies/CreateScriptUrlDependency" +); + +module.exports = CreateScriptUrlDependency; diff --git a/node_modules/webpack/lib/dependencies/CriticalDependencyWarning.js b/node_modules/webpack/lib/dependencies/CriticalDependencyWarning.js new file mode 100644 index 00000000..3299150b --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CriticalDependencyWarning.js @@ -0,0 +1,28 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const WebpackError = require("../WebpackError"); +const makeSerializable = require("../util/makeSerializable"); + +class CriticalDependencyWarning extends WebpackError { + /** + * @param {string} message message + */ + constructor(message) { + super(); + + this.name = "CriticalDependencyWarning"; + this.message = `Critical dependency: ${message}`; + } +} + +makeSerializable( + CriticalDependencyWarning, + "webpack/lib/dependencies/CriticalDependencyWarning" +); + +module.exports = CriticalDependencyWarning; diff --git a/node_modules/webpack/lib/dependencies/CssExportDependency.js b/node_modules/webpack/lib/dependencies/CssExportDependency.js new file mode 100644 index 00000000..a7cf6dbb --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CssExportDependency.js @@ -0,0 +1,156 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const { cssExportConvention } = require("../util/conventions"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */ +/** @typedef {import("../CssModule")} CssModule */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../css/CssExportsGenerator")} CssExportsGenerator */ +/** @typedef {import("../css/CssGenerator")} CssGenerator */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +class CssExportDependency extends NullDependency { + /** + * @param {string} name name + * @param {string} value value + */ + constructor(name, value) { + super(); + this.name = name; + this.value = value; + } + + get type() { + return "css :export"; + } + + /** + * @param {string} name export name + * @param {CssGeneratorExportsConvention} convention convention of the export name + * @returns {string[]} convention results + */ + getExportsConventionNames(name, convention) { + if (this._conventionNames) { + return this._conventionNames; + } + this._conventionNames = cssExportConvention(name, convention); + return this._conventionNames; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this)); + const convention = + /** @type {CssGenerator | CssExportsGenerator} */ + (module.generator).convention; + const names = this.getExportsConventionNames(this.name, convention); + return { + exports: names.map(name => ({ + name, + canMangle: true + })), + dependencies: undefined + }; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, { chunkGraph }) { + const module = /** @type {CssModule} */ ( + chunkGraph.moduleGraph.getParentModule(this) + ); + const generator = + /** @type {CssGenerator | CssExportsGenerator} */ + (module.generator); + const names = this.getExportsConventionNames( + this.name, + generator.convention + ); + hash.update("exportsConvention"); + hash.update(JSON.stringify(names)); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.name); + write(this.value); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.name = read(); + this.value = read(); + super.deserialize(context); + } +} + +CssExportDependency.Template = class CssExportDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { cssExportsData, module: m, runtime, moduleGraph } + ) { + const dep = /** @type {CssExportDependency} */ (dependency); + const module = /** @type {CssModule} */ (m); + const convention = /** @type {CssGenerator | CssExportsGenerator} */ ( + module.generator + ).convention; + const names = dep.getExportsConventionNames(dep.name, convention); + const usedNames = /** @type {string[]} */ ( + names + .map(name => + moduleGraph.getExportInfo(module, name).getUsedName(name, runtime) + ) + .filter(Boolean) + ); + if (usedNames.length === 0) return; + + for (const used of usedNames) { + cssExportsData.exports.set(used, dep.value); + } + } +}; + +makeSerializable( + CssExportDependency, + "webpack/lib/dependencies/CssExportDependency" +); + +module.exports = CssExportDependency; diff --git a/node_modules/webpack/lib/dependencies/CssImportDependency.js b/node_modules/webpack/lib/dependencies/CssImportDependency.js new file mode 100644 index 00000000..c235be41 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CssImportDependency.js @@ -0,0 +1,125 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../css/CssParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class CssImportDependency extends ModuleDependency { + /** + * Example of dependency: + * \@import url("landscape.css") layer(forms) screen and (orientation: landscape) screen and (orientation: landscape); + * @param {string} request request + * @param {Range} range range of the argument + * @param {string | undefined} layer layer + * @param {string | undefined} supports list of supports conditions + * @param {string | undefined} media list of media conditions + */ + constructor(request, range, layer, supports, media) { + super(request); + this.range = range; + this.layer = layer; + this.supports = supports; + this.media = media; + } + + get type() { + return "css @import"; + } + + get category() { + return "css-import"; + } + + /** + * @returns {string | null} an identifier to merge equal requests + */ + getResourceIdentifier() { + let str = `context${this._context || ""}|module${this.request}`; + + if (this.layer) { + str += `|layer${this.layer}`; + } + + if (this.supports) { + str += `|supports${this.supports}`; + } + + if (this.media) { + str += `|media${this.media}`; + } + + return str; + } + + /** + * @param {string} context context directory + * @returns {Module | null} a module + */ + createIgnoredModule(context) { + return null; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.layer); + write(this.supports); + write(this.media); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.layer = read(); + this.supports = read(); + this.media = read(); + super.deserialize(context); + } +} + +CssImportDependency.Template = class CssImportDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {CssImportDependency} */ (dependency); + + source.replace(dep.range[0], dep.range[1] - 1, ""); + } +}; + +makeSerializable( + CssImportDependency, + "webpack/lib/dependencies/CssImportDependency" +); + +module.exports = CssImportDependency; diff --git a/node_modules/webpack/lib/dependencies/CssLocalIdentifierDependency.js b/node_modules/webpack/lib/dependencies/CssLocalIdentifierDependency.js new file mode 100644 index 00000000..2b495dd8 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CssLocalIdentifierDependency.js @@ -0,0 +1,245 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const { cssExportConvention } = require("../util/conventions"); +const createHash = require("../util/createHash"); +const { makePathsRelative } = require("../util/identifier"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorExportsConvention} CssGeneratorExportsConvention */ +/** @typedef {import("../../declarations/WebpackOptions").CssGeneratorLocalIdentName} CssGeneratorLocalIdentName */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../CssModule")} CssModule */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../css/CssExportsGenerator")} CssExportsGenerator */ +/** @typedef {import("../css/CssGenerator")} CssGenerator */ +/** @typedef {import("../css/CssParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +/** + * @param {string} local css local + * @param {CssModule} module module + * @param {ChunkGraph} chunkGraph chunk graph + * @param {RuntimeTemplate} runtimeTemplate runtime template + * @returns {string} local ident + */ +const getLocalIdent = (local, module, chunkGraph, runtimeTemplate) => { + const localIdentName = + /** @type {CssGenerator | CssExportsGenerator} */ + (module.generator).localIdentName; + const relativeResourcePath = makePathsRelative( + /** @type {string} */ (module.context), + module.resourceResolveData.path + ); + const { hashFunction, hashDigest, hashDigestLength, hashSalt, uniqueName } = + runtimeTemplate.outputOptions; + const hash = createHash(hashFunction); + if (hashSalt) { + hash.update(hashSalt); + } + hash.update(relativeResourcePath); + if (!/\[local\]/.test(localIdentName)) { + hash.update(local); + } + const localIdentHash = /** @type {string} */ (hash.digest(hashDigest)) + // Remove all leading digits + .replace(/^\d+/, "") + // Replace all slashes with underscores (same as in base64url) + .replace(/\//g, "_") + // Remove everything that is not an alphanumeric or underscore + .replace(/[^A-Za-z0-9_]+/g, "_") + .slice(0, hashDigestLength); + return runtimeTemplate.compilation + .getPath(localIdentName, { + filename: relativeResourcePath, + hash: localIdentHash, + contentHash: localIdentHash, + chunkGraph, + module + }) + .replace(/\[local\]/g, local) + .replace(/\[uniqueName\]/g, uniqueName); +}; + +class CssLocalIdentifierDependency extends NullDependency { + /** + * @param {string} name name + * @param {Range} range range + * @param {string=} prefix prefix + */ + constructor(name, range, prefix = "") { + super(); + this.name = name; + this.range = range; + this.prefix = prefix; + } + + get type() { + return "css local identifier"; + } + + /** + * @param {string} name export name + * @param {CssGeneratorExportsConvention} convention convention of the export name + * @returns {string[]} convention results + */ + getExportsConventionNames(name, convention) { + if (this._conventionNames) { + return this._conventionNames; + } + this._conventionNames = cssExportConvention(this.name, convention); + return this._conventionNames; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + const module = /** @type {CssModule} */ (moduleGraph.getParentModule(this)); + const convention = /** @type {CssGenerator | CssExportsGenerator} */ ( + module.generator + ).convention; + const names = this.getExportsConventionNames(this.name, convention); + return { + exports: names.map(name => ({ + name, + canMangle: true + })), + dependencies: undefined + }; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, { chunkGraph }) { + const module = /** @type {CssModule} */ ( + chunkGraph.moduleGraph.getParentModule(this) + ); + const generator = /** @type {CssGenerator | CssExportsGenerator} */ ( + module.generator + ); + const names = this.getExportsConventionNames( + this.name, + generator.convention + ); + hash.update("exportsConvention"); + hash.update(JSON.stringify(names)); + hash.update("localIdentName"); + hash.update(generator.localIdentName); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.name); + write(this.range); + write(this.prefix); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.name = read(); + this.range = read(); + this.prefix = read(); + super.deserialize(context); + } +} + +/** + * @param {string} str string + * @param {string | boolean} omitUnderscore true if you need to omit underscore + * @returns {string} escaped css identifier + */ +const escapeCssIdentifier = (str, omitUnderscore) => { + const escaped = `${str}`.replace( + // cspell:word uffff + /[^a-zA-Z0-9_\u0081-\uFFFF-]/g, + s => `\\${s}` + ); + return !omitUnderscore && /^(?!--)[0-9-]/.test(escaped) + ? `_${escaped}` + : escaped; +}; + +CssLocalIdentifierDependency.Template = class CssLocalIdentifierDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { + module: m, + moduleGraph, + chunkGraph, + runtime, + runtimeTemplate, + cssExportsData + } + ) { + const dep = /** @type {CssLocalIdentifierDependency} */ (dependency); + const module = /** @type {CssModule} */ (m); + const convention = /** @type {CssGenerator | CssExportsGenerator} */ ( + module.generator + ).convention; + const names = dep.getExportsConventionNames(dep.name, convention); + const usedNames = /** @type {string[]} */ ( + names + .map(name => + moduleGraph.getExportInfo(module, name).getUsedName(name, runtime) + ) + .filter(Boolean) + ); + if (usedNames.length === 0) return; + + // use the first usedName to generate localIdent, it's shorter when mangle exports enabled + const localIdent = + dep.prefix + + getLocalIdent(usedNames[0], module, chunkGraph, runtimeTemplate); + source.replace( + dep.range[0], + dep.range[1] - 1, + escapeCssIdentifier(localIdent, dep.prefix) + ); + for (const used of usedNames) { + cssExportsData.exports.set(used, localIdent); + } + } +}; + +makeSerializable( + CssLocalIdentifierDependency, + "webpack/lib/dependencies/CssLocalIdentifierDependency" +); + +module.exports = CssLocalIdentifierDependency; diff --git a/node_modules/webpack/lib/dependencies/CssSelfLocalIdentifierDependency.js b/node_modules/webpack/lib/dependencies/CssSelfLocalIdentifierDependency.js new file mode 100644 index 00000000..b63ff53a --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CssSelfLocalIdentifierDependency.js @@ -0,0 +1,111 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const makeSerializable = require("../util/makeSerializable"); +const CssLocalIdentifierDependency = require("./CssLocalIdentifierDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../css/CssParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class CssSelfLocalIdentifierDependency extends CssLocalIdentifierDependency { + /** + * @param {string} name name + * @param {Range} range range + * @param {string=} prefix prefix + * @param {Set<string>=} declaredSet set of declared names (will only be active when in declared set) + */ + constructor(name, range, prefix = "", declaredSet = undefined) { + super(name, range, prefix); + this.declaredSet = declaredSet; + } + + get type() { + return "css self local identifier"; + } + + get category() { + return "self"; + } + + /** + * @returns {string | null} an identifier to merge equal requests + */ + getResourceIdentifier() { + return "self"; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + if (this.declaredSet && !this.declaredSet.has(this.name)) return; + return super.getExports(moduleGraph); + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + if (this.declaredSet && !this.declaredSet.has(this.name)) + return Dependency.NO_EXPORTS_REFERENCED; + return [[this.name]]; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.declaredSet); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.declaredSet = read(); + super.deserialize(context); + } +} + +CssSelfLocalIdentifierDependency.Template = class CssSelfLocalIdentifierDependencyTemplate extends ( + CssLocalIdentifierDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {CssSelfLocalIdentifierDependency} */ (dependency); + if (dep.declaredSet && !dep.declaredSet.has(dep.name)) return; + super.apply(dependency, source, templateContext); + } +}; + +makeSerializable( + CssSelfLocalIdentifierDependency, + "webpack/lib/dependencies/CssSelfLocalIdentifierDependency" +); + +module.exports = CssSelfLocalIdentifierDependency; diff --git a/node_modules/webpack/lib/dependencies/CssUrlDependency.js b/node_modules/webpack/lib/dependencies/CssUrlDependency.js new file mode 100644 index 00000000..15fc53aa --- /dev/null +++ b/node_modules/webpack/lib/dependencies/CssUrlDependency.js @@ -0,0 +1,164 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const RawDataUrlModule = require("../asset/RawDataUrlModule"); +const makeSerializable = require("../util/makeSerializable"); +const memoize = require("../util/memoize"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +const getIgnoredRawDataUrlModule = memoize( + () => new RawDataUrlModule("data:,", "ignored-asset", "(ignored asset)") +); + +class CssUrlDependency extends ModuleDependency { + /** + * @param {string} request request + * @param {Range} range range of the argument + * @param {"string" | "url"} urlType dependency type e.g. url() or string + */ + constructor(request, range, urlType) { + super(request); + this.range = range; + this.urlType = urlType; + } + + get type() { + return "css url()"; + } + + get category() { + return "url"; + } + + /** + * @param {string} context context directory + * @returns {Module | null} a module + */ + createIgnoredModule(context) { + return getIgnoredRawDataUrlModule(); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.urlType); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.urlType = read(); + super.deserialize(context); + } +} + +/** + * @param {string} str string + * @returns {string} string in quotes if needed + */ +const cssEscapeString = str => { + let countWhiteOrBracket = 0; + let countQuotation = 0; + let countApostrophe = 0; + for (let i = 0; i < str.length; i++) { + const cc = str.charCodeAt(i); + switch (cc) { + case 9: // tab + case 10: // nl + case 32: // space + case 40: // ( + case 41: // ) + countWhiteOrBracket++; + break; + case 34: + countQuotation++; + break; + case 39: + countApostrophe++; + break; + } + } + if (countWhiteOrBracket < 2) { + return str.replace(/[\n\t ()'"\\]/g, m => `\\${m}`); + } else if (countQuotation <= countApostrophe) { + return `"${str.replace(/[\n"\\]/g, m => `\\${m}`)}"`; + } + return `'${str.replace(/[\n'\\]/g, m => `\\${m}`)}'`; +}; + +CssUrlDependency.Template = class CssUrlDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { moduleGraph, runtimeTemplate, codeGenerationResults } + ) { + const dep = /** @type {CssUrlDependency} */ (dependency); + const module = /** @type {Module} */ (moduleGraph.getModule(dep)); + + /** @type {string | undefined} */ + let newValue; + + switch (dep.urlType) { + case "string": + newValue = cssEscapeString( + runtimeTemplate.assetUrl({ + module, + codeGenerationResults + }) + ); + break; + case "url": + newValue = `url(${cssEscapeString( + runtimeTemplate.assetUrl({ + module, + codeGenerationResults + }) + )})`; + break; + } + + source.replace( + dep.range[0], + dep.range[1] - 1, + /** @type {string} */ (newValue) + ); + } +}; + +makeSerializable(CssUrlDependency, "webpack/lib/dependencies/CssUrlDependency"); + +CssUrlDependency.PUBLIC_PATH_AUTO = "__WEBPACK_CSS_PUBLIC_PATH_AUTO__"; + +module.exports = CssUrlDependency; diff --git a/node_modules/webpack/lib/dependencies/DelegatedSourceDependency.js b/node_modules/webpack/lib/dependencies/DelegatedSourceDependency.js new file mode 100644 index 00000000..737f60e7 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/DelegatedSourceDependency.js @@ -0,0 +1,33 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +class DelegatedSourceDependency extends ModuleDependency { + /** + * @param {string} request the request string + */ + constructor(request) { + super(request); + } + + get type() { + return "delegated source"; + } + + get category() { + return "esm"; + } +} + +makeSerializable( + DelegatedSourceDependency, + "webpack/lib/dependencies/DelegatedSourceDependency" +); + +module.exports = DelegatedSourceDependency; diff --git a/node_modules/webpack/lib/dependencies/DllEntryDependency.js b/node_modules/webpack/lib/dependencies/DllEntryDependency.js new file mode 100644 index 00000000..74697042 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/DllEntryDependency.js @@ -0,0 +1,61 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const makeSerializable = require("../util/makeSerializable"); + +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./EntryDependency")} EntryDependency */ + +class DllEntryDependency extends Dependency { + /** + * @param {EntryDependency[]} dependencies dependencies + * @param {string} name name + */ + constructor(dependencies, name) { + super(); + + this.dependencies = dependencies; + this.name = name; + } + + get type() { + return "dll entry"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.dependencies); + write(this.name); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.dependencies = read(); + this.name = read(); + + super.deserialize(context); + } +} + +makeSerializable( + DllEntryDependency, + "webpack/lib/dependencies/DllEntryDependency" +); + +module.exports = DllEntryDependency; diff --git a/node_modules/webpack/lib/dependencies/DynamicExports.js b/node_modules/webpack/lib/dependencies/DynamicExports.js new file mode 100644 index 00000000..cdc5e9c9 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/DynamicExports.js @@ -0,0 +1,73 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../Parser").ParserState} ParserState */ + +/** @type {WeakMap<ParserState, boolean>} */ +const parserStateExportsState = new WeakMap(); + +/** + * @param {ParserState} parserState parser state + * @returns {void} + */ +module.exports.bailout = parserState => { + const value = parserStateExportsState.get(parserState); + parserStateExportsState.set(parserState, false); + if (value === true) { + const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta); + buildMeta.exportsType = undefined; + buildMeta.defaultObject = false; + } +}; + +/** + * @param {ParserState} parserState parser state + * @returns {void} + */ +module.exports.enable = parserState => { + const value = parserStateExportsState.get(parserState); + if (value === false) return; + parserStateExportsState.set(parserState, true); + if (value !== true) { + const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta); + buildMeta.exportsType = "default"; + buildMeta.defaultObject = "redirect"; + } +}; + +/** + * @param {ParserState} parserState parser state + * @returns {void} + */ +module.exports.setFlagged = parserState => { + const value = parserStateExportsState.get(parserState); + if (value !== true) return; + const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta); + if (buildMeta.exportsType === "dynamic") return; + buildMeta.exportsType = "flagged"; +}; + +/** + * @param {ParserState} parserState parser state + * @returns {void} + */ +module.exports.setDynamic = parserState => { + const value = parserStateExportsState.get(parserState); + if (value !== true) return; + /** @type {BuildMeta} */ + (parserState.module.buildMeta).exportsType = "dynamic"; +}; + +/** + * @param {ParserState} parserState parser state + * @returns {boolean} true, when enabled + */ +module.exports.isEnabled = parserState => { + const value = parserStateExportsState.get(parserState); + return value === true; +}; diff --git a/node_modules/webpack/lib/dependencies/EntryDependency.js b/node_modules/webpack/lib/dependencies/EntryDependency.js new file mode 100644 index 00000000..f4644494 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/EntryDependency.js @@ -0,0 +1,30 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +class EntryDependency extends ModuleDependency { + /** + * @param {string} request request path for entry + */ + constructor(request) { + super(request); + } + + get type() { + return "entry"; + } + + get category() { + return "esm"; + } +} + +makeSerializable(EntryDependency, "webpack/lib/dependencies/EntryDependency"); + +module.exports = EntryDependency; diff --git a/node_modules/webpack/lib/dependencies/ExportsInfoDependency.js b/node_modules/webpack/lib/dependencies/ExportsInfoDependency.js new file mode 100644 index 00000000..70383e25 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ExportsInfoDependency.js @@ -0,0 +1,158 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { UsageState } = require("../ExportsInfo"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +/** + * @param {ModuleGraph} moduleGraph the module graph + * @param {Module} module the module + * @param {string[] | null} _exportName name of the export if any + * @param {string | null} property name of the requested property + * @param {RuntimeSpec} runtime for which runtime + * @returns {any} value of the property + */ +const getProperty = (moduleGraph, module, _exportName, property, runtime) => { + if (!_exportName) { + switch (property) { + case "usedExports": { + const usedExports = moduleGraph + .getExportsInfo(module) + .getUsedExports(runtime); + if ( + typeof usedExports === "boolean" || + usedExports === undefined || + usedExports === null + ) { + return usedExports; + } + return Array.from(usedExports).sort(); + } + } + } + const exportName = /** @type {string[]} */ (_exportName); + switch (property) { + case "canMangle": { + const exportsInfo = moduleGraph.getExportsInfo(module); + const exportInfo = exportsInfo.getReadOnlyExportInfoRecursive(exportName); + if (exportInfo) return exportInfo.canMangle; + return exportsInfo.otherExportsInfo.canMangle; + } + case "used": + return ( + moduleGraph.getExportsInfo(module).getUsed(exportName, runtime) !== + UsageState.Unused + ); + case "useInfo": { + const state = moduleGraph + .getExportsInfo(module) + .getUsed(exportName, runtime); + switch (state) { + case UsageState.Used: + case UsageState.OnlyPropertiesUsed: + return true; + case UsageState.Unused: + return false; + case UsageState.NoInfo: + return; + case UsageState.Unknown: + return null; + default: + throw new Error(`Unexpected UsageState ${state}`); + } + } + case "provideInfo": + return moduleGraph.getExportsInfo(module).isExportProvided(exportName); + } +}; + +class ExportsInfoDependency extends NullDependency { + /** + * @param {Range} range range + * @param {string[] | null} exportName export name + * @param {string | null} property property + */ + constructor(range, exportName, property) { + super(); + this.range = range; + this.exportName = exportName; + this.property = property; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + write(this.exportName); + write(this.property); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + * @returns {ExportsInfoDependency} ExportsInfoDependency + */ + static deserialize(context) { + const obj = new ExportsInfoDependency( + context.read(), + context.read(), + context.read() + ); + obj.deserialize(context); + return obj; + } +} + +makeSerializable( + ExportsInfoDependency, + "webpack/lib/dependencies/ExportsInfoDependency" +); + +ExportsInfoDependency.Template = class ExportsInfoDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { module, moduleGraph, runtime }) { + const dep = /** @type {ExportsInfoDependency} */ (dependency); + + const value = getProperty( + moduleGraph, + module, + dep.exportName, + dep.property, + runtime + ); + source.replace( + dep.range[0], + dep.range[1] - 1, + value === undefined ? "undefined" : JSON.stringify(value) + ); + } +}; + +module.exports = ExportsInfoDependency; diff --git a/node_modules/webpack/lib/dependencies/ExternalModuleDependency.js b/node_modules/webpack/lib/dependencies/ExternalModuleDependency.js new file mode 100644 index 00000000..ce3e3785 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ExternalModuleDependency.js @@ -0,0 +1,109 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const CachedConstDependency = require("./CachedConstDependency"); +const ExternalModuleInitFragment = require("./ExternalModuleInitFragment"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +class ExternalModuleDependency extends CachedConstDependency { + /** + * @param {string} module module + * @param {{ name: string, value: string }[]} importSpecifiers import specifiers + * @param {string | undefined} defaultImport default import + * @param {string} expression expression + * @param {Range} range range + * @param {string} identifier identifier + */ + constructor( + module, + importSpecifiers, + defaultImport, + expression, + range, + identifier + ) { + super(expression, range, identifier); + + this.importedModule = module; + this.specifiers = importSpecifiers; + this.default = defaultImport; + } + + /** + * @returns {string} hash update + */ + _createHashUpdate() { + return `${this.importedModule}${JSON.stringify(this.specifiers)}${ + this.default || "null" + }${super._createHashUpdate()}`; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + super.serialize(context); + const { write } = context; + write(this.importedModule); + write(this.specifiers); + write(this.default); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + super.deserialize(context); + const { read } = context; + this.importedModule = read(); + this.specifiers = read(); + this.default = read(); + } +} + +makeSerializable( + ExternalModuleDependency, + "webpack/lib/dependencies/ExternalModuleDependency" +); + +ExternalModuleDependency.Template = class ExternalModuleDependencyTemplate extends ( + CachedConstDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + super.apply(dependency, source, templateContext); + const dep = /** @type {ExternalModuleDependency} */ (dependency); + const { chunkInitFragments, runtimeTemplate } = templateContext; + + chunkInitFragments.push( + new ExternalModuleInitFragment( + `${runtimeTemplate.supportNodePrefixForCoreModules() ? "node:" : ""}${ + dep.importedModule + }`, + dep.specifiers, + dep.default + ) + ); + } +}; + +module.exports = ExternalModuleDependency; diff --git a/node_modules/webpack/lib/dependencies/ExternalModuleInitFragment.js b/node_modules/webpack/lib/dependencies/ExternalModuleInitFragment.js new file mode 100644 index 00000000..41bbe538 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ExternalModuleInitFragment.js @@ -0,0 +1,133 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const InitFragment = require("../InitFragment"); +const makeSerializable = require("../util/makeSerializable"); + +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../Generator").GenerateContext} GenerateContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {Map<string, Set<string>>} ImportSpecifiers */ + +/** + * @extends {InitFragment<GenerateContext>} + */ +class ExternalModuleInitFragment extends InitFragment { + /** + * @param {string} importedModule imported module + * @param {Array<{ name: string, value?: string }> | ImportSpecifiers} specifiers import specifiers + * @param {string=} defaultImport default import + */ + constructor(importedModule, specifiers, defaultImport) { + super( + undefined, + InitFragment.STAGE_CONSTANTS, + 0, + `external module imports|${importedModule}|${defaultImport || "null"}` + ); + this.importedModule = importedModule; + if (Array.isArray(specifiers)) { + /** @type {ImportSpecifiers} */ + this.specifiers = new Map(); + for (const { name, value } of specifiers) { + let specifiers = this.specifiers.get(name); + if (!specifiers) { + specifiers = new Set(); + this.specifiers.set(name, specifiers); + } + specifiers.add(value || name); + } + } else { + this.specifiers = specifiers; + } + this.defaultImport = defaultImport; + } + + /** + * @param {ExternalModuleInitFragment} other other + * @returns {ExternalModuleInitFragment} ExternalModuleInitFragment + */ + merge(other) { + const newSpecifiersMap = new Map(this.specifiers); + for (const [name, specifiers] of other.specifiers) { + if (newSpecifiersMap.has(name)) { + const currentSpecifiers = + /** @type {Set<string>} */ + (newSpecifiersMap.get(name)); + for (const spec of specifiers) currentSpecifiers.add(spec); + } else { + newSpecifiersMap.set(name, specifiers); + } + } + return new ExternalModuleInitFragment( + this.importedModule, + newSpecifiersMap, + this.defaultImport + ); + } + + /** + * @param {GenerateContext} context context + * @returns {string | Source | undefined} the source code that will be included as initialization code + */ + getContent({ runtimeRequirements }) { + const namedImports = []; + + for (const [name, specifiers] of this.specifiers) { + for (const spec of specifiers) { + if (spec === name) { + namedImports.push(name); + } else { + namedImports.push(`${name} as ${spec}`); + } + } + } + + let importsString = + namedImports.length > 0 ? `{${namedImports.join(",")}}` : ""; + + if (this.defaultImport) { + importsString = `${this.defaultImport}${ + importsString ? `, ${importsString}` : "" + }`; + } + + return `import ${importsString} from ${JSON.stringify( + this.importedModule + )};`; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + super.serialize(context); + const { write } = context; + write(this.importedModule); + write(this.specifiers); + write(this.defaultImport); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + super.deserialize(context); + const { read } = context; + this.importedModule = read(); + this.specifiers = read(); + this.defaultImport = read(); + } +} + +makeSerializable( + ExternalModuleInitFragment, + "webpack/lib/dependencies/ExternalModuleInitFragment" +); + +module.exports = ExternalModuleInitFragment; diff --git a/node_modules/webpack/lib/dependencies/HarmonyAcceptDependency.js b/node_modules/webpack/lib/dependencies/HarmonyAcceptDependency.js new file mode 100644 index 00000000..4817b722 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyAcceptDependency.js @@ -0,0 +1,143 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Template = require("../Template"); +const makeSerializable = require("../util/makeSerializable"); +const HarmonyImportDependency = require("./HarmonyImportDependency"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./HarmonyAcceptImportDependency")} HarmonyAcceptImportDependency */ + +class HarmonyAcceptDependency extends NullDependency { + /** + * @param {Range} range expression range + * @param {HarmonyAcceptImportDependency[]} dependencies import dependencies + * @param {boolean} hasCallback true, if the range wraps an existing callback + */ + constructor(range, dependencies, hasCallback) { + super(); + this.range = range; + this.dependencies = dependencies; + this.hasCallback = hasCallback; + } + + get type() { + return "accepted harmony modules"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + write(this.dependencies); + write(this.hasCallback); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.range = read(); + this.dependencies = read(); + this.hasCallback = read(); + super.deserialize(context); + } +} + +makeSerializable( + HarmonyAcceptDependency, + "webpack/lib/dependencies/HarmonyAcceptDependency" +); + +HarmonyAcceptDependency.Template = class HarmonyAcceptDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {HarmonyAcceptDependency} */ (dependency); + const { + module, + runtime, + runtimeRequirements, + runtimeTemplate, + moduleGraph, + chunkGraph + } = templateContext; + const content = dep.dependencies + .map(dependency => { + const referencedModule = moduleGraph.getModule(dependency); + return { + dependency, + runtimeCondition: referencedModule + ? HarmonyImportDependency.Template.getImportEmittedRuntime( + module, + referencedModule + ) + : false + }; + }) + .filter(({ runtimeCondition }) => runtimeCondition !== false) + .map(({ dependency, runtimeCondition }) => { + const condition = runtimeTemplate.runtimeConditionExpression({ + chunkGraph, + runtime, + runtimeCondition, + runtimeRequirements + }); + const s = dependency.getImportStatement(true, templateContext); + const code = s[0] + s[1]; + if (condition !== "true") { + return `if (${condition}) {\n${Template.indent(code)}\n}\n`; + } + return code; + }) + .join(""); + + if (dep.hasCallback) { + if (runtimeTemplate.supportsArrowFunction()) { + source.insert( + dep.range[0], + `__WEBPACK_OUTDATED_DEPENDENCIES__ => { ${content}(` + ); + source.insert(dep.range[1], ")(__WEBPACK_OUTDATED_DEPENDENCIES__); }"); + } else { + source.insert( + dep.range[0], + `function(__WEBPACK_OUTDATED_DEPENDENCIES__) { ${content}(` + ); + source.insert( + dep.range[1], + ")(__WEBPACK_OUTDATED_DEPENDENCIES__); }.bind(this)" + ); + } + return; + } + + const arrow = runtimeTemplate.supportsArrowFunction(); + source.insert( + dep.range[1] - 0.5, + `, ${arrow ? "() =>" : "function()"} { ${content} }` + ); + } +}; + +module.exports = HarmonyAcceptDependency; diff --git a/node_modules/webpack/lib/dependencies/HarmonyAcceptImportDependency.js b/node_modules/webpack/lib/dependencies/HarmonyAcceptImportDependency.js new file mode 100644 index 00000000..03cb0002 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyAcceptImportDependency.js @@ -0,0 +1,40 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const HarmonyImportDependency = require("./HarmonyImportDependency"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ + +class HarmonyAcceptImportDependency extends HarmonyImportDependency { + /** + * @param {string} request the request string + */ + constructor(request) { + super(request, Number.NaN); + this.weak = true; + } + + get type() { + return "harmony accept"; + } +} + +makeSerializable( + HarmonyAcceptImportDependency, + "webpack/lib/dependencies/HarmonyAcceptImportDependency" +); + +HarmonyAcceptImportDependency.Template = + /** @type {typeof HarmonyImportDependency.Template} */ ( + NullDependency.Template + ); + +module.exports = HarmonyAcceptImportDependency; diff --git a/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js b/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js new file mode 100644 index 00000000..5464f91b --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyCompatibilityDependency.js @@ -0,0 +1,92 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { UsageState } = require("../ExportsInfo"); +const InitFragment = require("../InitFragment"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ + +class HarmonyCompatibilityDependency extends NullDependency { + get type() { + return "harmony export header"; + } +} + +makeSerializable( + HarmonyCompatibilityDependency, + "webpack/lib/dependencies/HarmonyCompatibilityDependency" +); + +HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { + module, + runtimeTemplate, + moduleGraph, + initFragments, + runtimeRequirements, + runtime, + concatenationScope + } + ) { + if (concatenationScope) return; + const exportsInfo = moduleGraph.getExportsInfo(module); + if ( + exportsInfo.getReadOnlyExportInfo("__esModule").getUsed(runtime) !== + UsageState.Unused + ) { + const content = runtimeTemplate.defineEsModuleFlagStatement({ + exportsArgument: module.exportsArgument, + runtimeRequirements + }); + initFragments.push( + new InitFragment( + content, + InitFragment.STAGE_HARMONY_EXPORTS, + 0, + "harmony compatibility" + ) + ); + } + if (moduleGraph.isAsync(module)) { + runtimeRequirements.add(RuntimeGlobals.module); + runtimeRequirements.add(RuntimeGlobals.asyncModule); + initFragments.push( + new InitFragment( + runtimeTemplate.supportsArrowFunction() + ? `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__, __webpack_async_result__) => { try {\n` + : `${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async function (__webpack_handle_async_dependencies__, __webpack_async_result__) { try {\n`, + InitFragment.STAGE_ASYNC_BOUNDARY, + 0, + undefined, + `\n__webpack_async_result__();\n} catch(e) { __webpack_async_result__(e); } }${ + /** @type {BuildMeta} */ (module.buildMeta).async ? ", 1" : "" + });` + ) + ); + } + } +}; + +module.exports = HarmonyCompatibilityDependency; diff --git a/node_modules/webpack/lib/dependencies/HarmonyDetectionParserPlugin.js b/node_modules/webpack/lib/dependencies/HarmonyDetectionParserPlugin.js new file mode 100644 index 00000000..4cf84fc1 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyDetectionParserPlugin.js @@ -0,0 +1,123 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const EnvironmentNotSupportAsyncWarning = require("../EnvironmentNotSupportAsyncWarning"); +const { JAVASCRIPT_MODULE_TYPE_ESM } = require("../ModuleTypeConstants"); +const DynamicExports = require("./DynamicExports"); +const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency"); +const HarmonyExports = require("./HarmonyExports"); + +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("./HarmonyModulesPlugin").HarmonyModulesPluginOptions} HarmonyModulesPluginOptions */ + +module.exports = class HarmonyDetectionParserPlugin { + /** + * @param {HarmonyModulesPluginOptions} options options + */ + constructor(options) { + const { topLevelAwait = false } = options || {}; + this.topLevelAwait = topLevelAwait; + } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + parser.hooks.program.tap("HarmonyDetectionParserPlugin", ast => { + const isStrictHarmony = + parser.state.module.type === JAVASCRIPT_MODULE_TYPE_ESM; + const isHarmony = + isStrictHarmony || + ast.body.some( + statement => + statement.type === "ImportDeclaration" || + statement.type === "ExportDefaultDeclaration" || + statement.type === "ExportNamedDeclaration" || + statement.type === "ExportAllDeclaration" + ); + if (isHarmony) { + const module = parser.state.module; + const compatDep = new HarmonyCompatibilityDependency(); + compatDep.loc = { + start: { + line: -1, + column: 0 + }, + end: { + line: -1, + column: 0 + }, + index: -3 + }; + module.addPresentationalDependency(compatDep); + DynamicExports.bailout(parser.state); + HarmonyExports.enable(parser.state, isStrictHarmony); + parser.scope.isStrict = true; + } + }); + + parser.hooks.topLevelAwait.tap("HarmonyDetectionParserPlugin", () => { + const module = parser.state.module; + if (!this.topLevelAwait) { + throw new Error( + "The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enable it)" + ); + } + if (!HarmonyExports.isEnabled(parser.state)) { + throw new Error( + "Top-level-await is only supported in EcmaScript Modules" + ); + } + /** @type {BuildMeta} */ + (module.buildMeta).async = true; + EnvironmentNotSupportAsyncWarning.check( + module, + parser.state.compilation.runtimeTemplate, + "topLevelAwait" + ); + }); + + /** + * @returns {boolean | undefined} true if in harmony + */ + const skipInHarmony = () => { + if (HarmonyExports.isEnabled(parser.state)) { + return true; + } + }; + + /** + * @returns {null | undefined} null if in harmony + */ + const nullInHarmony = () => { + if (HarmonyExports.isEnabled(parser.state)) { + return null; + } + }; + + const nonHarmonyIdentifiers = ["define", "exports"]; + for (const identifier of nonHarmonyIdentifiers) { + parser.hooks.evaluateTypeof + .for(identifier) + .tap("HarmonyDetectionParserPlugin", nullInHarmony); + parser.hooks.typeof + .for(identifier) + .tap("HarmonyDetectionParserPlugin", skipInHarmony); + parser.hooks.evaluate + .for(identifier) + .tap("HarmonyDetectionParserPlugin", nullInHarmony); + parser.hooks.expression + .for(identifier) + .tap("HarmonyDetectionParserPlugin", skipInHarmony); + parser.hooks.call + .for(identifier) + .tap("HarmonyDetectionParserPlugin", skipInHarmony); + } + } +}; diff --git a/node_modules/webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js b/node_modules/webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js new file mode 100644 index 00000000..09ceb8e4 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js @@ -0,0 +1,152 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +/** + * Dependency for static evaluating import specifier. e.g. + * @example + * import a from "a"; + * "x" in a; + * a.x !== undefined; // if x value statically analyzable + */ +class HarmonyEvaluatedImportSpecifierDependency extends HarmonyImportSpecifierDependency { + /** + * @param {string} request the request string + * @param {number} sourceOrder source order + * @param {TODO} ids ids + * @param {TODO} name name + * @param {Range} range location in source code + * @param {ImportAttributes} attributes import assertions + * @param {string} operator operator + */ + constructor(request, sourceOrder, ids, name, range, attributes, operator) { + super(request, sourceOrder, ids, name, range, false, attributes, []); + this.operator = operator; + } + + get type() { + return `evaluated X ${this.operator} harmony import specifier`; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + super.serialize(context); + const { write } = context; + write(this.operator); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + super.deserialize(context); + const { read } = context; + this.operator = read(); + } +} + +makeSerializable( + HarmonyEvaluatedImportSpecifierDependency, + "webpack/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency" +); + +HarmonyEvaluatedImportSpecifierDependency.Template = class HarmonyEvaluatedImportSpecifierDependencyTemplate extends ( + HarmonyImportSpecifierDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {HarmonyEvaluatedImportSpecifierDependency} */ ( + dependency + ); + const { module, moduleGraph, runtime } = templateContext; + const connection = moduleGraph.getConnection(dep); + // Skip rendering depending when dependency is conditional + if (connection && !connection.isTargetActive(runtime)) return; + + const exportsInfo = moduleGraph.getExportsInfo( + /** @type {ModuleGraphConnection} */ (connection).module + ); + const ids = dep.getIds(moduleGraph); + + let value; + + const exportsType = + /** @type {ModuleGraphConnection} */ + (connection).module.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ + (module.buildMeta).strictHarmonyModule + ); + switch (exportsType) { + case "default-with-named": { + if (ids[0] === "default") { + value = + ids.length === 1 || exportsInfo.isExportProvided(ids.slice(1)); + } else { + value = exportsInfo.isExportProvided(ids); + } + break; + } + case "namespace": { + value = + ids[0] === "__esModule" + ? ids.length === 1 || undefined + : exportsInfo.isExportProvided(ids); + break; + } + case "dynamic": { + if (ids[0] !== "default") { + value = exportsInfo.isExportProvided(ids); + } + break; + } + // default-only could lead to runtime error, when default value is primitive + } + + if (typeof value === "boolean") { + source.replace(dep.range[0], dep.range[1] - 1, ` ${value}`); + } else { + const usedName = exportsInfo.getUsedName(ids, runtime); + + const code = this._getCodeForIds( + dep, + source, + templateContext, + ids.slice(0, -1) + ); + source.replace( + dep.range[0], + dep.range[1] - 1, + `${ + usedName ? JSON.stringify(usedName[usedName.length - 1]) : '""' + } in ${code}` + ); + } + } +}; + +module.exports = HarmonyEvaluatedImportSpecifierDependency; diff --git a/node_modules/webpack/lib/dependencies/HarmonyExportDependencyParserPlugin.js b/node_modules/webpack/lib/dependencies/HarmonyExportDependencyParserPlugin.js new file mode 100644 index 00000000..0978a5a2 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyExportDependencyParserPlugin.js @@ -0,0 +1,221 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const InnerGraph = require("../optimize/InnerGraph"); +const ConstDependency = require("./ConstDependency"); +const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDependency"); +const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency"); +const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency"); +const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDependency"); +const { ExportPresenceModes } = require("./HarmonyImportDependency"); +const { + harmonySpecifierTag, + getAttributes +} = require("./HarmonyImportDependencyParserPlugin"); +const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency"); + +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").FunctionDeclaration} FunctionDeclaration */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const { HarmonyStarExportsList } = HarmonyExportImportedSpecifierDependency; + +module.exports = class HarmonyExportDependencyParserPlugin { + /** + * @param {import("../../declarations/WebpackOptions").JavascriptParserOptions} options options + */ + constructor(options) { + this.exportPresenceMode = + options.reexportExportsPresence !== undefined + ? ExportPresenceModes.fromUserOption(options.reexportExportsPresence) + : options.exportsPresence !== undefined + ? ExportPresenceModes.fromUserOption(options.exportsPresence) + : options.strictExportPresence + ? ExportPresenceModes.ERROR + : ExportPresenceModes.AUTO; + } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + const { exportPresenceMode } = this; + parser.hooks.export.tap( + "HarmonyExportDependencyParserPlugin", + statement => { + const dep = new HarmonyExportHeaderDependency( + /** @type {Range | false} */ ( + statement.declaration && statement.declaration.range + ), + /** @type {Range} */ (statement.range) + ); + dep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) + ); + dep.loc.index = -1; + parser.state.module.addPresentationalDependency(dep); + return true; + } + ); + parser.hooks.exportImport.tap( + "HarmonyExportDependencyParserPlugin", + (statement, source) => { + parser.state.lastHarmonyImportOrder = + (parser.state.lastHarmonyImportOrder || 0) + 1; + const clearDep = new ConstDependency( + "", + /** @type {Range} */ (statement.range) + ); + clearDep.loc = /** @type {DependencyLocation} */ (statement.loc); + clearDep.loc.index = -1; + parser.state.module.addPresentationalDependency(clearDep); + const sideEffectDep = new HarmonyImportSideEffectDependency( + /** @type {string} */ (source), + parser.state.lastHarmonyImportOrder, + getAttributes(statement) + ); + sideEffectDep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) + ); + sideEffectDep.loc.index = -1; + parser.state.current.addDependency(sideEffectDep); + return true; + } + ); + parser.hooks.exportExpression.tap( + "HarmonyExportDependencyParserPlugin", + (statement, expr) => { + const isFunctionDeclaration = expr.type === "FunctionDeclaration"; + const exprRange = /** @type {Range} */ (expr.range); + const statementRange = /** @type {Range} */ (statement.range); + const comments = parser.getComments([statementRange[0], exprRange[0]]); + const dep = new HarmonyExportExpressionDependency( + exprRange, + statementRange, + comments + .map(c => { + switch (c.type) { + case "Block": + return `/*${c.value}*/`; + case "Line": + return `//${c.value}\n`; + } + return ""; + }) + .join(""), + expr.type.endsWith("Declaration") && expr.id + ? expr.id.name + : isFunctionDeclaration + ? { + range: [ + exprRange[0], + expr.params.length > 0 + ? /** @type {Range} */ (expr.params[0].range)[0] + : /** @type {Range} */ (expr.body.range)[0] + ], + prefix: `${expr.async ? "async " : ""}function${ + expr.generator ? "*" : "" + } `, + suffix: `(${expr.params.length > 0 ? "" : ") "}` + } + : undefined + ); + dep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) + ); + dep.loc.index = -1; + parser.state.current.addDependency(dep); + InnerGraph.addVariableUsage( + parser, + expr.type.endsWith("Declaration") && expr.id + ? expr.id.name + : "*default*", + "default" + ); + return true; + } + ); + parser.hooks.exportSpecifier.tap( + "HarmonyExportDependencyParserPlugin", + (statement, id, name, idx) => { + const settings = parser.getTagData(id, harmonySpecifierTag); + const harmonyNamedExports = (parser.state.harmonyNamedExports = + parser.state.harmonyNamedExports || new Set()); + harmonyNamedExports.add(name); + InnerGraph.addVariableUsage(parser, id, name); + const dep = settings + ? new HarmonyExportImportedSpecifierDependency( + settings.source, + settings.sourceOrder, + settings.ids, + name, + harmonyNamedExports, + null, + exportPresenceMode, + null, + settings.assertions + ) + : new HarmonyExportSpecifierDependency(id, name); + dep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) + ); + dep.loc.index = idx; + const isAsiSafe = !parser.isAsiPosition( + /** @type {Range} */ + (statement.range)[0] + ); + if (!isAsiSafe) { + parser.setAsiPosition(/** @type {Range} */ (statement.range)[1]); + } + parser.state.current.addDependency(dep); + return true; + } + ); + parser.hooks.exportImportSpecifier.tap( + "HarmonyExportDependencyParserPlugin", + (statement, source, id, name, idx) => { + const harmonyNamedExports = (parser.state.harmonyNamedExports = + parser.state.harmonyNamedExports || new Set()); + let harmonyStarExports = null; + if (name) { + harmonyNamedExports.add(name); + } else { + harmonyStarExports = parser.state.harmonyStarExports = + parser.state.harmonyStarExports || new HarmonyStarExportsList(); + } + const dep = new HarmonyExportImportedSpecifierDependency( + /** @type {string} */ (source), + parser.state.lastHarmonyImportOrder, + id ? [id] : [], + name, + harmonyNamedExports, + harmonyStarExports && harmonyStarExports.slice(), + exportPresenceMode, + harmonyStarExports + ); + if (harmonyStarExports) { + harmonyStarExports.push(dep); + } + dep.loc = Object.create( + /** @type {DependencyLocation} */ (statement.loc) + ); + dep.loc.index = idx; + const isAsiSafe = !parser.isAsiPosition( + /** @type {Range} */ + (statement.range)[0] + ); + if (!isAsiSafe) { + parser.setAsiPosition(/** @type {Range} */ (statement.range)[1]); + } + parser.state.current.addDependency(dep); + return true; + } + ); + } +}; diff --git a/node_modules/webpack/lib/dependencies/HarmonyExportExpressionDependency.js b/node_modules/webpack/lib/dependencies/HarmonyExportExpressionDependency.js new file mode 100644 index 00000000..12481cf9 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyExportExpressionDependency.js @@ -0,0 +1,207 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ConcatenationScope = require("../ConcatenationScope"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const propertyAccess = require("../util/propertyAccess"); +const HarmonyExportInitFragment = require("./HarmonyExportInitFragment"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class HarmonyExportExpressionDependency extends NullDependency { + /** + * @param {Range} range range + * @param {Range} rangeStatement range statement + * @param {string} prefix prefix + * @param {string | { range: Range, prefix: string, suffix: string }} [declarationId] declaration id + */ + constructor(range, rangeStatement, prefix, declarationId) { + super(); + this.range = range; + this.rangeStatement = rangeStatement; + this.prefix = prefix; + this.declarationId = declarationId; + } + + get type() { + return "harmony export expression"; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + return { + exports: ["default"], + priority: 1, + terminalBinding: true, + dependencies: undefined + }; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {ConnectionState} how this dependency connects the module to referencing modules + */ + getModuleEvaluationSideEffectsState(moduleGraph) { + // The expression/declaration is already covered by SideEffectsFlagPlugin + return false; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + write(this.rangeStatement); + write(this.prefix); + write(this.declarationId); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.range = read(); + this.rangeStatement = read(); + this.prefix = read(); + this.declarationId = read(); + super.deserialize(context); + } +} + +makeSerializable( + HarmonyExportExpressionDependency, + "webpack/lib/dependencies/HarmonyExportExpressionDependency" +); + +HarmonyExportExpressionDependency.Template = class HarmonyExportDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { + module, + moduleGraph, + runtimeTemplate, + runtimeRequirements, + initFragments, + runtime, + concatenationScope + } + ) { + const dep = /** @type {HarmonyExportExpressionDependency} */ (dependency); + const { declarationId } = dep; + const exportsName = module.exportsArgument; + if (declarationId) { + let name; + if (typeof declarationId === "string") { + name = declarationId; + } else { + name = ConcatenationScope.DEFAULT_EXPORT; + source.replace( + declarationId.range[0], + declarationId.range[1] - 1, + `${declarationId.prefix}${name}${declarationId.suffix}` + ); + } + + if (concatenationScope) { + concatenationScope.registerExport("default", name); + } else { + const used = moduleGraph + .getExportsInfo(module) + .getUsedName("default", runtime); + if (used) { + const map = new Map(); + map.set(used, `/* export default binding */ ${name}`); + initFragments.push(new HarmonyExportInitFragment(exportsName, map)); + } + } + + source.replace( + dep.rangeStatement[0], + dep.range[0] - 1, + `/* harmony default export */ ${dep.prefix}` + ); + } else { + /** @type {string} */ + let content; + const name = ConcatenationScope.DEFAULT_EXPORT; + if (runtimeTemplate.supportsConst()) { + content = `/* harmony default export */ const ${name} = `; + if (concatenationScope) { + concatenationScope.registerExport("default", name); + } else { + const used = moduleGraph + .getExportsInfo(module) + .getUsedName("default", runtime); + if (used) { + runtimeRequirements.add(RuntimeGlobals.exports); + const map = new Map(); + map.set(used, name); + initFragments.push(new HarmonyExportInitFragment(exportsName, map)); + } else { + content = `/* unused harmony default export */ var ${name} = `; + } + } + } else if (concatenationScope) { + content = `/* harmony default export */ var ${name} = `; + concatenationScope.registerExport("default", name); + } else { + const used = moduleGraph + .getExportsInfo(module) + .getUsedName("default", runtime); + if (used) { + runtimeRequirements.add(RuntimeGlobals.exports); + // This is a little bit incorrect as TDZ is not correct, but we can't use const. + content = `/* harmony default export */ ${exportsName}${propertyAccess( + typeof used === "string" ? [used] : used + )} = `; + } else { + content = `/* unused harmony default export */ var ${name} = `; + } + } + + if (dep.range) { + source.replace( + dep.rangeStatement[0], + dep.range[0] - 1, + `${content}(${dep.prefix}` + ); + source.replace(dep.range[1], dep.rangeStatement[1] - 0.5, ");"); + return; + } + + source.replace(dep.rangeStatement[0], dep.rangeStatement[1] - 1, content); + } + } +}; + +module.exports = HarmonyExportExpressionDependency; diff --git a/node_modules/webpack/lib/dependencies/HarmonyExportHeaderDependency.js b/node_modules/webpack/lib/dependencies/HarmonyExportHeaderDependency.js new file mode 100644 index 00000000..ae649796 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyExportHeaderDependency.js @@ -0,0 +1,78 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class HarmonyExportHeaderDependency extends NullDependency { + /** + * @param {Range | false} range range + * @param {Range} rangeStatement range statement + */ + constructor(range, rangeStatement) { + super(); + this.range = range; + this.rangeStatement = rangeStatement; + } + + get type() { + return "harmony export header"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + write(this.rangeStatement); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.range = read(); + this.rangeStatement = read(); + super.deserialize(context); + } +} + +makeSerializable( + HarmonyExportHeaderDependency, + "webpack/lib/dependencies/HarmonyExportHeaderDependency" +); + +HarmonyExportHeaderDependency.Template = class HarmonyExportDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {HarmonyExportHeaderDependency} */ (dependency); + const content = ""; + const replaceUntil = dep.range + ? dep.range[0] - 1 + : dep.rangeStatement[1] - 1; + source.replace(dep.rangeStatement[0], replaceUntil, content); + } +}; + +module.exports = HarmonyExportHeaderDependency; diff --git a/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js b/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js new file mode 100644 index 00000000..a423ad97 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js @@ -0,0 +1,1371 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ConditionalInitFragment = require("../ConditionalInitFragment"); +const Dependency = require("../Dependency"); +const { UsageState } = require("../ExportsInfo"); +const HarmonyLinkingError = require("../HarmonyLinkingError"); +const InitFragment = require("../InitFragment"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const Template = require("../Template"); +const { countIterable } = require("../util/IterableHelpers"); +const { first, combine } = require("../util/SetHelpers"); +const makeSerializable = require("../util/makeSerializable"); +const propertyAccess = require("../util/propertyAccess"); +const { propertyName } = require("../util/propertyName"); +const { + getRuntimeKey, + keyToRuntime, + filterRuntime +} = require("../util/runtime"); +const HarmonyExportInitFragment = require("./HarmonyExportInitFragment"); +const HarmonyImportDependency = require("./HarmonyImportDependency"); +const processExportInfo = require("./processExportInfo"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ExportsInfo")} ExportsInfo */ +/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */ +/** @typedef {import("../ExportsInfo").UsedName} UsedName */ +/** @typedef {import("../Generator").GenerateContext} GenerateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../Module").RuntimeRequirements} RuntimeRequirements */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ +/** @typedef {import("./processExportInfo").ReferencedExports} ReferencedExports */ + +/** @typedef {"missing"|"unused"|"empty-star"|"reexport-dynamic-default"|"reexport-named-default"|"reexport-namespace-object"|"reexport-fake-namespace-object"|"reexport-undefined"|"normal-reexport"|"dynamic-reexport"} ExportModeType */ + +const { ExportPresenceModes } = HarmonyImportDependency; + +const idsSymbol = Symbol("HarmonyExportImportedSpecifierDependency.ids"); + +class NormalReexportItem { + /** + * @param {string} name export name + * @param {string[]} ids reexported ids from other module + * @param {ExportInfo} exportInfo export info from other module + * @param {boolean} checked true, if it should be checked at runtime if this export exists + * @param {boolean} hidden true, if it is hidden behind another active export in the same module + */ + constructor(name, ids, exportInfo, checked, hidden) { + this.name = name; + this.ids = ids; + this.exportInfo = exportInfo; + this.checked = checked; + this.hidden = hidden; + } +} + +/** @typedef {Set<string>} ExportModeIgnored */ +/** @typedef {Set<string>} ExportModeHidden */ + +class ExportMode { + /** + * @param {ExportModeType} type type of the mode + */ + constructor(type) { + /** @type {ExportModeType} */ + this.type = type; + + // for "normal-reexport": + /** @type {NormalReexportItem[] | null} */ + this.items = null; + + // for "reexport-named-default" | "reexport-fake-namespace-object" | "reexport-namespace-object" + /** @type {string | null} */ + this.name = null; + /** @type {ExportInfo | null} */ + this.partialNamespaceExportInfo = null; + + // for "dynamic-reexport": + /** @type {ExportModeIgnored | null} */ + this.ignored = null; + + // for "dynamic-reexport" | "empty-star": + /** @type {ExportModeHidden | null} */ + this.hidden = null; + + // for "missing": + /** @type {string | null} */ + this.userRequest = null; + + // for "reexport-fake-namespace-object": + /** @type {number} */ + this.fakeType = 0; + } +} + +const determineExportAssignments = ( + moduleGraph, + dependencies, + additionalDependency +) => { + const names = new Set(); + const dependencyIndices = []; + + if (additionalDependency) { + dependencies = dependencies.concat(additionalDependency); + } + + for (const dep of dependencies) { + const i = dependencyIndices.length; + dependencyIndices[i] = names.size; + const otherImportedModule = moduleGraph.getModule(dep); + if (otherImportedModule) { + const exportsInfo = moduleGraph.getExportsInfo(otherImportedModule); + for (const exportInfo of exportsInfo.exports) { + if ( + exportInfo.provided === true && + exportInfo.name !== "default" && + !names.has(exportInfo.name) + ) { + names.add(exportInfo.name); + dependencyIndices[i] = names.size; + } + } + } + } + dependencyIndices.push(names.size); + + return { names: Array.from(names), dependencyIndices }; +}; + +const findDependencyForName = ( + { names, dependencyIndices }, + name, + dependencies +) => { + const dependenciesIt = dependencies[Symbol.iterator](); + const dependencyIndicesIt = dependencyIndices[Symbol.iterator](); + let dependenciesItResult = dependenciesIt.next(); + let dependencyIndicesItResult = dependencyIndicesIt.next(); + if (dependencyIndicesItResult.done) return; + for (let i = 0; i < names.length; i++) { + while (i >= dependencyIndicesItResult.value) { + dependenciesItResult = dependenciesIt.next(); + dependencyIndicesItResult = dependencyIndicesIt.next(); + if (dependencyIndicesItResult.done) return; + } + if (names[i] === name) return dependenciesItResult.value; + } + return undefined; +}; + +/** + * @param {ModuleGraph} moduleGraph the module graph + * @param {HarmonyExportImportedSpecifierDependency} dep the dependency + * @param {string} runtimeKey the runtime key + * @returns {ExportMode} the export mode + */ +const getMode = (moduleGraph, dep, runtimeKey) => { + const importedModule = moduleGraph.getModule(dep); + + if (!importedModule) { + const mode = new ExportMode("missing"); + + mode.userRequest = dep.userRequest; + + return mode; + } + + const name = dep.name; + const runtime = keyToRuntime(runtimeKey); + const parentModule = /** @type {Module} */ (moduleGraph.getParentModule(dep)); + const exportsInfo = moduleGraph.getExportsInfo(parentModule); + + if ( + name + ? exportsInfo.getUsed(name, runtime) === UsageState.Unused + : exportsInfo.isUsed(runtime) === false + ) { + const mode = new ExportMode("unused"); + + mode.name = name || "*"; + + return mode; + } + + const importedExportsType = importedModule.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ (parentModule.buildMeta).strictHarmonyModule + ); + + const ids = dep.getIds(moduleGraph); + + // Special handling for reexporting the default export + // from non-namespace modules + if (name && ids.length > 0 && ids[0] === "default") { + switch (importedExportsType) { + case "dynamic": { + const mode = new ExportMode("reexport-dynamic-default"); + + mode.name = name; + + return mode; + } + case "default-only": + case "default-with-named": { + const exportInfo = exportsInfo.getReadOnlyExportInfo(name); + const mode = new ExportMode("reexport-named-default"); + + mode.name = name; + mode.partialNamespaceExportInfo = exportInfo; + + return mode; + } + } + } + + // reexporting with a fixed name + if (name) { + let mode; + const exportInfo = exportsInfo.getReadOnlyExportInfo(name); + + if (ids.length > 0) { + // export { name as name } + switch (importedExportsType) { + case "default-only": + mode = new ExportMode("reexport-undefined"); + mode.name = name; + break; + default: + mode = new ExportMode("normal-reexport"); + mode.items = [ + new NormalReexportItem(name, ids, exportInfo, false, false) + ]; + break; + } + } else { + // export * as name + switch (importedExportsType) { + case "default-only": + mode = new ExportMode("reexport-fake-namespace-object"); + mode.name = name; + mode.partialNamespaceExportInfo = exportInfo; + mode.fakeType = 0; + break; + case "default-with-named": + mode = new ExportMode("reexport-fake-namespace-object"); + mode.name = name; + mode.partialNamespaceExportInfo = exportInfo; + mode.fakeType = 2; + break; + case "dynamic": + default: + mode = new ExportMode("reexport-namespace-object"); + mode.name = name; + mode.partialNamespaceExportInfo = exportInfo; + } + } + + return mode; + } + + // Star reexporting + + const { ignoredExports, exports, checked, hidden } = dep.getStarReexports( + moduleGraph, + runtime, + exportsInfo, + importedModule + ); + if (!exports) { + // We have too few info about the modules + // Delegate the logic to the runtime code + + const mode = new ExportMode("dynamic-reexport"); + mode.ignored = ignoredExports; + mode.hidden = hidden; + + return mode; + } + + if (exports.size === 0) { + const mode = new ExportMode("empty-star"); + mode.hidden = hidden; + + return mode; + } + + const mode = new ExportMode("normal-reexport"); + + mode.items = Array.from( + exports, + exportName => + new NormalReexportItem( + exportName, + [exportName], + exportsInfo.getReadOnlyExportInfo(exportName), + /** @type {Set<string>} */ + (checked).has(exportName), + false + ) + ); + if (hidden !== undefined) { + for (const exportName of hidden) { + mode.items.push( + new NormalReexportItem( + exportName, + [exportName], + exportsInfo.getReadOnlyExportInfo(exportName), + false, + true + ) + ); + } + } + + return mode; +}; + +/** @typedef {string[]} Ids */ +/** @typedef {Set<string>} Exports */ +/** @typedef {Set<string>} Checked */ +/** @typedef {Set<string>} Hidden */ +/** @typedef {Set<string>} IgnoredExports */ + +class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency { + /** + * @param {string} request the request string + * @param {number} sourceOrder the order in the original source file + * @param {Ids} ids the requested export name of the imported module + * @param {string | null} name the export name of for this module + * @param {Set<string>} activeExports other named exports in the module + * @param {ReadonlyArray<HarmonyExportImportedSpecifierDependency> | Iterable<HarmonyExportImportedSpecifierDependency> | null} otherStarExports other star exports in the module before this import + * @param {number} exportPresenceMode mode of checking export names + * @param {HarmonyStarExportsList | null} allStarExports all star exports in the module + * @param {ImportAttributes=} attributes import attributes + */ + constructor( + request, + sourceOrder, + ids, + name, + activeExports, + otherStarExports, + exportPresenceMode, + allStarExports, + attributes + ) { + super(request, sourceOrder, attributes); + + this.ids = ids; + this.name = name; + this.activeExports = activeExports; + this.otherStarExports = otherStarExports; + this.exportPresenceMode = exportPresenceMode; + this.allStarExports = allStarExports; + } + + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return Dependency.TRANSITIVE; + } + + // TODO webpack 6 remove + get id() { + throw new Error("id was renamed to ids and type changed to string[]"); + } + + // TODO webpack 6 remove + getId() { + throw new Error("id was renamed to ids and type changed to string[]"); + } + + // TODO webpack 6 remove + setId() { + throw new Error("id was renamed to ids and type changed to string[]"); + } + + get type() { + return "harmony export imported specifier"; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {Ids} the imported id + */ + getIds(moduleGraph) { + return moduleGraph.getMeta(this)[idsSymbol] || this.ids; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @param {Ids} ids the imported ids + * @returns {void} + */ + setIds(moduleGraph, ids) { + moduleGraph.getMeta(this)[idsSymbol] = ids; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @param {RuntimeSpec} runtime the runtime + * @returns {ExportMode} the export mode + */ + getMode(moduleGraph, runtime) { + return moduleGraph.dependencyCacheProvide( + this, + getRuntimeKey(runtime), + getMode + ); + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @param {RuntimeSpec} runtime the runtime + * @param {ExportsInfo} exportsInfo exports info about the current module (optional) + * @param {Module} importedModule the imported module (optional) + * @returns {{exports?: Exports, checked?: Checked, ignoredExports: IgnoredExports, hidden?: Hidden}} information + */ + getStarReexports( + moduleGraph, + runtime, + exportsInfo = moduleGraph.getExportsInfo( + /** @type {Module} */ (moduleGraph.getParentModule(this)) + ), + importedModule = /** @type {Module} */ (moduleGraph.getModule(this)) + ) { + const importedExportsInfo = moduleGraph.getExportsInfo(importedModule); + const noExtraExports = + importedExportsInfo.otherExportsInfo.provided === false; + const noExtraImports = + exportsInfo.otherExportsInfo.getUsed(runtime) === UsageState.Unused; + + const ignoredExports = new Set(["default", ...this.activeExports]); + + let hiddenExports; + const otherStarExports = + this._discoverActiveExportsFromOtherStarExports(moduleGraph); + if (otherStarExports !== undefined) { + hiddenExports = new Set(); + for (let i = 0; i < otherStarExports.namesSlice; i++) { + hiddenExports.add(otherStarExports.names[i]); + } + for (const e of ignoredExports) hiddenExports.delete(e); + } + + if (!noExtraExports && !noExtraImports) { + return { + ignoredExports, + hidden: hiddenExports + }; + } + + /** @type {Exports} */ + const exports = new Set(); + /** @type {Checked} */ + const checked = new Set(); + /** @type {Hidden | undefined} */ + const hidden = hiddenExports !== undefined ? new Set() : undefined; + + if (noExtraImports) { + for (const exportInfo of exportsInfo.orderedExports) { + const name = exportInfo.name; + if (ignoredExports.has(name)) continue; + if (exportInfo.getUsed(runtime) === UsageState.Unused) continue; + const importedExportInfo = + importedExportsInfo.getReadOnlyExportInfo(name); + if (importedExportInfo.provided === false) continue; + if (hiddenExports !== undefined && hiddenExports.has(name)) { + /** @type {Set<string>} */ + (hidden).add(name); + continue; + } + exports.add(name); + if (importedExportInfo.provided === true) continue; + checked.add(name); + } + } else if (noExtraExports) { + for (const importedExportInfo of importedExportsInfo.orderedExports) { + const name = importedExportInfo.name; + if (ignoredExports.has(name)) continue; + if (importedExportInfo.provided === false) continue; + const exportInfo = exportsInfo.getReadOnlyExportInfo(name); + if (exportInfo.getUsed(runtime) === UsageState.Unused) continue; + if (hiddenExports !== undefined && hiddenExports.has(name)) { + /** @type {ExportModeHidden} */ + (hidden).add(name); + continue; + } + exports.add(name); + if (importedExportInfo.provided === true) continue; + checked.add(name); + } + } + + return { ignoredExports, exports, checked, hidden }; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {null | false | GetConditionFn} function to determine if the connection is active + */ + getCondition(moduleGraph) { + return (connection, runtime) => { + const mode = this.getMode(moduleGraph, runtime); + return mode.type !== "unused" && mode.type !== "empty-star"; + }; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {ConnectionState} how this dependency connects the module to referencing modules + */ + getModuleEvaluationSideEffectsState(moduleGraph) { + return false; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + const mode = this.getMode(moduleGraph, runtime); + + switch (mode.type) { + case "missing": + case "unused": + case "empty-star": + case "reexport-undefined": + return Dependency.NO_EXPORTS_REFERENCED; + + case "reexport-dynamic-default": + return Dependency.EXPORTS_OBJECT_REFERENCED; + + case "reexport-named-default": { + if (!mode.partialNamespaceExportInfo) + return Dependency.EXPORTS_OBJECT_REFERENCED; + /** @type {ReferencedExports} */ + const referencedExports = []; + processExportInfo( + runtime, + referencedExports, + [], + /** @type {ExportInfo} */ (mode.partialNamespaceExportInfo) + ); + return referencedExports; + } + + case "reexport-namespace-object": + case "reexport-fake-namespace-object": { + if (!mode.partialNamespaceExportInfo) + return Dependency.EXPORTS_OBJECT_REFERENCED; + /** @type {ReferencedExports} */ + const referencedExports = []; + processExportInfo( + runtime, + referencedExports, + [], + /** @type {ExportInfo} */ (mode.partialNamespaceExportInfo), + mode.type === "reexport-fake-namespace-object" + ); + return referencedExports; + } + + case "dynamic-reexport": + return Dependency.EXPORTS_OBJECT_REFERENCED; + + case "normal-reexport": { + /** @type {ReferencedExports} */ + const referencedExports = []; + for (const { ids, exportInfo, hidden } of mode.items) { + if (hidden) continue; + processExportInfo(runtime, referencedExports, ids, exportInfo, false); + } + return referencedExports; + } + + default: + throw new Error(`Unknown mode ${mode.type}`); + } + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {{ names: string[], namesSlice: number, dependencyIndices: number[], dependencyIndex: number } | undefined} exported names and their origin dependency + */ + _discoverActiveExportsFromOtherStarExports(moduleGraph) { + if (!this.otherStarExports) return; + + const i = + "length" in this.otherStarExports + ? this.otherStarExports.length + : countIterable(this.otherStarExports); + if (i === 0) return; + + if (this.allStarExports) { + const { names, dependencyIndices } = moduleGraph.cached( + determineExportAssignments, + this.allStarExports.dependencies + ); + + return { + names, + namesSlice: dependencyIndices[i - 1], + dependencyIndices, + dependencyIndex: i + }; + } + + const { names, dependencyIndices } = moduleGraph.cached( + determineExportAssignments, + this.otherStarExports, + this + ); + + return { + names, + namesSlice: dependencyIndices[i - 1], + dependencyIndices, + dependencyIndex: i + }; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + const mode = this.getMode(moduleGraph, undefined); + + switch (mode.type) { + case "missing": + return; + case "dynamic-reexport": { + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); + return { + exports: true, + from, + canMangle: false, + excludeExports: mode.hidden + ? combine( + /** @type {ExportModeIgnored} */ (mode.ignored), + mode.hidden + ) + : /** @type {ExportModeIgnored} */ (mode.ignored), + hideExports: mode.hidden, + dependencies: [from.module] + }; + } + case "empty-star": + return { + exports: [], + hideExports: mode.hidden, + dependencies: [/** @type {Module} */ (moduleGraph.getModule(this))] + }; + // falls through + case "normal-reexport": { + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); + return { + exports: Array.from(mode.items, item => ({ + name: item.name, + from, + export: item.ids, + hidden: item.hidden + })), + priority: 1, + dependencies: [from.module] + }; + } + case "reexport-dynamic-default": { + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); + return { + exports: [ + { + name: /** @type {string} */ (mode.name), + from, + export: ["default"] + } + ], + priority: 1, + dependencies: [from.module] + }; + } + case "reexport-undefined": + return { + exports: [/** @type {string} */ (mode.name)], + dependencies: [/** @type {Module} */ (moduleGraph.getModule(this))] + }; + case "reexport-fake-namespace-object": { + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); + return { + exports: [ + { + name: /** @type {string} */ (mode.name), + from, + export: null, + exports: [ + { + name: "default", + canMangle: false, + from, + export: null + } + ] + } + ], + priority: 1, + dependencies: [from.module] + }; + } + case "reexport-namespace-object": { + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); + return { + exports: [ + { + name: /** @type {string} */ (mode.name), + from, + export: null + } + ], + priority: 1, + dependencies: [from.module] + }; + } + case "reexport-named-default": { + const from = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(this)); + return { + exports: [ + { + name: /** @type {string} */ (mode.name), + from, + export: ["default"] + } + ], + priority: 1, + dependencies: [from.module] + }; + } + default: + throw new Error(`Unknown mode ${mode.type}`); + } + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {number} effective mode + */ + _getEffectiveExportPresenceLevel(moduleGraph) { + if (this.exportPresenceMode !== ExportPresenceModes.AUTO) + return this.exportPresenceMode; + const module = /** @type {Module} */ (moduleGraph.getParentModule(this)); + return /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule + ? ExportPresenceModes.ERROR + : ExportPresenceModes.WARN; + } + + /** + * Returns warnings + * @param {ModuleGraph} moduleGraph module graph + * @returns {WebpackError[] | null | undefined} warnings + */ + getWarnings(moduleGraph) { + const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph); + if (exportsPresence === ExportPresenceModes.WARN) { + return this._getErrors(moduleGraph); + } + return null; + } + + /** + * Returns errors + * @param {ModuleGraph} moduleGraph module graph + * @returns {WebpackError[] | null | undefined} errors + */ + getErrors(moduleGraph) { + const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph); + if (exportsPresence === ExportPresenceModes.ERROR) { + return this._getErrors(moduleGraph); + } + return null; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {WebpackError[] | undefined} errors + */ + _getErrors(moduleGraph) { + const ids = this.getIds(moduleGraph); + let errors = this.getLinkingErrors( + moduleGraph, + ids, + `(reexported as '${this.name}')` + ); + if (ids.length === 0 && this.name === null) { + const potentialConflicts = + this._discoverActiveExportsFromOtherStarExports(moduleGraph); + if (potentialConflicts && potentialConflicts.namesSlice > 0) { + const ownNames = new Set( + potentialConflicts.names.slice( + potentialConflicts.namesSlice, + potentialConflicts.dependencyIndices[ + potentialConflicts.dependencyIndex + ] + ) + ); + const importedModule = moduleGraph.getModule(this); + if (importedModule) { + const exportsInfo = moduleGraph.getExportsInfo(importedModule); + /** @type {Map<string, string[]>} */ + const conflicts = new Map(); + for (const exportInfo of exportsInfo.orderedExports) { + if (exportInfo.provided !== true) continue; + if (exportInfo.name === "default") continue; + if (this.activeExports.has(exportInfo.name)) continue; + if (ownNames.has(exportInfo.name)) continue; + const conflictingDependency = findDependencyForName( + potentialConflicts, + exportInfo.name, + this.allStarExports + ? this.allStarExports.dependencies + : [...this.otherStarExports, this] + ); + if (!conflictingDependency) continue; + const target = exportInfo.getTerminalBinding(moduleGraph); + if (!target) continue; + const conflictingModule = + /** @type {Module} */ + (moduleGraph.getModule(conflictingDependency)); + if (conflictingModule === importedModule) continue; + const conflictingExportInfo = moduleGraph.getExportInfo( + conflictingModule, + exportInfo.name + ); + const conflictingTarget = + conflictingExportInfo.getTerminalBinding(moduleGraph); + if (!conflictingTarget) continue; + if (target === conflictingTarget) continue; + const list = conflicts.get(conflictingDependency.request); + if (list === undefined) { + conflicts.set(conflictingDependency.request, [exportInfo.name]); + } else { + list.push(exportInfo.name); + } + } + for (const [request, exports] of conflicts) { + if (!errors) errors = []; + errors.push( + new HarmonyLinkingError( + `The requested module '${ + this.request + }' contains conflicting star exports for the ${ + exports.length > 1 ? "names" : "name" + } ${exports + .map(e => `'${e}'`) + .join(", ")} with the previous requested module '${request}'` + ) + ); + } + } + } + } + return errors; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write, setCircularReference } = context; + + setCircularReference(this); + write(this.ids); + write(this.name); + write(this.activeExports); + write(this.otherStarExports); + write(this.exportPresenceMode); + write(this.allStarExports); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read, setCircularReference } = context; + + setCircularReference(this); + this.ids = read(); + this.name = read(); + this.activeExports = read(); + this.otherStarExports = read(); + this.exportPresenceMode = read(); + this.allStarExports = read(); + + super.deserialize(context); + } +} + +makeSerializable( + HarmonyExportImportedSpecifierDependency, + "webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency" +); + +module.exports = HarmonyExportImportedSpecifierDependency; + +HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedSpecifierDependencyTemplate extends ( + HarmonyImportDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const { moduleGraph, runtime, concatenationScope } = templateContext; + + const dep = /** @type {HarmonyExportImportedSpecifierDependency} */ ( + dependency + ); + + const mode = dep.getMode(moduleGraph, runtime); + + if (concatenationScope) { + switch (mode.type) { + case "reexport-undefined": + concatenationScope.registerRawExport( + /** @type {NonNullable<ExportMode["name"]>} */ (mode.name), + "/* reexport non-default export from non-harmony */ undefined" + ); + } + return; + } + + if (mode.type !== "unused" && mode.type !== "empty-star") { + super.apply(dependency, source, templateContext); + + this._addExportFragments( + templateContext.initFragments, + dep, + mode, + templateContext.module, + moduleGraph, + runtime, + templateContext.runtimeTemplate, + templateContext.runtimeRequirements + ); + } + } + + /** + * @param {InitFragment<GenerateContext>[]} initFragments target array for init fragments + * @param {HarmonyExportImportedSpecifierDependency} dep dependency + * @param {ExportMode} mode the export mode + * @param {Module} module the current module + * @param {ModuleGraph} moduleGraph the module graph + * @param {RuntimeSpec} runtime the runtime + * @param {RuntimeTemplate} runtimeTemplate the runtime template + * @param {RuntimeRequirements} runtimeRequirements runtime requirements + * @returns {void} + */ + _addExportFragments( + initFragments, + dep, + mode, + module, + moduleGraph, + runtime, + runtimeTemplate, + runtimeRequirements + ) { + const importedModule = /** @type {Module} */ (moduleGraph.getModule(dep)); + const importVar = dep.getImportVar(moduleGraph); + + switch (mode.type) { + case "missing": + case "empty-star": + initFragments.push( + new InitFragment( + "/* empty/unused harmony star reexport */\n", + InitFragment.STAGE_HARMONY_EXPORTS, + 1 + ) + ); + break; + + case "unused": + initFragments.push( + new InitFragment( + `${Template.toNormalComment( + `unused harmony reexport ${mode.name}` + )}\n`, + InitFragment.STAGE_HARMONY_EXPORTS, + 1 + ) + ); + break; + + case "reexport-dynamic-default": + initFragments.push( + this.getReexportFragment( + module, + "reexport default from dynamic", + moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime), + importVar, + null, + runtimeRequirements + ) + ); + break; + + case "reexport-fake-namespace-object": + initFragments.push( + ...this.getReexportFakeNamespaceObjectFragments( + module, + moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime), + importVar, + mode.fakeType, + runtimeRequirements + ) + ); + break; + + case "reexport-undefined": + initFragments.push( + this.getReexportFragment( + module, + "reexport non-default export from non-harmony", + moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime), + "undefined", + "", + runtimeRequirements + ) + ); + break; + + case "reexport-named-default": + initFragments.push( + this.getReexportFragment( + module, + "reexport default export from named module", + moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime), + importVar, + "", + runtimeRequirements + ) + ); + break; + + case "reexport-namespace-object": + initFragments.push( + this.getReexportFragment( + module, + "reexport module object", + moduleGraph.getExportsInfo(module).getUsedName(mode.name, runtime), + importVar, + "", + runtimeRequirements + ) + ); + break; + + case "normal-reexport": + for (const { + name, + ids, + checked, + hidden + } of /** @type {NormalReexportItem[]} */ (mode.items)) { + if (hidden) continue; + if (checked) { + const connection = moduleGraph.getConnection(dep); + const key = `harmony reexport (checked) ${importVar} ${name}`; + const runtimeCondition = dep.weak + ? false + : connection + ? filterRuntime(runtime, r => connection.isTargetActive(r)) + : true; + initFragments.push( + new ConditionalInitFragment( + `/* harmony reexport (checked) */ ${this.getConditionalReexportStatement( + module, + name, + importVar, + ids, + runtimeRequirements + )}`, + moduleGraph.isAsync(importedModule) + ? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS + : InitFragment.STAGE_HARMONY_IMPORTS, + dep.sourceOrder, + key, + runtimeCondition + ) + ); + } else { + initFragments.push( + this.getReexportFragment( + module, + "reexport safe", + moduleGraph.getExportsInfo(module).getUsedName(name, runtime), + importVar, + moduleGraph + .getExportsInfo(importedModule) + .getUsedName(ids, runtime), + runtimeRequirements + ) + ); + } + } + break; + + case "dynamic-reexport": { + const ignored = mode.hidden + ? combine( + /** @type {ExportModeIgnored} */ + (mode.ignored), + mode.hidden + ) + : /** @type {ExportModeIgnored} */ (mode.ignored); + const modern = + runtimeTemplate.supportsConst() && + runtimeTemplate.supportsArrowFunction(); + let content = + "/* harmony reexport (unknown) */ var __WEBPACK_REEXPORT_OBJECT__ = {};\n" + + `/* harmony reexport (unknown) */ for(${ + modern ? "const" : "var" + } __WEBPACK_IMPORT_KEY__ in ${importVar}) `; + + // Filter out exports which are defined by other exports + // and filter out default export because it cannot be reexported with * + if (ignored.size > 1) { + content += `if(${JSON.stringify( + Array.from(ignored) + )}.indexOf(__WEBPACK_IMPORT_KEY__) < 0) `; + } else if (ignored.size === 1) { + content += `if(__WEBPACK_IMPORT_KEY__ !== ${JSON.stringify( + first(ignored) + )}) `; + } + + content += "__WEBPACK_REEXPORT_OBJECT__[__WEBPACK_IMPORT_KEY__] = "; + content += modern + ? `() => ${importVar}[__WEBPACK_IMPORT_KEY__]` + : `function(key) { return ${importVar}[key]; }.bind(0, __WEBPACK_IMPORT_KEY__)`; + + runtimeRequirements.add(RuntimeGlobals.exports); + runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); + + const exportsName = module.exportsArgument; + initFragments.push( + new InitFragment( + `${content}\n/* harmony reexport (unknown) */ ${RuntimeGlobals.definePropertyGetters}(${exportsName}, __WEBPACK_REEXPORT_OBJECT__);\n`, + moduleGraph.isAsync(importedModule) + ? InitFragment.STAGE_ASYNC_HARMONY_IMPORTS + : InitFragment.STAGE_HARMONY_IMPORTS, + dep.sourceOrder + ) + ); + break; + } + + default: + throw new Error(`Unknown mode ${mode.type}`); + } + } + + /** + * @param {Module} module the current module + * @param {string} comment comment + * @param {UsedName} key key + * @param {string} name name + * @param {string | string[] | null | false} valueKey value key + * @param {RuntimeRequirements} runtimeRequirements runtime requirements + * @returns {HarmonyExportInitFragment} harmony export init fragment + */ + getReexportFragment( + module, + comment, + key, + name, + valueKey, + runtimeRequirements + ) { + const returnValue = this.getReturnValue(name, valueKey); + + runtimeRequirements.add(RuntimeGlobals.exports); + runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); + + const map = new Map(); + map.set(key, `/* ${comment} */ ${returnValue}`); + + return new HarmonyExportInitFragment(module.exportsArgument, map); + } + + /** + * @param {Module} module module + * @param {string | string[] | false} key key + * @param {string} name name + * @param {number} fakeType fake type + * @param {RuntimeRequirements} runtimeRequirements runtime requirements + * @returns {[InitFragment<GenerateContext>, HarmonyExportInitFragment]} init fragments + */ + getReexportFakeNamespaceObjectFragments( + module, + key, + name, + fakeType, + runtimeRequirements + ) { + runtimeRequirements.add(RuntimeGlobals.exports); + runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); + runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject); + + const map = new Map(); + map.set( + key, + `/* reexport fake namespace object from non-harmony */ ${name}_namespace_cache || (${name}_namespace_cache = ${ + RuntimeGlobals.createFakeNamespaceObject + }(${name}${fakeType ? `, ${fakeType}` : ""}))` + ); + + return [ + new InitFragment( + `var ${name}_namespace_cache;\n`, + InitFragment.STAGE_CONSTANTS, + -1, + `${name}_namespace_cache` + ), + new HarmonyExportInitFragment(module.exportsArgument, map) + ]; + } + + /** + * @param {Module} module module + * @param {string} key key + * @param {string} name name + * @param {string | string[] | false} valueKey value key + * @param {RuntimeRequirements} runtimeRequirements runtime requirements + * @returns {string} result + */ + getConditionalReexportStatement( + module, + key, + name, + valueKey, + runtimeRequirements + ) { + if (valueKey === false) { + return "/* unused export */\n"; + } + + const exportsName = module.exportsArgument; + const returnValue = this.getReturnValue(name, valueKey); + + runtimeRequirements.add(RuntimeGlobals.exports); + runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); + runtimeRequirements.add(RuntimeGlobals.hasOwnProperty); + + return `if(${RuntimeGlobals.hasOwnProperty}(${name}, ${JSON.stringify( + valueKey[0] + )})) ${ + RuntimeGlobals.definePropertyGetters + }(${exportsName}, { ${propertyName( + key + )}: function() { return ${returnValue}; } });\n`; + } + + /** + * @param {string} name name + * @param {null | false | string | string[]} valueKey value key + * @returns {string | undefined} value + */ + getReturnValue(name, valueKey) { + if (valueKey === null) { + return `${name}_default.a`; + } + + if (valueKey === "") { + return name; + } + + if (valueKey === false) { + return "/* unused export */ undefined"; + } + + return `${name}${propertyAccess(valueKey)}`; + } +}; + +class HarmonyStarExportsList { + constructor() { + /** @type {HarmonyExportImportedSpecifierDependency[]} */ + this.dependencies = []; + } + + /** + * @param {HarmonyExportImportedSpecifierDependency} dep dependency + * @returns {void} + */ + push(dep) { + this.dependencies.push(dep); + } + + slice() { + return this.dependencies.slice(); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize({ write, setCircularReference }) { + setCircularReference(this); + write(this.dependencies); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize({ read, setCircularReference }) { + setCircularReference(this); + this.dependencies = read(); + } +} + +makeSerializable( + HarmonyStarExportsList, + "webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency", + "HarmonyStarExportsList" +); + +module.exports.HarmonyStarExportsList = HarmonyStarExportsList; diff --git a/node_modules/webpack/lib/dependencies/HarmonyExportInitFragment.js b/node_modules/webpack/lib/dependencies/HarmonyExportInitFragment.js new file mode 100644 index 00000000..8125cc2d --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyExportInitFragment.js @@ -0,0 +1,177 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const InitFragment = require("../InitFragment"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const { first } = require("../util/SetHelpers"); +const { propertyName } = require("../util/propertyName"); + +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../Generator").GenerateContext} GenerateContext */ + +/** + * @param {Iterable<string>} iterable iterable strings + * @returns {string} result + */ +const joinIterableWithComma = iterable => { + // This is more performant than Array.from().join(", ") + // as it doesn't create an array + let str = ""; + let first = true; + for (const item of iterable) { + if (first) { + first = false; + } else { + str += ", "; + } + str += item; + } + return str; +}; + +const EMPTY_MAP = new Map(); +const EMPTY_SET = new Set(); + +/** + * @extends {InitFragment<GenerateContext>} Context + */ +class HarmonyExportInitFragment extends InitFragment { + /** + * @param {string} exportsArgument the exports identifier + * @param {Map<string, string>} exportMap mapping from used name to exposed variable name + * @param {Set<string>} unusedExports list of unused export names + */ + constructor( + exportsArgument, + exportMap = EMPTY_MAP, + unusedExports = EMPTY_SET + ) { + super(undefined, InitFragment.STAGE_HARMONY_EXPORTS, 1, "harmony-exports"); + this.exportsArgument = exportsArgument; + this.exportMap = exportMap; + this.unusedExports = unusedExports; + } + + /** + * @param {HarmonyExportInitFragment[]} fragments all fragments to merge + * @returns {HarmonyExportInitFragment} merged fragment + */ + mergeAll(fragments) { + let exportMap; + let exportMapOwned = false; + let unusedExports; + let unusedExportsOwned = false; + + for (const fragment of fragments) { + if (fragment.exportMap.size !== 0) { + if (exportMap === undefined) { + exportMap = fragment.exportMap; + exportMapOwned = false; + } else { + if (!exportMapOwned) { + exportMap = new Map(exportMap); + exportMapOwned = true; + } + for (const [key, value] of fragment.exportMap) { + if (!exportMap.has(key)) exportMap.set(key, value); + } + } + } + if (fragment.unusedExports.size !== 0) { + if (unusedExports === undefined) { + unusedExports = fragment.unusedExports; + unusedExportsOwned = false; + } else { + if (!unusedExportsOwned) { + unusedExports = new Set(unusedExports); + unusedExportsOwned = true; + } + for (const value of fragment.unusedExports) { + unusedExports.add(value); + } + } + } + } + return new HarmonyExportInitFragment( + this.exportsArgument, + exportMap, + unusedExports + ); + } + + /** + * @param {HarmonyExportInitFragment} other other + * @returns {HarmonyExportInitFragment} merged result + */ + merge(other) { + let exportMap; + if (this.exportMap.size === 0) { + exportMap = other.exportMap; + } else if (other.exportMap.size === 0) { + exportMap = this.exportMap; + } else { + exportMap = new Map(other.exportMap); + for (const [key, value] of this.exportMap) { + if (!exportMap.has(key)) exportMap.set(key, value); + } + } + let unusedExports; + if (this.unusedExports.size === 0) { + unusedExports = other.unusedExports; + } else if (other.unusedExports.size === 0) { + unusedExports = this.unusedExports; + } else { + unusedExports = new Set(other.unusedExports); + for (const value of this.unusedExports) { + unusedExports.add(value); + } + } + return new HarmonyExportInitFragment( + this.exportsArgument, + exportMap, + unusedExports + ); + } + + /** + * @param {GenerateContext} context context + * @returns {string | Source | undefined} the source code that will be included as initialization code + */ + getContent({ runtimeTemplate, runtimeRequirements }) { + runtimeRequirements.add(RuntimeGlobals.exports); + runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); + + const unusedPart = + this.unusedExports.size > 1 + ? `/* unused harmony exports ${joinIterableWithComma( + this.unusedExports + )} */\n` + : this.unusedExports.size > 0 + ? `/* unused harmony export ${first(this.unusedExports)} */\n` + : ""; + const definitions = []; + const orderedExportMap = Array.from(this.exportMap).sort(([a], [b]) => + a < b ? -1 : 1 + ); + for (const [key, value] of orderedExportMap) { + definitions.push( + `\n/* harmony export */ ${propertyName( + key + )}: ${runtimeTemplate.returningFunction(value)}` + ); + } + const definePart = + this.exportMap.size > 0 + ? `/* harmony export */ ${RuntimeGlobals.definePropertyGetters}(${ + this.exportsArgument + }, {${definitions.join(",")}\n/* harmony export */ });\n` + : ""; + return `${definePart}${unusedPart}`; + } +} + +module.exports = HarmonyExportInitFragment; diff --git a/node_modules/webpack/lib/dependencies/HarmonyExportSpecifierDependency.js b/node_modules/webpack/lib/dependencies/HarmonyExportSpecifierDependency.js new file mode 100644 index 00000000..4e742935 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyExportSpecifierDependency.js @@ -0,0 +1,123 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const HarmonyExportInitFragment = require("./HarmonyExportInitFragment"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class HarmonyExportSpecifierDependency extends NullDependency { + /** + * @param {TODO} id id + * @param {TODO} name name + */ + constructor(id, name) { + super(); + this.id = id; + this.name = name; + } + + get type() { + return "harmony export specifier"; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + return { + exports: [this.name], + priority: 1, + terminalBinding: true, + dependencies: undefined + }; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {ConnectionState} how this dependency connects the module to referencing modules + */ + getModuleEvaluationSideEffectsState(moduleGraph) { + return false; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.id); + write(this.name); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.id = read(); + this.name = read(); + super.deserialize(context); + } +} + +makeSerializable( + HarmonyExportSpecifierDependency, + "webpack/lib/dependencies/HarmonyExportSpecifierDependency" +); + +HarmonyExportSpecifierDependency.Template = class HarmonyExportSpecifierDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { module, moduleGraph, initFragments, runtime, concatenationScope } + ) { + const dep = /** @type {HarmonyExportSpecifierDependency} */ (dependency); + if (concatenationScope) { + concatenationScope.registerExport(dep.name, dep.id); + return; + } + const used = moduleGraph + .getExportsInfo(module) + .getUsedName(dep.name, runtime); + if (!used) { + const set = new Set(); + set.add(dep.name || "namespace"); + initFragments.push( + new HarmonyExportInitFragment(module.exportsArgument, undefined, set) + ); + return; + } + + const map = new Map(); + map.set(used, `/* binding */ ${dep.id}`); + initFragments.push( + new HarmonyExportInitFragment(module.exportsArgument, map, undefined) + ); + } +}; + +module.exports = HarmonyExportSpecifierDependency; diff --git a/node_modules/webpack/lib/dependencies/HarmonyExports.js b/node_modules/webpack/lib/dependencies/HarmonyExports.js new file mode 100644 index 00000000..1f6e6d4a --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyExports.js @@ -0,0 +1,46 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); + +/** @typedef {import("../Module").BuildInfo} BuildInfo */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../Parser").ParserState} ParserState */ + +/** @type {WeakMap<ParserState, boolean>} */ +const parserStateExportsState = new WeakMap(); + +/** + * @param {ParserState} parserState parser state + * @param {boolean} isStrictHarmony strict harmony mode should be enabled + * @returns {void} + */ +module.exports.enable = (parserState, isStrictHarmony) => { + const value = parserStateExportsState.get(parserState); + if (value === false) return; + parserStateExportsState.set(parserState, true); + if (value !== true) { + const buildMeta = /** @type {BuildMeta} */ (parserState.module.buildMeta); + buildMeta.exportsType = "namespace"; + const buildInfo = /** @type {BuildInfo} */ (parserState.module.buildInfo); + buildInfo.strict = true; + buildInfo.exportsArgument = RuntimeGlobals.exports; + if (isStrictHarmony) { + buildMeta.strictHarmonyModule = true; + buildInfo.moduleArgument = "__webpack_module__"; + } + } +}; + +/** + * @param {ParserState} parserState parser state + * @returns {boolean} true, when enabled + */ +module.exports.isEnabled = parserState => { + const value = parserStateExportsState.get(parserState); + return value === true; +}; diff --git a/node_modules/webpack/lib/dependencies/HarmonyImportDependency.js b/node_modules/webpack/lib/dependencies/HarmonyImportDependency.js new file mode 100644 index 00000000..e9f26fc9 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyImportDependency.js @@ -0,0 +1,382 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ConditionalInitFragment = require("../ConditionalInitFragment"); +const Dependency = require("../Dependency"); +const HarmonyLinkingError = require("../HarmonyLinkingError"); +const InitFragment = require("../InitFragment"); +const Template = require("../Template"); +const AwaitDependenciesInitFragment = require("../async-modules/AwaitDependenciesInitFragment"); +const { filterRuntime, mergeRuntime } = require("../util/runtime"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("webpack-sources").Source} Source */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ExportsInfo")} ExportsInfo */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +const ExportPresenceModes = { + NONE: /** @type {0} */ (0), + WARN: /** @type {1} */ (1), + AUTO: /** @type {2} */ (2), + ERROR: /** @type {3} */ (3), + /** + * @param {string | false} str param + * @returns {0 | 1 | 2 | 3} result + */ + fromUserOption(str) { + switch (str) { + case "error": + return ExportPresenceModes.ERROR; + case "warn": + return ExportPresenceModes.WARN; + case "auto": + return ExportPresenceModes.AUTO; + case false: + return ExportPresenceModes.NONE; + default: + throw new Error(`Invalid export presence value ${str}`); + } + } +}; + +class HarmonyImportDependency extends ModuleDependency { + /** + * @param {string} request request string + * @param {number} sourceOrder source order + * @param {ImportAttributes=} attributes import attributes + */ + constructor(request, sourceOrder, attributes) { + super(request); + this.sourceOrder = sourceOrder; + this.assertions = attributes; + } + + get category() { + return "esm"; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + return Dependency.NO_EXPORTS_REFERENCED; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {string} name of the variable for the import + */ + getImportVar(moduleGraph) { + const module = /** @type {Module} */ (moduleGraph.getParentModule(this)); + const meta = /** @type {TODO} */ (moduleGraph.getMeta(module)); + let importVarMap = meta.importVarMap; + if (!importVarMap) meta.importVarMap = importVarMap = new Map(); + let importVar = importVarMap.get( + /** @type {Module} */ (moduleGraph.getModule(this)) + ); + if (importVar) return importVar; + importVar = `${Template.toIdentifier( + `${this.userRequest}` + )}__WEBPACK_IMPORTED_MODULE_${importVarMap.size}__`; + importVarMap.set( + /** @type {Module} */ (moduleGraph.getModule(this)), + importVar + ); + return importVar; + } + + /** + * @param {boolean} update create new variables or update existing one + * @param {DependencyTemplateContext} templateContext the template context + * @returns {[string, string]} the import statement and the compat statement + */ + getImportStatement( + update, + { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements } + ) { + return runtimeTemplate.importStatement({ + update, + module: /** @type {Module} */ (moduleGraph.getModule(this)), + chunkGraph, + importVar: this.getImportVar(moduleGraph), + request: this.request, + originModule: module, + runtimeRequirements + }); + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @param {string[]} ids imported ids + * @param {string} additionalMessage extra info included in the error message + * @returns {WebpackError[] | undefined} errors + */ + getLinkingErrors(moduleGraph, ids, additionalMessage) { + const importedModule = moduleGraph.getModule(this); + // ignore errors for missing or failed modules + if (!importedModule || importedModule.getNumberOfErrors() > 0) { + return; + } + + const parentModule = + /** @type {Module} */ + (moduleGraph.getParentModule(this)); + const exportsType = importedModule.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ (parentModule.buildMeta).strictHarmonyModule + ); + if (exportsType === "namespace" || exportsType === "default-with-named") { + if (ids.length === 0) { + return; + } + + if ( + (exportsType !== "default-with-named" || ids[0] !== "default") && + moduleGraph.isExportProvided(importedModule, ids) === false + ) { + // We are sure that it's not provided + + // Try to provide detailed info in the error message + let pos = 0; + let exportsInfo = moduleGraph.getExportsInfo(importedModule); + while (pos < ids.length && exportsInfo) { + const id = ids[pos++]; + const exportInfo = exportsInfo.getReadOnlyExportInfo(id); + if (exportInfo.provided === false) { + // We are sure that it's not provided + const providedExports = exportsInfo.getProvidedExports(); + const moreInfo = !Array.isArray(providedExports) + ? " (possible exports unknown)" + : providedExports.length === 0 + ? " (module has no exports)" + : ` (possible exports: ${providedExports.join(", ")})`; + return [ + new HarmonyLinkingError( + `export ${ids + .slice(0, pos) + .map(id => `'${id}'`) + .join(".")} ${additionalMessage} was not found in '${ + this.userRequest + }'${moreInfo}` + ) + ]; + } + exportsInfo = + /** @type {ExportsInfo} */ + (exportInfo.getNestedExportsInfo()); + } + + // General error message + return [ + new HarmonyLinkingError( + `export ${ids + .map(id => `'${id}'`) + .join(".")} ${additionalMessage} was not found in '${ + this.userRequest + }'` + ) + ]; + } + } + switch (exportsType) { + case "default-only": + // It's has only a default export + if (ids.length > 0 && ids[0] !== "default") { + // In strict harmony modules we only support the default export + return [ + new HarmonyLinkingError( + `Can't import the named export ${ids + .map(id => `'${id}'`) + .join( + "." + )} ${additionalMessage} from default-exporting module (only default export is available)` + ) + ]; + } + break; + case "default-with-named": + // It has a default export and named properties redirect + // In some cases we still want to warn here + if ( + ids.length > 0 && + ids[0] !== "default" && + /** @type {BuildMeta} */ + (importedModule.buildMeta).defaultObject === "redirect-warn" + ) { + // For these modules only the default export is supported + return [ + new HarmonyLinkingError( + `Should not import the named export ${ids + .map(id => `'${id}'`) + .join( + "." + )} ${additionalMessage} from default-exporting module (only default export is available soon)` + ) + ]; + } + break; + } + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.sourceOrder); + write(this.assertions); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.sourceOrder = read(); + this.assertions = read(); + super.deserialize(context); + } +} + +module.exports = HarmonyImportDependency; + +/** @type {WeakMap<Module, WeakMap<Module, RuntimeSpec | boolean>>} */ +const importEmittedMap = new WeakMap(); + +HarmonyImportDependency.Template = class HarmonyImportDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {HarmonyImportDependency} */ (dependency); + const { module, chunkGraph, moduleGraph, runtime } = templateContext; + + const connection = moduleGraph.getConnection(dep); + if (connection && !connection.isTargetActive(runtime)) return; + + const referencedModule = connection && connection.module; + + if ( + connection && + connection.weak && + referencedModule && + chunkGraph.getModuleId(referencedModule) === null + ) { + // in weak references, module might not be in any chunk + // but that's ok, we don't need that logic in this case + return; + } + + const moduleKey = referencedModule + ? referencedModule.identifier() + : dep.request; + const key = `harmony import ${moduleKey}`; + + const runtimeCondition = dep.weak + ? false + : connection + ? filterRuntime(runtime, r => connection.isTargetActive(r)) + : true; + + if (module && referencedModule) { + let emittedModules = importEmittedMap.get(module); + if (emittedModules === undefined) { + emittedModules = new WeakMap(); + importEmittedMap.set(module, emittedModules); + } + let mergedRuntimeCondition = runtimeCondition; + const oldRuntimeCondition = emittedModules.get(referencedModule) || false; + if (oldRuntimeCondition !== false && mergedRuntimeCondition !== true) { + if (mergedRuntimeCondition === false || oldRuntimeCondition === true) { + mergedRuntimeCondition = oldRuntimeCondition; + } else { + mergedRuntimeCondition = mergeRuntime( + oldRuntimeCondition, + mergedRuntimeCondition + ); + } + } + emittedModules.set(referencedModule, mergedRuntimeCondition); + } + + const importStatement = dep.getImportStatement(false, templateContext); + if ( + referencedModule && + templateContext.moduleGraph.isAsync(referencedModule) + ) { + templateContext.initFragments.push( + new ConditionalInitFragment( + importStatement[0], + InitFragment.STAGE_HARMONY_IMPORTS, + dep.sourceOrder, + key, + runtimeCondition + ) + ); + templateContext.initFragments.push( + new AwaitDependenciesInitFragment( + new Set([dep.getImportVar(templateContext.moduleGraph)]) + ) + ); + templateContext.initFragments.push( + new ConditionalInitFragment( + importStatement[1], + InitFragment.STAGE_ASYNC_HARMONY_IMPORTS, + dep.sourceOrder, + `${key} compat`, + runtimeCondition + ) + ); + } else { + templateContext.initFragments.push( + new ConditionalInitFragment( + importStatement[0] + importStatement[1], + InitFragment.STAGE_HARMONY_IMPORTS, + dep.sourceOrder, + key, + runtimeCondition + ) + ); + } + } + + /** + * @param {Module} module the module + * @param {Module} referencedModule the referenced module + * @returns {RuntimeSpec | boolean} runtimeCondition in which this import has been emitted + */ + static getImportEmittedRuntime(module, referencedModule) { + const emittedModules = importEmittedMap.get(module); + if (emittedModules === undefined) return false; + return emittedModules.get(referencedModule) || false; + } +}; + +module.exports.ExportPresenceModes = ExportPresenceModes; diff --git a/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js b/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js new file mode 100644 index 00000000..c5af0754 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyImportDependencyParserPlugin.js @@ -0,0 +1,437 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const HotModuleReplacementPlugin = require("../HotModuleReplacementPlugin"); +const InnerGraph = require("../optimize/InnerGraph"); +const ConstDependency = require("./ConstDependency"); +const HarmonyAcceptDependency = require("./HarmonyAcceptDependency"); +const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency"); +const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency"); +const HarmonyExports = require("./HarmonyExports"); +const { ExportPresenceModes } = require("./HarmonyImportDependency"); +const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency"); +const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency"); + +/** @typedef {import("estree").ExportAllDeclaration} ExportAllDeclaration */ +/** @typedef {import("estree").ExportNamedDeclaration} ExportNamedDeclaration */ +/** @typedef {import("estree").Identifier} Identifier */ +/** @typedef {import("estree").ImportDeclaration} ImportDeclaration */ +/** @typedef {import("estree").ImportExpression} ImportExpression */ +/** @typedef {import("estree").Literal} Literal */ +/** @typedef {import("estree").MemberExpression} MemberExpression */ +/** @typedef {import("estree").ObjectExpression} ObjectExpression */ +/** @typedef {import("estree").Property} Property */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../optimize/InnerGraph").InnerGraph} InnerGraph */ +/** @typedef {import("../optimize/InnerGraph").TopLevelSymbol} TopLevelSymbol */ +/** @typedef {import("./HarmonyImportDependency")} HarmonyImportDependency */ + +const harmonySpecifierTag = Symbol("harmony import"); + +/** + * @typedef {object} HarmonySettings + * @property {string[]} ids + * @property {string} source + * @property {number} sourceOrder + * @property {string} name + * @property {boolean} await + * @property {Record<string, any> | undefined} assertions + */ + +/** + * @param {ImportDeclaration | ExportNamedDeclaration | ExportAllDeclaration | (ImportExpression & { arguments?: ObjectExpression[] })} node node with assertions + * @returns {ImportAttributes | undefined} import attributes + */ +function getAttributes(node) { + if ( + node.type === "ImportExpression" && + node.arguments && + node.arguments[0] && + node.arguments[0].type === "ObjectExpression" && + node.arguments[0].properties[0] && + node.arguments[0].properties[0].type === "Property" && + node.arguments[0].properties[0].value.type === "ObjectExpression" && + node.arguments[0].properties[0].value.properties + ) { + const properties = + /** @type {Property[]} */ + (node.arguments[0].properties[0].value.properties); + const result = /** @type {ImportAttributes} */ ({}); + for (const property of properties) { + const key = + /** @type {string} */ + ( + property.key.type === "Identifier" + ? property.key.name + : /** @type {Literal} */ (property.key).value + ); + result[key] = + /** @type {string} */ + (/** @type {Literal} */ (property.value).value); + } + const key = + node.arguments[0].properties[0].key.type === "Identifier" + ? node.arguments[0].properties[0].key.name + : /** @type {Literal} */ (node.arguments[0].properties[0].key).value; + if (key === "assert") { + result._isLegacyAssert = true; + } + return result; + } + // TODO remove cast when @types/estree has been updated to import assertions + const isImportAssertion = + /** @type {{ assertions?: ImportAttributeNode[] }} */ (node).assertions !== + undefined; + const attributes = isImportAssertion + ? /** @type {{ assertions?: ImportAttributeNode[] }} */ (node).assertions + : /** @type {{ attributes?: ImportAttributeNode[] }} */ (node).attributes; + if (attributes === undefined) { + return; + } + const result = /** @type {ImportAttributes} */ ({}); + for (const attribute of attributes) { + const key = + /** @type {string} */ + ( + attribute.key.type === "Identifier" + ? attribute.key.name + : attribute.key.value + ); + result[key] = /** @type {string} */ (attribute.value.value); + } + if (isImportAssertion) { + result._isLegacyAssert = true; + } + return result; +} + +module.exports = class HarmonyImportDependencyParserPlugin { + /** + * @param {JavascriptParserOptions} options options + */ + constructor(options) { + this.exportPresenceMode = + options.importExportsPresence !== undefined + ? ExportPresenceModes.fromUserOption(options.importExportsPresence) + : options.exportsPresence !== undefined + ? ExportPresenceModes.fromUserOption(options.exportsPresence) + : options.strictExportPresence + ? ExportPresenceModes.ERROR + : ExportPresenceModes.AUTO; + this.strictThisContextOnImports = options.strictThisContextOnImports; + } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + const { exportPresenceMode } = this; + + /** + * @param {string[]} members members + * @param {boolean[]} membersOptionals members Optionals + * @returns {string[]} a non optional part + */ + function getNonOptionalPart(members, membersOptionals) { + let i = 0; + while (i < members.length && membersOptionals[i] === false) i++; + return i !== members.length ? members.slice(0, i) : members; + } + + /** + * @param {TODO} node member expression + * @param {number} count count + * @returns {TODO} member expression + */ + function getNonOptionalMemberChain(node, count) { + while (count--) node = node.object; + return node; + } + + parser.hooks.isPure + .for("Identifier") + .tap("HarmonyImportDependencyParserPlugin", expression => { + const expr = /** @type {Identifier} */ (expression); + if ( + parser.isVariableDefined(expr.name) || + parser.getTagData(expr.name, harmonySpecifierTag) + ) { + return true; + } + }); + parser.hooks.import.tap( + "HarmonyImportDependencyParserPlugin", + (statement, source) => { + parser.state.lastHarmonyImportOrder = + (parser.state.lastHarmonyImportOrder || 0) + 1; + const clearDep = new ConstDependency( + parser.isAsiPosition(/** @type {Range} */ (statement.range)[0]) + ? ";" + : "", + /** @type {Range} */ (statement.range) + ); + clearDep.loc = /** @type {DependencyLocation} */ (statement.loc); + parser.state.module.addPresentationalDependency(clearDep); + parser.unsetAsiPosition(/** @type {Range} */ (statement.range)[1]); + const attributes = getAttributes(statement); + const sideEffectDep = new HarmonyImportSideEffectDependency( + /** @type {string} */ (source), + parser.state.lastHarmonyImportOrder, + attributes + ); + sideEffectDep.loc = /** @type {DependencyLocation} */ (statement.loc); + parser.state.module.addDependency(sideEffectDep); + return true; + } + ); + parser.hooks.importSpecifier.tap( + "HarmonyImportDependencyParserPlugin", + (statement, source, id, name) => { + const ids = id === null ? [] : [id]; + parser.tagVariable(name, harmonySpecifierTag, { + name, + source, + ids, + sourceOrder: parser.state.lastHarmonyImportOrder, + assertions: getAttributes(statement) + }); + return true; + } + ); + parser.hooks.binaryExpression.tap( + "HarmonyImportDependencyParserPlugin", + expression => { + if (expression.operator !== "in") return; + + const leftPartEvaluated = parser.evaluateExpression(expression.left); + if (leftPartEvaluated.couldHaveSideEffects()) return; + const leftPart = leftPartEvaluated.asString(); + if (!leftPart) return; + + const rightPart = parser.evaluateExpression(expression.right); + if (!rightPart.isIdentifier()) return; + + const rootInfo = rightPart.rootInfo; + if ( + typeof rootInfo === "string" || + !rootInfo || + !rootInfo.tagInfo || + rootInfo.tagInfo.tag !== harmonySpecifierTag + ) + return; + const settings = rootInfo.tagInfo.data; + const members = + /** @type {(() => string[])} */ + (rightPart.getMembers)(); + const dep = new HarmonyEvaluatedImportSpecifierDependency( + settings.source, + settings.sourceOrder, + settings.ids.concat(members).concat([leftPart]), + settings.name, + /** @type {Range} */ (expression.range), + settings.assertions, + "in" + ); + dep.directImport = members.length === 0; + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expression.range)[0] + ); + dep.loc = /** @type {DependencyLocation} */ (expression.loc); + parser.state.module.addDependency(dep); + InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); + return true; + } + ); + parser.hooks.expression + .for(harmonySpecifierTag) + .tap("HarmonyImportDependencyParserPlugin", expr => { + const settings = /** @type {HarmonySettings} */ (parser.currentTagData); + const dep = new HarmonyImportSpecifierDependency( + settings.source, + settings.sourceOrder, + settings.ids, + settings.name, + /** @type {Range} */ (expr.range), + exportPresenceMode, + settings.assertions, + [] + ); + dep.referencedPropertiesInDestructuring = + parser.destructuringAssignmentPropertiesFor(expr); + dep.shorthand = parser.scope.inShorthand; + dep.directImport = true; + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.call = parser.scope.inTaggedTemplateTag; + parser.state.module.addDependency(dep); + InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); + return true; + }); + parser.hooks.expressionMemberChain + .for(harmonySpecifierTag) + .tap( + "HarmonyImportDependencyParserPlugin", + (expression, members, membersOptionals, memberRanges) => { + const settings = /** @type {HarmonySettings} */ ( + parser.currentTagData + ); + const nonOptionalMembers = getNonOptionalPart( + members, + membersOptionals + ); + /** @type {Range[]} */ + const ranges = memberRanges.slice( + 0, + memberRanges.length - (members.length - nonOptionalMembers.length) + ); + const expr = + nonOptionalMembers !== members + ? getNonOptionalMemberChain( + expression, + members.length - nonOptionalMembers.length + ) + : expression; + const ids = settings.ids.concat(nonOptionalMembers); + const dep = new HarmonyImportSpecifierDependency( + settings.source, + settings.sourceOrder, + ids, + settings.name, + /** @type {Range} */ (expr.range), + exportPresenceMode, + settings.assertions, + ranges + ); + dep.referencedPropertiesInDestructuring = + parser.destructuringAssignmentPropertiesFor(expr); + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); + return true; + } + ); + parser.hooks.callMemberChain + .for(harmonySpecifierTag) + .tap( + "HarmonyImportDependencyParserPlugin", + (expression, members, membersOptionals, memberRanges) => { + const { arguments: args, callee } = expression; + const settings = /** @type {HarmonySettings} */ ( + parser.currentTagData + ); + const nonOptionalMembers = getNonOptionalPart( + members, + membersOptionals + ); + /** @type {Range[]} */ + const ranges = memberRanges.slice( + 0, + memberRanges.length - (members.length - nonOptionalMembers.length) + ); + const expr = + nonOptionalMembers !== members + ? getNonOptionalMemberChain( + callee, + members.length - nonOptionalMembers.length + ) + : callee; + const ids = settings.ids.concat(nonOptionalMembers); + const dep = new HarmonyImportSpecifierDependency( + settings.source, + settings.sourceOrder, + ids, + settings.name, + /** @type {Range} */ (expr.range), + exportPresenceMode, + settings.assertions, + ranges + ); + dep.directImport = members.length === 0; + dep.call = true; + dep.asiSafe = !parser.isAsiPosition( + /** @type {Range} */ (expr.range)[0] + ); + // only in case when we strictly follow the spec we need a special case here + dep.namespaceObjectAsContext = + members.length > 0 && + /** @type {boolean} */ (this.strictThisContextOnImports); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + if (args) parser.walkExpressions(args); + InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); + return true; + } + ); + const { hotAcceptCallback, hotAcceptWithoutCallback } = + HotModuleReplacementPlugin.getParserHooks(parser); + hotAcceptCallback.tap( + "HarmonyImportDependencyParserPlugin", + (expr, requests) => { + if (!HarmonyExports.isEnabled(parser.state)) { + // This is not a harmony module, skip it + return; + } + const dependencies = requests.map(request => { + const dep = new HarmonyAcceptImportDependency(request); + dep.loc = expr.loc; + parser.state.module.addDependency(dep); + return dep; + }); + if (dependencies.length > 0) { + const dep = new HarmonyAcceptDependency( + expr.range, + dependencies, + true + ); + dep.loc = expr.loc; + parser.state.module.addDependency(dep); + } + } + ); + hotAcceptWithoutCallback.tap( + "HarmonyImportDependencyParserPlugin", + (expr, requests) => { + if (!HarmonyExports.isEnabled(parser.state)) { + // This is not a harmony module, skip it + return; + } + const dependencies = requests.map(request => { + const dep = new HarmonyAcceptImportDependency(request); + dep.loc = expr.loc; + parser.state.module.addDependency(dep); + return dep; + }); + if (dependencies.length > 0) { + const dep = new HarmonyAcceptDependency( + expr.range, + dependencies, + false + ); + dep.loc = expr.loc; + parser.state.module.addDependency(dep); + } + } + ); + } +}; + +module.exports.harmonySpecifierTag = harmonySpecifierTag; +// TODO remove it in webpack@6 in favor getAttributes +module.exports.getAssertions = getAttributes; +module.exports.getAttributes = getAttributes; diff --git a/node_modules/webpack/lib/dependencies/HarmonyImportSideEffectDependency.js b/node_modules/webpack/lib/dependencies/HarmonyImportSideEffectDependency.js new file mode 100644 index 00000000..bf691745 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyImportSideEffectDependency.js @@ -0,0 +1,86 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const HarmonyImportDependency = require("./HarmonyImportDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class HarmonyImportSideEffectDependency extends HarmonyImportDependency { + /** + * @param {string} request the request string + * @param {number} sourceOrder source order + * @param {ImportAttributes=} attributes import attributes + */ + constructor(request, sourceOrder, attributes) { + super(request, sourceOrder, attributes); + } + + get type() { + return "harmony side effect evaluation"; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {null | false | GetConditionFn} function to determine if the connection is active + */ + getCondition(moduleGraph) { + return connection => { + const refModule = connection.resolvedModule; + if (!refModule) return true; + return refModule.getSideEffectsConnectionState(moduleGraph); + }; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {ConnectionState} how this dependency connects the module to referencing modules + */ + getModuleEvaluationSideEffectsState(moduleGraph) { + const refModule = moduleGraph.getModule(this); + if (!refModule) return true; + return refModule.getSideEffectsConnectionState(moduleGraph); + } +} + +makeSerializable( + HarmonyImportSideEffectDependency, + "webpack/lib/dependencies/HarmonyImportSideEffectDependency" +); + +HarmonyImportSideEffectDependency.Template = class HarmonyImportSideEffectDependencyTemplate extends ( + HarmonyImportDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const { moduleGraph, concatenationScope } = templateContext; + if (concatenationScope) { + const module = /** @type {Module} */ (moduleGraph.getModule(dependency)); + if (concatenationScope.isModuleInScope(module)) { + return; + } + } + super.apply(dependency, source, templateContext); + } +}; + +module.exports = HarmonyImportSideEffectDependency; diff --git a/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js b/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js new file mode 100644 index 00000000..277624e7 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyImportSpecifierDependency.js @@ -0,0 +1,465 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const Template = require("../Template"); +const { + getDependencyUsedByExportsCondition +} = require("../optimize/InnerGraph"); +const { getTrimmedIdsAndRange } = require("../util/chainedImports"); +const makeSerializable = require("../util/makeSerializable"); +const propertyAccess = require("../util/propertyAccess"); +const HarmonyImportDependency = require("./HarmonyImportDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../javascript/JavascriptParser").DestructuringAssignmentProperty} DestructuringAssignmentProperty */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +const idsSymbol = Symbol("HarmonyImportSpecifierDependency.ids"); + +const { ExportPresenceModes } = HarmonyImportDependency; + +class HarmonyImportSpecifierDependency extends HarmonyImportDependency { + /** + * @param {string} request request + * @param {number} sourceOrder source order + * @param {string[]} ids ids + * @param {string} name name + * @param {Range} range range + * @param {TODO} exportPresenceMode export presence mode + * @param {ImportAttributes | undefined} attributes import attributes + * @param {Range[] | undefined} idRanges ranges for members of ids; the two arrays are right-aligned + */ + constructor( + request, + sourceOrder, + ids, + name, + range, + exportPresenceMode, + attributes, + idRanges // TODO webpack 6 make this non-optional. It must always be set to properly trim ids. + ) { + super(request, sourceOrder, attributes); + this.ids = ids; + this.name = name; + this.range = range; + this.idRanges = idRanges; + this.exportPresenceMode = exportPresenceMode; + this.namespaceObjectAsContext = false; + this.call = undefined; + this.directImport = undefined; + this.shorthand = undefined; + this.asiSafe = undefined; + /** @type {Set<string> | boolean | undefined} */ + this.usedByExports = undefined; + /** @type {Set<DestructuringAssignmentProperty> | undefined} */ + this.referencedPropertiesInDestructuring = undefined; + } + + // TODO webpack 6 remove + get id() { + throw new Error("id was renamed to ids and type changed to string[]"); + } + + // TODO webpack 6 remove + getId() { + throw new Error("id was renamed to ids and type changed to string[]"); + } + + // TODO webpack 6 remove + setId() { + throw new Error("id was renamed to ids and type changed to string[]"); + } + + get type() { + return "harmony import specifier"; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {string[]} the imported ids + */ + getIds(moduleGraph) { + const meta = moduleGraph.getMetaIfExisting(this); + if (meta === undefined) return this.ids; + const ids = meta[/** @type {keyof object} */ (idsSymbol)]; + return ids !== undefined ? ids : this.ids; + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @param {string[]} ids the imported ids + * @returns {void} + */ + setIds(moduleGraph, ids) { + moduleGraph.getMeta(this)[idsSymbol] = ids; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {null | false | GetConditionFn} function to determine if the connection is active + */ + getCondition(moduleGraph) { + return getDependencyUsedByExportsCondition( + this, + this.usedByExports, + moduleGraph + ); + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {ConnectionState} how this dependency connects the module to referencing modules + */ + getModuleEvaluationSideEffectsState(moduleGraph) { + return false; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + let ids = this.getIds(moduleGraph); + if (ids.length === 0) return this._getReferencedExportsInDestructuring(); + let namespaceObjectAsContext = this.namespaceObjectAsContext; + if (ids[0] === "default") { + const selfModule = + /** @type {Module} */ + (moduleGraph.getParentModule(this)); + const importedModule = + /** @type {Module} */ + (moduleGraph.getModule(this)); + switch ( + importedModule.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ + (selfModule.buildMeta).strictHarmonyModule + ) + ) { + case "default-only": + case "default-with-named": + if (ids.length === 1) + return this._getReferencedExportsInDestructuring(); + ids = ids.slice(1); + namespaceObjectAsContext = true; + break; + case "dynamic": + return Dependency.EXPORTS_OBJECT_REFERENCED; + } + } + + if ( + this.call && + !this.directImport && + (namespaceObjectAsContext || ids.length > 1) + ) { + if (ids.length === 1) return Dependency.EXPORTS_OBJECT_REFERENCED; + ids = ids.slice(0, -1); + } + + return this._getReferencedExportsInDestructuring(ids); + } + + /** + * @param {string[]=} ids ids + * @returns {string[][]} referenced exports + */ + _getReferencedExportsInDestructuring(ids) { + if (this.referencedPropertiesInDestructuring) { + /** @type {string[][]} */ + const refs = []; + for (const { id } of this.referencedPropertiesInDestructuring) { + refs.push(ids ? ids.concat([id]) : [id]); + } + return refs; + } + return ids ? [ids] : Dependency.EXPORTS_OBJECT_REFERENCED; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {number} effective mode + */ + _getEffectiveExportPresenceLevel(moduleGraph) { + if (this.exportPresenceMode !== ExportPresenceModes.AUTO) + return this.exportPresenceMode; + const buildMeta = + /** @type {BuildMeta} */ + ( + /** @type {Module} */ + (moduleGraph.getParentModule(this)).buildMeta + ); + return buildMeta.strictHarmonyModule + ? ExportPresenceModes.ERROR + : ExportPresenceModes.WARN; + } + + /** + * Returns warnings + * @param {ModuleGraph} moduleGraph module graph + * @returns {WebpackError[] | null | undefined} warnings + */ + getWarnings(moduleGraph) { + const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph); + if (exportsPresence === ExportPresenceModes.WARN) { + return this._getErrors(moduleGraph); + } + return null; + } + + /** + * Returns errors + * @param {ModuleGraph} moduleGraph module graph + * @returns {WebpackError[] | null | undefined} errors + */ + getErrors(moduleGraph) { + const exportsPresence = this._getEffectiveExportPresenceLevel(moduleGraph); + if (exportsPresence === ExportPresenceModes.ERROR) { + return this._getErrors(moduleGraph); + } + return null; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {WebpackError[] | undefined} errors + */ + _getErrors(moduleGraph) { + const ids = this.getIds(moduleGraph); + return this.getLinkingErrors( + moduleGraph, + ids, + `(imported as '${this.name}')` + ); + } + + /** + * implement this method to allow the occurrence order plugin to count correctly + * @returns {number} count how often the id is used in this dependency + */ + getNumberOfIdOccurrences() { + return 0; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.ids); + write(this.name); + write(this.range); + write(this.idRanges); + write(this.exportPresenceMode); + write(this.namespaceObjectAsContext); + write(this.call); + write(this.directImport); + write(this.shorthand); + write(this.asiSafe); + write(this.usedByExports); + write(this.referencedPropertiesInDestructuring); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.ids = read(); + this.name = read(); + this.range = read(); + this.idRanges = read(); + this.exportPresenceMode = read(); + this.namespaceObjectAsContext = read(); + this.call = read(); + this.directImport = read(); + this.shorthand = read(); + this.asiSafe = read(); + this.usedByExports = read(); + this.referencedPropertiesInDestructuring = read(); + super.deserialize(context); + } +} + +makeSerializable( + HarmonyImportSpecifierDependency, + "webpack/lib/dependencies/HarmonyImportSpecifierDependency" +); + +HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependencyTemplate extends ( + HarmonyImportDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {HarmonyImportSpecifierDependency} */ (dependency); + const { moduleGraph, runtime } = templateContext; + const connection = moduleGraph.getConnection(dep); + // Skip rendering depending when dependency is conditional + if (connection && !connection.isTargetActive(runtime)) return; + + const ids = dep.getIds(moduleGraph); + const { + trimmedRange: [trimmedRangeStart, trimmedRangeEnd], + trimmedIds + } = getTrimmedIdsAndRange(ids, dep.range, dep.idRanges, moduleGraph, dep); + + const exportExpr = this._getCodeForIds( + dep, + source, + templateContext, + trimmedIds + ); + if (dep.shorthand) { + source.insert(trimmedRangeEnd, `: ${exportExpr}`); + } else { + source.replace(trimmedRangeStart, trimmedRangeEnd - 1, exportExpr); + } + + if (dep.referencedPropertiesInDestructuring) { + let prefixedIds = ids; + + if (ids[0] === "default") { + const selfModule = moduleGraph.getParentModule(dep); + const importedModule = + /** @type {Module} */ + (moduleGraph.getModule(dep)); + const exportsType = importedModule.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ + (selfModule.buildMeta).strictHarmonyModule + ); + if ( + (exportsType === "default-only" || + exportsType === "default-with-named") && + ids.length >= 1 + ) { + prefixedIds = ids.slice(1); + } + } + + for (const { + id, + shorthand, + range + } of dep.referencedPropertiesInDestructuring) { + const concatedIds = prefixedIds.concat([id]); + const module = /** @type {Module} */ (moduleGraph.getModule(dep)); + const used = moduleGraph + .getExportsInfo(module) + .getUsedName(concatedIds, runtime); + if (!used) return; + const newName = used[used.length - 1]; + const name = concatedIds[concatedIds.length - 1]; + if (newName === name) continue; + + const comment = `${Template.toNormalComment(name)} `; + const key = comment + JSON.stringify(newName); + source.replace( + /** @type {Range} */ + (range)[0], + /** @type {Range} */ + (range)[1] - 1, + shorthand ? `${key}: ${name}` : `${key}` + ); + } + } + } + + /** + * @param {HarmonyImportSpecifierDependency} dep dependency + * @param {ReplaceSource} source source + * @param {DependencyTemplateContext} templateContext context + * @param {string[]} ids ids + * @returns {string} generated code + */ + _getCodeForIds(dep, source, templateContext, ids) { + const { moduleGraph, module, runtime, concatenationScope } = + templateContext; + const connection = moduleGraph.getConnection(dep); + let exportExpr; + if ( + connection && + concatenationScope && + concatenationScope.isModuleInScope(connection.module) + ) { + if (ids.length === 0) { + exportExpr = concatenationScope.createModuleReference( + connection.module, + { + asiSafe: dep.asiSafe + } + ); + } else if (dep.namespaceObjectAsContext && ids.length === 1) { + exportExpr = + concatenationScope.createModuleReference(connection.module, { + asiSafe: dep.asiSafe + }) + propertyAccess(ids); + } else { + exportExpr = concatenationScope.createModuleReference( + connection.module, + { + ids, + call: dep.call, + directImport: dep.directImport, + asiSafe: dep.asiSafe + } + ); + } + } else { + super.apply(dep, source, templateContext); + + const { runtimeTemplate, initFragments, runtimeRequirements } = + templateContext; + + exportExpr = runtimeTemplate.exportFromImport({ + moduleGraph, + module: /** @type {Module} */ (moduleGraph.getModule(dep)), + request: dep.request, + exportName: ids, + originModule: module, + asiSafe: dep.shorthand ? true : dep.asiSafe, + isCall: dep.call, + callContext: !dep.directImport, + defaultInterop: true, + importVar: dep.getImportVar(moduleGraph), + initFragments, + runtime, + runtimeRequirements + }); + } + return exportExpr; + } +}; + +module.exports = HarmonyImportSpecifierDependency; diff --git a/node_modules/webpack/lib/dependencies/HarmonyModulesPlugin.js b/node_modules/webpack/lib/dependencies/HarmonyModulesPlugin.js new file mode 100644 index 00000000..a3bbd98d --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyModulesPlugin.js @@ -0,0 +1,149 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const HarmonyAcceptDependency = require("./HarmonyAcceptDependency"); +const HarmonyAcceptImportDependency = require("./HarmonyAcceptImportDependency"); +const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency"); +const HarmonyEvaluatedImportSpecifierDependency = require("./HarmonyEvaluatedImportSpecifierDependency"); +const HarmonyExportExpressionDependency = require("./HarmonyExportExpressionDependency"); +const HarmonyExportHeaderDependency = require("./HarmonyExportHeaderDependency"); +const HarmonyExportImportedSpecifierDependency = require("./HarmonyExportImportedSpecifierDependency"); +const HarmonyExportSpecifierDependency = require("./HarmonyExportSpecifierDependency"); +const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency"); +const HarmonyImportSpecifierDependency = require("./HarmonyImportSpecifierDependency"); + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); +const HarmonyDetectionParserPlugin = require("./HarmonyDetectionParserPlugin"); +const HarmonyExportDependencyParserPlugin = require("./HarmonyExportDependencyParserPlugin"); +const HarmonyImportDependencyParserPlugin = require("./HarmonyImportDependencyParserPlugin"); +const HarmonyTopLevelThisParserPlugin = require("./HarmonyTopLevelThisParserPlugin"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "HarmonyModulesPlugin"; + +/** @typedef {{ topLevelAwait?: boolean }} HarmonyModulesPluginOptions */ + +class HarmonyModulesPlugin { + /** + * @param {HarmonyModulesPluginOptions} options options + */ + constructor(options) { + this.options = options; + } + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { normalModuleFactory }) => { + compilation.dependencyTemplates.set( + HarmonyCompatibilityDependency, + new HarmonyCompatibilityDependency.Template() + ); + + compilation.dependencyFactories.set( + HarmonyImportSideEffectDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + HarmonyImportSideEffectDependency, + new HarmonyImportSideEffectDependency.Template() + ); + + compilation.dependencyFactories.set( + HarmonyImportSpecifierDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + HarmonyImportSpecifierDependency, + new HarmonyImportSpecifierDependency.Template() + ); + + compilation.dependencyFactories.set( + HarmonyEvaluatedImportSpecifierDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + HarmonyEvaluatedImportSpecifierDependency, + new HarmonyEvaluatedImportSpecifierDependency.Template() + ); + + compilation.dependencyTemplates.set( + HarmonyExportHeaderDependency, + new HarmonyExportHeaderDependency.Template() + ); + + compilation.dependencyTemplates.set( + HarmonyExportExpressionDependency, + new HarmonyExportExpressionDependency.Template() + ); + + compilation.dependencyTemplates.set( + HarmonyExportSpecifierDependency, + new HarmonyExportSpecifierDependency.Template() + ); + + compilation.dependencyFactories.set( + HarmonyExportImportedSpecifierDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + HarmonyExportImportedSpecifierDependency, + new HarmonyExportImportedSpecifierDependency.Template() + ); + + compilation.dependencyTemplates.set( + HarmonyAcceptDependency, + new HarmonyAcceptDependency.Template() + ); + + compilation.dependencyFactories.set( + HarmonyAcceptImportDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + HarmonyAcceptImportDependency, + new HarmonyAcceptImportDependency.Template() + ); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + // TODO webpack 6: rename harmony to esm or module + if (parserOptions.harmony !== undefined && !parserOptions.harmony) + return; + + new HarmonyDetectionParserPlugin(this.options).apply(parser); + new HarmonyImportDependencyParserPlugin(parserOptions).apply(parser); + new HarmonyExportDependencyParserPlugin(parserOptions).apply(parser); + new HarmonyTopLevelThisParserPlugin().apply(parser); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); + } + ); + } +} +module.exports = HarmonyModulesPlugin; diff --git a/node_modules/webpack/lib/dependencies/HarmonyTopLevelThisParserPlugin.js b/node_modules/webpack/lib/dependencies/HarmonyTopLevelThisParserPlugin.js new file mode 100644 index 00000000..b8ba1848 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/HarmonyTopLevelThisParserPlugin.js @@ -0,0 +1,39 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Florent Cailhol @ooflorent +*/ + +"use strict"; + +const ConstDependency = require("./ConstDependency"); +const HarmonyExports = require("./HarmonyExports"); + +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class HarmonyTopLevelThisParserPlugin { + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + parser.hooks.expression + .for("this") + .tap("HarmonyTopLevelThisParserPlugin", node => { + if (!parser.scope.topLevelScope) return; + if (HarmonyExports.isEnabled(parser.state)) { + const dep = new ConstDependency( + "undefined", + /** @type {Range} */ (node.range), + null + ); + dep.loc = /** @type {DependencyLocation} */ (node.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + } + }); + } +} + +module.exports = HarmonyTopLevelThisParserPlugin; diff --git a/node_modules/webpack/lib/dependencies/ImportContextDependency.js b/node_modules/webpack/lib/dependencies/ImportContextDependency.js new file mode 100644 index 00000000..a1811e72 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportContextDependency.js @@ -0,0 +1,67 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ContextDependency = require("./ContextDependency"); +const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class ImportContextDependency extends ContextDependency { + /** + * @param {TODO} options options + * @param {Range} range range + * @param {Range} valueRange value range + */ + constructor(options, range, valueRange) { + super(options); + + this.range = range; + this.valueRange = valueRange; + } + + get type() { + return `import() context ${this.options.mode}`; + } + + get category() { + return "esm"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.valueRange); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.valueRange = read(); + + super.deserialize(context); + } +} + +makeSerializable( + ImportContextDependency, + "webpack/lib/dependencies/ImportContextDependency" +); + +ImportContextDependency.Template = ContextDependencyTemplateAsRequireCall; + +module.exports = ImportContextDependency; diff --git a/node_modules/webpack/lib/dependencies/ImportDependency.js b/node_modules/webpack/lib/dependencies/ImportDependency.js new file mode 100644 index 00000000..1368d405 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportDependency.js @@ -0,0 +1,139 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class ImportDependency extends ModuleDependency { + /** + * @param {string} request the request + * @param {Range} range expression range + * @param {(string[][] | null)=} referencedExports list of referenced exports + * @param {ImportAttributes=} attributes import attributes + */ + constructor(request, range, referencedExports, attributes) { + super(request); + this.range = range; + this.referencedExports = referencedExports; + this.assertions = attributes; + } + + get type() { + return "import()"; + } + + get category() { + return "esm"; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + if (!this.referencedExports) return Dependency.EXPORTS_OBJECT_REFERENCED; + const refs = []; + for (const referencedExport of this.referencedExports) { + if (referencedExport[0] === "default") { + const selfModule = + /** @type {Module} */ + (moduleGraph.getParentModule(this)); + const importedModule = + /** @type {Module} */ + (moduleGraph.getModule(this)); + const exportsType = importedModule.getExportsType( + moduleGraph, + /** @type {BuildMeta} */ + (selfModule.buildMeta).strictHarmonyModule + ); + if ( + exportsType === "default-only" || + exportsType === "default-with-named" + ) { + return Dependency.EXPORTS_OBJECT_REFERENCED; + } + } + refs.push({ + name: referencedExport, + canMangle: false + }); + } + return refs; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + context.write(this.range); + context.write(this.referencedExports); + context.write(this.assertions); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + this.range = context.read(); + this.referencedExports = context.read(); + this.assertions = context.read(); + super.deserialize(context); + } +} + +makeSerializable(ImportDependency, "webpack/lib/dependencies/ImportDependency"); + +ImportDependency.Template = class ImportDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements } + ) { + const dep = /** @type {ImportDependency} */ (dependency); + const block = /** @type {AsyncDependenciesBlock} */ ( + moduleGraph.getParentBlock(dep) + ); + const content = runtimeTemplate.moduleNamespacePromise({ + chunkGraph, + block, + module: /** @type {Module} */ (moduleGraph.getModule(dep)), + request: dep.request, + strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule, + message: "import()", + runtimeRequirements + }); + + source.replace(dep.range[0], dep.range[1] - 1, content); + } +}; + +module.exports = ImportDependency; diff --git a/node_modules/webpack/lib/dependencies/ImportEagerDependency.js b/node_modules/webpack/lib/dependencies/ImportEagerDependency.js new file mode 100644 index 00000000..dd607302 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportEagerDependency.js @@ -0,0 +1,74 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ImportDependency = require("./ImportDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class ImportEagerDependency extends ImportDependency { + /** + * @param {string} request the request + * @param {Range} range expression range + * @param {(string[][] | null)=} referencedExports list of referenced exports + * @param {ImportAttributes=} attributes import attributes + */ + constructor(request, range, referencedExports, attributes) { + super(request, range, referencedExports, attributes); + } + + get type() { + return "import() eager"; + } + + get category() { + return "esm"; + } +} + +makeSerializable( + ImportEagerDependency, + "webpack/lib/dependencies/ImportEagerDependency" +); + +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 + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements } + ) { + const dep = /** @type {ImportEagerDependency} */ (dependency); + const content = runtimeTemplate.moduleNamespacePromise({ + chunkGraph, + module: /** @type {Module} */ (moduleGraph.getModule(dep)), + request: dep.request, + strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule, + message: "import() eager", + runtimeRequirements + }); + + source.replace(dep.range[0], dep.range[1] - 1, content); + } +}; + +module.exports = ImportEagerDependency; diff --git a/node_modules/webpack/lib/dependencies/ImportMetaContextDependency.js b/node_modules/webpack/lib/dependencies/ImportMetaContextDependency.js new file mode 100644 index 00000000..ee27ee15 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportMetaContextDependency.js @@ -0,0 +1,42 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ContextDependency = require("./ContextDependency"); +const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */ + +class ImportMetaContextDependency extends ContextDependency { + /** + * @param {ContextDependencyOptions} options options + * @param {Range} range range + */ + constructor(options, range) { + super(options); + + this.range = range; + } + + get category() { + return "esm"; + } + + get type() { + return `import.meta.webpackContext ${this.options.mode}`; + } +} + +makeSerializable( + ImportMetaContextDependency, + "webpack/lib/dependencies/ImportMetaContextDependency" +); + +ImportMetaContextDependency.Template = ModuleDependencyTemplateAsRequireId; + +module.exports = ImportMetaContextDependency; diff --git a/node_modules/webpack/lib/dependencies/ImportMetaContextDependencyParserPlugin.js b/node_modules/webpack/lib/dependencies/ImportMetaContextDependencyParserPlugin.js new file mode 100644 index 00000000..753f0430 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportMetaContextDependencyParserPlugin.js @@ -0,0 +1,301 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const WebpackError = require("../WebpackError"); +const { + evaluateToIdentifier +} = require("../javascript/JavascriptParserHelpers"); +const ImportMetaContextDependency = require("./ImportMetaContextDependency"); + +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").ObjectExpression} ObjectExpression */ +/** @typedef {import("estree").Property} Property */ +/** @typedef {import("estree").SourceLocation} SourceLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../ContextModule").ContextModuleOptions} ContextModuleOptions */ +/** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {Pick<ContextModuleOptions, 'mode'|'recursive'|'regExp'|'include'|'exclude'|'chunkName'>&{groupOptions: RawChunkGroupOptions, exports?: ContextModuleOptions["referencedExports"]}} ImportMetaContextOptions */ + +/** + * @param {TODO} prop property + * @param {string} expect except message + * @returns {WebpackError} error + */ +function createPropertyParseError(prop, expect) { + return createError( + `Parsing import.meta.webpackContext options failed. Unknown value for property ${JSON.stringify( + prop.key.name + )}, expected type ${expect}.`, + prop.value.loc + ); +} + +/** + * @param {string} msg message + * @param {DependencyLocation} loc location + * @returns {WebpackError} error + */ +function createError(msg, loc) { + const error = new WebpackError(msg); + error.name = "ImportMetaContextError"; + error.loc = loc; + return error; +} + +module.exports = class ImportMetaContextDependencyParserPlugin { + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + parser.hooks.evaluateIdentifier + .for("import.meta.webpackContext") + .tap("ImportMetaContextDependencyParserPlugin", expr => + evaluateToIdentifier( + "import.meta.webpackContext", + "import.meta", + () => ["webpackContext"], + true + )(expr) + ); + parser.hooks.call + .for("import.meta.webpackContext") + .tap("ImportMetaContextDependencyParserPlugin", expr => { + if (expr.arguments.length < 1 || expr.arguments.length > 2) return; + const [directoryNode, optionsNode] = expr.arguments; + if (optionsNode && optionsNode.type !== "ObjectExpression") return; + const requestExpr = parser.evaluateExpression( + /** @type {Expression} */ (directoryNode) + ); + if (!requestExpr.isString()) return; + const request = /** @type {string} */ (requestExpr.string); + const errors = []; + let regExp = /^\.\/.*$/; + let recursive = true; + /** @type {ContextModuleOptions["mode"]} */ + let mode = "sync"; + /** @type {ContextModuleOptions["include"]} */ + let include; + /** @type {ContextModuleOptions["exclude"]} */ + let exclude; + /** @type {RawChunkGroupOptions} */ + const groupOptions = {}; + /** @type {ContextModuleOptions["chunkName"]} */ + let chunkName; + /** @type {ContextModuleOptions["referencedExports"]} */ + let exports; + if (optionsNode) { + for (const prop of /** @type {ObjectExpression} */ (optionsNode) + .properties) { + if (prop.type !== "Property" || prop.key.type !== "Identifier") { + errors.push( + createError( + "Parsing import.meta.webpackContext options failed.", + /** @type {DependencyLocation} */ (optionsNode.loc) + ) + ); + break; + } + switch (prop.key.name) { + case "regExp": { + const regExpExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!regExpExpr.isRegExp()) { + errors.push(createPropertyParseError(prop, "RegExp")); + } else { + regExp = /** @type {RegExp} */ (regExpExpr.regExp); + } + break; + } + case "include": { + const regExpExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!regExpExpr.isRegExp()) { + errors.push(createPropertyParseError(prop, "RegExp")); + } else { + include = regExpExpr.regExp; + } + break; + } + case "exclude": { + const regExpExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!regExpExpr.isRegExp()) { + errors.push(createPropertyParseError(prop, "RegExp")); + } else { + exclude = regExpExpr.regExp; + } + break; + } + case "mode": { + const modeExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!modeExpr.isString()) { + errors.push(createPropertyParseError(prop, "string")); + } else { + mode = /** @type {ContextModuleOptions["mode"]} */ ( + modeExpr.string + ); + } + break; + } + case "chunkName": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!expr.isString()) { + errors.push(createPropertyParseError(prop, "string")); + } else { + chunkName = expr.string; + } + break; + } + case "exports": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (expr.isString()) { + exports = [[/** @type {string} */ (expr.string)]]; + } else if (expr.isArray()) { + const items = + /** @type {BasicEvaluatedExpression[]} */ + (expr.items); + if ( + items.every(i => { + if (!i.isArray()) return false; + const innerItems = + /** @type {BasicEvaluatedExpression[]} */ (i.items); + return innerItems.every(i => i.isString()); + }) + ) { + exports = []; + for (const i1 of items) { + /** @type {string[]} */ + const export_ = []; + for (const i2 of /** @type {BasicEvaluatedExpression[]} */ ( + i1.items + )) { + export_.push(/** @type {string} */ (i2.string)); + } + exports.push(export_); + } + } else { + errors.push( + createPropertyParseError(prop, "string|string[][]") + ); + } + } else { + errors.push( + createPropertyParseError(prop, "string|string[][]") + ); + } + break; + } + case "prefetch": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (expr.isBoolean()) { + groupOptions.prefetchOrder = 0; + } else if (expr.isNumber()) { + groupOptions.prefetchOrder = expr.number; + } else { + errors.push(createPropertyParseError(prop, "boolean|number")); + } + break; + } + case "preload": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (expr.isBoolean()) { + groupOptions.preloadOrder = 0; + } else if (expr.isNumber()) { + groupOptions.preloadOrder = expr.number; + } else { + errors.push(createPropertyParseError(prop, "boolean|number")); + } + break; + } + case "fetchPriority": { + const expr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if ( + expr.isString() && + ["high", "low", "auto"].includes( + /** @type {string} */ (expr.string) + ) + ) { + groupOptions.fetchPriority = + /** @type {RawChunkGroupOptions["fetchPriority"]} */ ( + expr.string + ); + } else { + errors.push( + createPropertyParseError(prop, '"high"|"low"|"auto"') + ); + } + break; + } + case "recursive": { + const recursiveExpr = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (!recursiveExpr.isBoolean()) { + errors.push(createPropertyParseError(prop, "boolean")); + } else { + recursive = /** @type {boolean} */ (recursiveExpr.bool); + } + break; + } + default: + errors.push( + createError( + `Parsing import.meta.webpackContext options failed. Unknown property ${JSON.stringify( + prop.key.name + )}.`, + /** @type {DependencyLocation} */ (optionsNode.loc) + ) + ); + } + } + } + if (errors.length) { + for (const error of errors) parser.state.current.addError(error); + return; + } + + const dep = new ImportMetaContextDependency( + { + request, + include, + exclude, + recursive, + regExp, + groupOptions, + chunkName, + referencedExports: exports, + mode, + category: "esm" + }, + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + }); + } +}; diff --git a/node_modules/webpack/lib/dependencies/ImportMetaContextPlugin.js b/node_modules/webpack/lib/dependencies/ImportMetaContextPlugin.js new file mode 100644 index 00000000..ed9ac05d --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportMetaContextPlugin.js @@ -0,0 +1,72 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); +const ContextElementDependency = require("./ContextElementDependency"); +const ImportMetaContextDependency = require("./ImportMetaContextDependency"); +const ImportMetaContextDependencyParserPlugin = require("./ImportMetaContextDependencyParserPlugin"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "ImportMetaContextPlugin"; + +class ImportMetaContextPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { contextModuleFactory, normalModuleFactory }) => { + compilation.dependencyFactories.set( + ImportMetaContextDependency, + contextModuleFactory + ); + compilation.dependencyTemplates.set( + ImportMetaContextDependency, + new ImportMetaContextDependency.Template() + ); + compilation.dependencyFactories.set( + ContextElementDependency, + normalModuleFactory + ); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + if ( + parserOptions.importMetaContext !== undefined && + !parserOptions.importMetaContext + ) + return; + + new ImportMetaContextDependencyParserPlugin().apply(parser); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); + } + ); + } +} + +module.exports = ImportMetaContextPlugin; diff --git a/node_modules/webpack/lib/dependencies/ImportMetaHotAcceptDependency.js b/node_modules/webpack/lib/dependencies/ImportMetaHotAcceptDependency.js new file mode 100644 index 00000000..70d81993 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportMetaHotAcceptDependency.js @@ -0,0 +1,41 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); +const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class ImportMetaHotAcceptDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ + constructor(request, range) { + super(request); + this.range = range; + this.weak = true; + } + + get type() { + return "import.meta.webpackHot.accept"; + } + + get category() { + return "esm"; + } +} + +makeSerializable( + ImportMetaHotAcceptDependency, + "webpack/lib/dependencies/ImportMetaHotAcceptDependency" +); + +ImportMetaHotAcceptDependency.Template = ModuleDependencyTemplateAsId; + +module.exports = ImportMetaHotAcceptDependency; diff --git a/node_modules/webpack/lib/dependencies/ImportMetaHotDeclineDependency.js b/node_modules/webpack/lib/dependencies/ImportMetaHotDeclineDependency.js new file mode 100644 index 00000000..c6c35a25 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportMetaHotDeclineDependency.js @@ -0,0 +1,42 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); +const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class ImportMetaHotDeclineDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ + constructor(request, range) { + super(request); + + this.range = range; + this.weak = true; + } + + get type() { + return "import.meta.webpackHot.decline"; + } + + get category() { + return "esm"; + } +} + +makeSerializable( + ImportMetaHotDeclineDependency, + "webpack/lib/dependencies/ImportMetaHotDeclineDependency" +); + +ImportMetaHotDeclineDependency.Template = ModuleDependencyTemplateAsId; + +module.exports = ImportMetaHotDeclineDependency; diff --git a/node_modules/webpack/lib/dependencies/ImportMetaPlugin.js b/node_modules/webpack/lib/dependencies/ImportMetaPlugin.js new file mode 100644 index 00000000..ff9231d2 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportMetaPlugin.js @@ -0,0 +1,253 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const { pathToFileURL } = require("url"); +const ModuleDependencyWarning = require("../ModuleDependencyWarning"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); +const Template = require("../Template"); +const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression"); +const { + evaluateToIdentifier, + toConstantDependency, + evaluateToString, + evaluateToNumber +} = require("../javascript/JavascriptParserHelpers"); +const memoize = require("../util/memoize"); +const propertyAccess = require("../util/propertyAccess"); +const ConstDependency = require("./ConstDependency"); + +/** @typedef {import("estree").MemberExpression} MemberExpression */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../NormalModule")} NormalModule */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const getCriticalDependencyWarning = memoize(() => + require("./CriticalDependencyWarning") +); + +const PLUGIN_NAME = "ImportMetaPlugin"; + +class ImportMetaPlugin { + /** + * @param {Compiler} compiler compiler + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { normalModuleFactory }) => { + /** + * @param {NormalModule} module module + * @returns {string} file url + */ + const getUrl = module => pathToFileURL(module.resource).toString(); + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const parserHandler = (parser, { importMeta }) => { + if (importMeta === false) { + const { importMetaName } = compilation.outputOptions; + if (importMetaName === "import.meta") return; + + parser.hooks.expression + .for("import.meta") + .tap(PLUGIN_NAME, metaProperty => { + const dep = new ConstDependency( + /** @type {string} */ (importMetaName), + /** @type {Range} */ (metaProperty.range) + ); + dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + return; + } + + // import.meta direct + const webpackVersion = Number.parseInt( + require("../../package.json").version, + 10 + ); + const importMetaUrl = () => + JSON.stringify(getUrl(parser.state.module)); + const importMetaWebpackVersion = () => JSON.stringify(webpackVersion); + /** + * @param {string[]} members members + * @returns {string} error message + */ + const importMetaUnknownProperty = members => + `${Template.toNormalComment( + `unsupported import.meta.${members.join(".")}` + )} undefined${propertyAccess(members, 1)}`; + parser.hooks.typeof + .for("import.meta") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("object")) + ); + parser.hooks.expression + .for("import.meta") + .tap(PLUGIN_NAME, metaProperty => { + const referencedPropertiesInDestructuring = + parser.destructuringAssignmentPropertiesFor(metaProperty); + if (!referencedPropertiesInDestructuring) { + const CriticalDependencyWarning = + getCriticalDependencyWarning(); + parser.state.module.addWarning( + new ModuleDependencyWarning( + parser.state.module, + new CriticalDependencyWarning( + "Accessing import.meta directly is unsupported (only property access or destructuring is supported)" + ), + /** @type {DependencyLocation} */ (metaProperty.loc) + ) + ); + const dep = new ConstDependency( + `${ + parser.isAsiPosition( + /** @type {Range} */ (metaProperty.range)[0] + ) + ? ";" + : "" + }({})`, + /** @type {Range} */ (metaProperty.range) + ); + dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + } + + let str = ""; + for (const { id: prop } of referencedPropertiesInDestructuring) { + switch (prop) { + case "url": + str += `url: ${importMetaUrl()},`; + break; + case "webpack": + str += `webpack: ${importMetaWebpackVersion()},`; + break; + default: + str += `[${JSON.stringify( + prop + )}]: ${importMetaUnknownProperty([prop])},`; + break; + } + } + const dep = new ConstDependency( + `({${str}})`, + /** @type {Range} */ (metaProperty.range) + ); + dep.loc = /** @type {DependencyLocation} */ (metaProperty.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + parser.hooks.evaluateTypeof + .for("import.meta") + .tap(PLUGIN_NAME, evaluateToString("object")); + parser.hooks.evaluateIdentifier.for("import.meta").tap( + PLUGIN_NAME, + evaluateToIdentifier("import.meta", "import.meta", () => [], true) + ); + + // import.meta.url + parser.hooks.typeof + .for("import.meta.url") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("string")) + ); + parser.hooks.expression + .for("import.meta.url") + .tap(PLUGIN_NAME, expr => { + const dep = new ConstDependency( + importMetaUrl(), + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + parser.hooks.evaluateTypeof + .for("import.meta.url") + .tap(PLUGIN_NAME, evaluateToString("string")); + parser.hooks.evaluateIdentifier + .for("import.meta.url") + .tap(PLUGIN_NAME, expr => + new BasicEvaluatedExpression() + .setString(getUrl(parser.state.module)) + .setRange(/** @type {Range} */ (expr.range)) + ); + + // import.meta.webpack + parser.hooks.typeof + .for("import.meta.webpack") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("number")) + ); + parser.hooks.expression + .for("import.meta.webpack") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, importMetaWebpackVersion()) + ); + parser.hooks.evaluateTypeof + .for("import.meta.webpack") + .tap(PLUGIN_NAME, evaluateToString("number")); + parser.hooks.evaluateIdentifier + .for("import.meta.webpack") + .tap(PLUGIN_NAME, evaluateToNumber(webpackVersion)); + + // Unknown properties + parser.hooks.unhandledExpressionMemberChain + .for("import.meta") + .tap(PLUGIN_NAME, (expr, members) => { + const dep = new ConstDependency( + importMetaUnknownProperty(members), + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + parser.hooks.evaluate + .for("MemberExpression") + .tap(PLUGIN_NAME, expression => { + const expr = /** @type {MemberExpression} */ (expression); + if ( + expr.object.type === "MetaProperty" && + expr.object.meta.name === "import" && + expr.object.property.name === "meta" && + expr.property.type === + (expr.computed ? "Literal" : "Identifier") + ) { + return new BasicEvaluatedExpression() + .setUndefined() + .setRange(/** @type {Range} */ (expr.range)); + } + }); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, parserHandler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, parserHandler); + } + ); + } +} + +module.exports = ImportMetaPlugin; diff --git a/node_modules/webpack/lib/dependencies/ImportParserPlugin.js b/node_modules/webpack/lib/dependencies/ImportParserPlugin.js new file mode 100644 index 00000000..0f92b5d1 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportParserPlugin.js @@ -0,0 +1,337 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); +const CommentCompilationWarning = require("../CommentCompilationWarning"); +const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); +const ContextDependencyHelpers = require("./ContextDependencyHelpers"); +const { getAttributes } = require("./HarmonyImportDependencyParserPlugin"); +const ImportContextDependency = require("./ImportContextDependency"); +const ImportDependency = require("./ImportDependency"); +const ImportEagerDependency = require("./ImportEagerDependency"); +const ImportWeakDependency = require("./ImportWeakDependency"); + +/** @typedef {import("estree").ImportExpression} ImportExpression */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */ +/** @typedef {import("../ContextModule").ContextMode} ContextMode */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class ImportParserPlugin { + /** + * @param {JavascriptParserOptions} options options + */ + constructor(options) { + this.options = options; + } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + /** + * @template T + * @param {Iterable<T>} enumerable enumerable + * @returns {T[][]} array of array + */ + const exportsFromEnumerable = enumerable => + Array.from(enumerable, e => [e]); + parser.hooks.importCall.tap("ImportParserPlugin", expr => { + const param = parser.evaluateExpression(expr.source); + + let chunkName = null; + let mode = /** @type {ContextMode} */ (this.options.dynamicImportMode); + let include = null; + let exclude = null; + /** @type {string[][] | null} */ + let exports = null; + /** @type {RawChunkGroupOptions} */ + const groupOptions = {}; + + const { + dynamicImportPreload, + dynamicImportPrefetch, + dynamicImportFetchPriority + } = this.options; + if (dynamicImportPreload !== undefined && dynamicImportPreload !== false) + groupOptions.preloadOrder = + dynamicImportPreload === true ? 0 : dynamicImportPreload; + if ( + dynamicImportPrefetch !== undefined && + dynamicImportPrefetch !== false + ) + groupOptions.prefetchOrder = + dynamicImportPrefetch === true ? 0 : dynamicImportPrefetch; + if ( + dynamicImportFetchPriority !== undefined && + dynamicImportFetchPriority !== false + ) + groupOptions.fetchPriority = dynamicImportFetchPriority; + + const { options: importOptions, errors: commentErrors } = + parser.parseCommentOptions(/** @type {Range} */ (expr.range)); + + if (commentErrors) { + for (const e of commentErrors) { + const { comment } = e; + parser.state.module.addWarning( + new CommentCompilationWarning( + `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`, + comment.loc + ) + ); + } + } + + if (importOptions) { + if (importOptions.webpackIgnore !== undefined) { + if (typeof importOptions.webpackIgnore !== "boolean") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else if (importOptions.webpackIgnore) { + // Do not instrument `import()` if `webpackIgnore` is `true` + return false; + } + } + if (importOptions.webpackChunkName !== undefined) { + if (typeof importOptions.webpackChunkName !== "string") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else { + chunkName = importOptions.webpackChunkName; + } + } + if (importOptions.webpackMode !== undefined) { + if (typeof importOptions.webpackMode !== "string") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackMode\` expected a string, but received: ${importOptions.webpackMode}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else { + mode = importOptions.webpackMode; + } + } + if (importOptions.webpackPrefetch !== undefined) { + if (importOptions.webpackPrefetch === true) { + groupOptions.prefetchOrder = 0; + } else if (typeof importOptions.webpackPrefetch === "number") { + groupOptions.prefetchOrder = importOptions.webpackPrefetch; + } else { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackPrefetch\` expected true or a number, but received: ${importOptions.webpackPrefetch}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } + } + if (importOptions.webpackPreload !== undefined) { + if (importOptions.webpackPreload === true) { + groupOptions.preloadOrder = 0; + } else if (typeof importOptions.webpackPreload === "number") { + groupOptions.preloadOrder = importOptions.webpackPreload; + } else { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackPreload\` expected true or a number, but received: ${importOptions.webpackPreload}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } + } + if (importOptions.webpackFetchPriority !== undefined) { + if ( + typeof importOptions.webpackFetchPriority === "string" && + ["high", "low", "auto"].includes(importOptions.webpackFetchPriority) + ) { + groupOptions.fetchPriority = importOptions.webpackFetchPriority; + } else { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackFetchPriority\` expected true or "low", "high" or "auto", but received: ${importOptions.webpackFetchPriority}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } + } + if (importOptions.webpackInclude !== undefined) { + if ( + !importOptions.webpackInclude || + !(importOptions.webpackInclude instanceof RegExp) + ) { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackInclude\` expected a regular expression, but received: ${importOptions.webpackInclude}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else { + include = importOptions.webpackInclude; + } + } + if (importOptions.webpackExclude !== undefined) { + if ( + !importOptions.webpackExclude || + !(importOptions.webpackExclude instanceof RegExp) + ) { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackExclude\` expected a regular expression, but received: ${importOptions.webpackExclude}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else { + exclude = importOptions.webpackExclude; + } + } + if (importOptions.webpackExports !== undefined) { + if ( + !( + typeof importOptions.webpackExports === "string" || + (Array.isArray(importOptions.webpackExports) && + /** @type {string[]} */ (importOptions.webpackExports).every( + item => typeof item === "string" + )) + ) + ) { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackExports\` expected a string or an array of strings, but received: ${importOptions.webpackExports}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else if (typeof importOptions.webpackExports === "string") { + exports = [[importOptions.webpackExports]]; + } else { + exports = exportsFromEnumerable(importOptions.webpackExports); + } + } + } + + if ( + mode !== "lazy" && + mode !== "lazy-once" && + mode !== "eager" && + mode !== "weak" + ) { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + mode = "lazy"; + } + + const referencedPropertiesInDestructuring = + parser.destructuringAssignmentPropertiesFor(expr); + if (referencedPropertiesInDestructuring) { + if (exports) { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + "`webpackExports` could not be used with destructuring assignment.", + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } + exports = exportsFromEnumerable( + [...referencedPropertiesInDestructuring].map(({ id }) => id) + ); + } + + if (param.isString()) { + const attributes = getAttributes(expr); + + if (mode === "eager") { + const dep = new ImportEagerDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range), + exports, + attributes + ); + parser.state.current.addDependency(dep); + } else if (mode === "weak") { + const dep = new ImportWeakDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range), + exports, + attributes + ); + parser.state.current.addDependency(dep); + } else { + const depBlock = new AsyncDependenciesBlock( + { + ...groupOptions, + name: chunkName + }, + /** @type {DependencyLocation} */ (expr.loc), + param.string + ); + const dep = new ImportDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range), + exports, + attributes + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + depBlock.addDependency(dep); + parser.state.current.addBlock(depBlock); + } + return true; + } + if (mode === "weak") { + mode = "async-weak"; + } + const dep = ContextDependencyHelpers.create( + ImportContextDependency, + /** @type {Range} */ (expr.range), + param, + expr, + this.options, + { + chunkName, + groupOptions, + include, + exclude, + mode, + namespaceObject: /** @type {BuildMeta} */ ( + parser.state.module.buildMeta + ).strictHarmonyModule + ? "strict" + : true, + typePrefix: "import()", + category: "esm", + referencedExports: exports, + attributes: getAttributes(expr) + }, + parser + ); + if (!dep) return; + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + }); + } +} + +module.exports = ImportParserPlugin; diff --git a/node_modules/webpack/lib/dependencies/ImportPlugin.js b/node_modules/webpack/lib/dependencies/ImportPlugin.js new file mode 100644 index 00000000..4ee51a8f --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportPlugin.js @@ -0,0 +1,96 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); +const ImportContextDependency = require("./ImportContextDependency"); +const ImportDependency = require("./ImportDependency"); +const ImportEagerDependency = require("./ImportEagerDependency"); +const ImportParserPlugin = require("./ImportParserPlugin"); +const ImportWeakDependency = require("./ImportWeakDependency"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "ImportPlugin"; + +class ImportPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { contextModuleFactory, normalModuleFactory }) => { + compilation.dependencyFactories.set( + ImportDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + ImportDependency, + new ImportDependency.Template() + ); + + compilation.dependencyFactories.set( + ImportEagerDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + ImportEagerDependency, + new ImportEagerDependency.Template() + ); + + compilation.dependencyFactories.set( + ImportWeakDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + ImportWeakDependency, + new ImportWeakDependency.Template() + ); + + compilation.dependencyFactories.set( + ImportContextDependency, + contextModuleFactory + ); + compilation.dependencyTemplates.set( + ImportContextDependency, + new ImportContextDependency.Template() + ); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + if (parserOptions.import !== undefined && !parserOptions.import) + return; + + new ImportParserPlugin(parserOptions).apply(parser); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, handler); + } + ); + } +} +module.exports = ImportPlugin; diff --git a/node_modules/webpack/lib/dependencies/ImportWeakDependency.js b/node_modules/webpack/lib/dependencies/ImportWeakDependency.js new file mode 100644 index 00000000..0ed3b053 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ImportWeakDependency.js @@ -0,0 +1,72 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ImportDependency = require("./ImportDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildMeta} BuildMeta */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class ImportWeakDependency extends ImportDependency { + /** + * @param {string} request the request + * @param {Range} range expression range + * @param {(string[][] | null)=} referencedExports list of referenced exports + * @param {ImportAttributes=} attributes import attributes + */ + constructor(request, range, referencedExports, attributes) { + super(request, range, referencedExports, attributes); + this.weak = true; + } + + get type() { + return "import() weak"; + } +} + +makeSerializable( + ImportWeakDependency, + "webpack/lib/dependencies/ImportWeakDependency" +); + +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 + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { runtimeTemplate, module, moduleGraph, chunkGraph, runtimeRequirements } + ) { + const dep = /** @type {ImportWeakDependency} */ (dependency); + const content = runtimeTemplate.moduleNamespacePromise({ + chunkGraph, + module: /** @type {Module} */ (moduleGraph.getModule(dep)), + request: dep.request, + strict: /** @type {BuildMeta} */ (module.buildMeta).strictHarmonyModule, + message: "import() weak", + weak: true, + runtimeRequirements + }); + + source.replace(dep.range[0], dep.range[1] - 1, content); + } +}; + +module.exports = ImportWeakDependency; diff --git a/node_modules/webpack/lib/dependencies/JsonExportsDependency.js b/node_modules/webpack/lib/dependencies/JsonExportsDependency.js new file mode 100644 index 00000000..39ce927e --- /dev/null +++ b/node_modules/webpack/lib/dependencies/JsonExportsDependency.js @@ -0,0 +1,111 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency").ExportSpec} ExportSpec */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../json/JsonData")} JsonData */ +/** @typedef {import("../json/JsonData").RawJsonData} RawJsonData */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +/** + * @param {RawJsonData} data data + * @returns {TODO} value + */ +const getExportsFromData = data => { + if (data && typeof data === "object") { + if (Array.isArray(data)) { + return data.length < 100 + ? data.map((item, idx) => ({ + name: `${idx}`, + canMangle: true, + exports: getExportsFromData(item) + })) + : undefined; + } + const exports = []; + for (const key of Object.keys(data)) { + exports.push({ + name: key, + canMangle: true, + exports: getExportsFromData(data[key]) + }); + } + return exports; + } + return undefined; +}; + +class JsonExportsDependency extends NullDependency { + /** + * @param {JsonData} data json data + */ + constructor(data) { + super(); + this.data = data; + } + + get type() { + return "json exports"; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + return { + exports: getExportsFromData( + this.data && /** @type {RawJsonData} */ (this.data.get()) + ), + dependencies: undefined + }; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + this.data.updateHash(hash); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.data); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.data = read(); + super.deserialize(context); + } +} + +makeSerializable( + JsonExportsDependency, + "webpack/lib/dependencies/JsonExportsDependency" +); + +module.exports = JsonExportsDependency; diff --git a/node_modules/webpack/lib/dependencies/LoaderDependency.js b/node_modules/webpack/lib/dependencies/LoaderDependency.js new file mode 100644 index 00000000..7ae66b3d --- /dev/null +++ b/node_modules/webpack/lib/dependencies/LoaderDependency.js @@ -0,0 +1,41 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class LoaderDependency extends ModuleDependency { + /** + * @param {string} request request string + */ + constructor(request) { + super(request); + } + + get type() { + return "loader"; + } + + get category() { + return "loader"; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {null | false | GetConditionFn} function to determine if the connection is active + */ + getCondition(moduleGraph) { + return false; + } +} + +module.exports = LoaderDependency; diff --git a/node_modules/webpack/lib/dependencies/LoaderImportDependency.js b/node_modules/webpack/lib/dependencies/LoaderImportDependency.js new file mode 100644 index 00000000..94937922 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/LoaderImportDependency.js @@ -0,0 +1,42 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class LoaderImportDependency extends ModuleDependency { + /** + * @param {string} request request string + */ + constructor(request) { + super(request); + this.weak = true; + } + + get type() { + return "loader import"; + } + + get category() { + return "loaderImport"; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {null | false | GetConditionFn} function to determine if the connection is active + */ + getCondition(moduleGraph) { + return false; + } +} + +module.exports = LoaderImportDependency; diff --git a/node_modules/webpack/lib/dependencies/LoaderPlugin.js b/node_modules/webpack/lib/dependencies/LoaderPlugin.js new file mode 100644 index 00000000..1f42a482 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/LoaderPlugin.js @@ -0,0 +1,273 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const NormalModule = require("../NormalModule"); +const LazySet = require("../util/LazySet"); +const LoaderDependency = require("./LoaderDependency"); +const LoaderImportDependency = require("./LoaderImportDependency"); + +/** @typedef {import("../../declarations/LoaderContext").LoaderPluginLoaderContext} LoaderPluginLoaderContext */ +/** @typedef {import("../Compilation").DepConstructor} DepConstructor */ +/** @typedef {import("../Compilation").ExecuteModuleResult} ExecuteModuleResult */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../Module").BuildInfo} BuildInfo */ + +/** + * @callback ImportModuleCallback + * @param {(Error | null)=} err error object + * @param {any=} exports exports of the evaluated module + */ + +/** + * @typedef {object} ImportModuleOptions + * @property {string=} layer the target layer + * @property {string=} publicPath the target public path + * @property {string=} baseUri target base uri + */ + +class LoaderPlugin { + /** + * @param {object} options options + */ + constructor(options = {}) {} + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + "LoaderPlugin", + (compilation, { normalModuleFactory }) => { + compilation.dependencyFactories.set( + LoaderDependency, + normalModuleFactory + ); + compilation.dependencyFactories.set( + LoaderImportDependency, + normalModuleFactory + ); + } + ); + + compiler.hooks.compilation.tap("LoaderPlugin", compilation => { + const moduleGraph = compilation.moduleGraph; + NormalModule.getCompilationHooks(compilation).loader.tap( + "LoaderPlugin", + loaderContext => { + loaderContext.loadModule = (request, callback) => { + const dep = new LoaderDependency(request); + dep.loc = { + name: request + }; + const factory = compilation.dependencyFactories.get( + /** @type {DepConstructor} */ (dep.constructor) + ); + if (factory === undefined) { + return callback( + new Error( + `No module factory available for dependency type: ${dep.constructor.name}` + ) + ); + } + compilation.buildQueue.increaseParallelism(); + compilation.handleModuleCreation( + { + factory, + dependencies: [dep], + originModule: + /** @type {NormalModule} */ + (loaderContext._module), + context: loaderContext.context, + recursive: false + }, + err => { + compilation.buildQueue.decreaseParallelism(); + if (err) { + return callback(err); + } + const referencedModule = moduleGraph.getModule(dep); + if (!referencedModule) { + return callback(new Error("Cannot load the module")); + } + if (referencedModule.getNumberOfErrors() > 0) { + return callback( + new Error("The loaded module contains errors") + ); + } + const moduleSource = referencedModule.originalSource(); + if (!moduleSource) { + return callback( + new Error( + "The module created for a LoaderDependency must have an original source" + ) + ); + } + let map; + let source; + if (moduleSource.sourceAndMap) { + const sourceAndMap = moduleSource.sourceAndMap(); + map = sourceAndMap.map; + source = sourceAndMap.source; + } else { + map = moduleSource.map(); + source = moduleSource.source(); + } + const fileDependencies = new LazySet(); + const contextDependencies = new LazySet(); + const missingDependencies = new LazySet(); + const buildDependencies = new LazySet(); + referencedModule.addCacheDependencies( + fileDependencies, + contextDependencies, + missingDependencies, + buildDependencies + ); + + for (const d of fileDependencies) { + loaderContext.addDependency(d); + } + for (const d of contextDependencies) { + loaderContext.addContextDependency(d); + } + for (const d of missingDependencies) { + loaderContext.addMissingDependency(d); + } + for (const d of buildDependencies) { + loaderContext.addBuildDependency(d); + } + return callback( + null, + source, + /** @type {object | null} */ (map), + referencedModule + ); + } + ); + }; + + /** + * @param {string} request the request string to load the module from + * @param {ImportModuleOptions} options options + * @param {ImportModuleCallback} callback callback returning the exports + * @returns {void} + */ + const importModule = (request, options, callback) => { + const dep = new LoaderImportDependency(request); + dep.loc = { + name: request + }; + const factory = compilation.dependencyFactories.get( + /** @type {DepConstructor} */ (dep.constructor) + ); + if (factory === undefined) { + return callback( + new Error( + `No module factory available for dependency type: ${dep.constructor.name}` + ) + ); + } + compilation.buildQueue.increaseParallelism(); + compilation.handleModuleCreation( + { + factory, + dependencies: [dep], + originModule: + /** @type {NormalModule} */ + (loaderContext._module), + contextInfo: { + issuerLayer: options.layer + }, + context: loaderContext.context, + connectOrigin: false, + checkCycle: true + }, + err => { + compilation.buildQueue.decreaseParallelism(); + if (err) { + return callback(err); + } + const referencedModule = moduleGraph.getModule(dep); + if (!referencedModule) { + return callback(new Error("Cannot load the module")); + } + compilation.executeModule( + referencedModule, + { + entryOptions: { + baseUri: options.baseUri, + publicPath: options.publicPath + } + }, + (err, result) => { + if (err) return callback(err); + const { + fileDependencies, + contextDependencies, + missingDependencies, + buildDependencies, + cacheable, + assets, + exports + } = /** @type {ExecuteModuleResult} */ (result); + for (const d of fileDependencies) { + loaderContext.addDependency(d); + } + for (const d of contextDependencies) { + loaderContext.addContextDependency(d); + } + for (const d of missingDependencies) { + loaderContext.addMissingDependency(d); + } + for (const d of buildDependencies) { + loaderContext.addBuildDependency(d); + } + if (cacheable === false) loaderContext.cacheable(false); + for (const [name, { source, info }] of assets) { + const buildInfo = + /** @type {BuildInfo} */ + ( + /** @type {NormalModule} */ (loaderContext._module) + .buildInfo + ); + if (!buildInfo.assets) { + buildInfo.assets = Object.create(null); + buildInfo.assetsInfo = new Map(); + } + /** @type {NonNullable<BuildInfo["assets"]>} */ + (buildInfo.assets)[name] = source; + /** @type {NonNullable<BuildInfo["assetsInfo"]>} */ + (buildInfo.assetsInfo).set(name, info); + } + callback(null, exports); + } + ); + } + ); + }; + + // eslint-disable-next-line no-warning-comments + // @ts-ignore Overloading doesn't work + loaderContext.importModule = (request, options, callback) => { + if (!callback) { + return new Promise((resolve, reject) => { + importModule(request, options || {}, (err, result) => { + if (err) reject(err); + else resolve(result); + }); + }); + } + return importModule(request, options || {}, callback); + }; + } + ); + }); + } +} +module.exports = LoaderPlugin; diff --git a/node_modules/webpack/lib/dependencies/LocalModule.js b/node_modules/webpack/lib/dependencies/LocalModule.js new file mode 100644 index 00000000..7748a06b --- /dev/null +++ b/node_modules/webpack/lib/dependencies/LocalModule.js @@ -0,0 +1,60 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); + +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class LocalModule { + /** + * @param {string} name name + * @param {number} idx index + */ + constructor(name, idx) { + this.name = name; + this.idx = idx; + this.used = false; + } + + flagUsed() { + this.used = true; + } + + /** + * @returns {string} variable name + */ + variableName() { + return `__WEBPACK_LOCAL_MODULE_${this.idx}__`; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.name); + write(this.idx); + write(this.used); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.name = read(); + this.idx = read(); + this.used = read(); + } +} + +makeSerializable(LocalModule, "webpack/lib/dependencies/LocalModule"); + +module.exports = LocalModule; diff --git a/node_modules/webpack/lib/dependencies/LocalModuleDependency.js b/node_modules/webpack/lib/dependencies/LocalModuleDependency.js new file mode 100644 index 00000000..2cde22fe --- /dev/null +++ b/node_modules/webpack/lib/dependencies/LocalModuleDependency.js @@ -0,0 +1,84 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./LocalModule")} LocalModule */ + +class LocalModuleDependency extends NullDependency { + /** + * @param {LocalModule} localModule local module + * @param {Range | undefined} range range + * @param {boolean} callNew true, when the local module should be called with new + */ + constructor(localModule, range, callNew) { + super(); + + this.localModule = localModule; + this.range = range; + this.callNew = callNew; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.localModule); + write(this.range); + write(this.callNew); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.localModule = read(); + this.range = read(); + this.callNew = read(); + + super.deserialize(context); + } +} + +makeSerializable( + LocalModuleDependency, + "webpack/lib/dependencies/LocalModuleDependency" +); + +LocalModuleDependency.Template = class LocalModuleDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {LocalModuleDependency} */ (dependency); + if (!dep.range) return; + const moduleInstance = dep.callNew + ? `new (function () { return ${dep.localModule.variableName()}; })()` + : dep.localModule.variableName(); + source.replace(dep.range[0], dep.range[1] - 1, moduleInstance); + } +}; + +module.exports = LocalModuleDependency; diff --git a/node_modules/webpack/lib/dependencies/LocalModulesHelpers.js b/node_modules/webpack/lib/dependencies/LocalModulesHelpers.js new file mode 100644 index 00000000..bcb947c2 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/LocalModulesHelpers.js @@ -0,0 +1,68 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const LocalModule = require("./LocalModule"); + +/** @typedef {import("../javascript/JavascriptParser").ParserState} ParserState */ + +/** + * @param {string} parent parent module + * @param {string} mod module to resolve + * @returns {string} resolved module + */ +const lookup = (parent, mod) => { + if (mod.charAt(0) !== ".") return mod; + + const path = parent.split("/"); + const segments = mod.split("/"); + path.pop(); + + for (let i = 0; i < segments.length; i++) { + const seg = segments[i]; + if (seg === "..") { + path.pop(); + } else if (seg !== ".") { + path.push(seg); + } + } + + return path.join("/"); +}; + +/** + * @param {ParserState} state parser state + * @param {string} name name + * @returns {LocalModule} local module + */ +module.exports.addLocalModule = (state, name) => { + if (!state.localModules) { + state.localModules = []; + } + const m = new LocalModule(name, state.localModules.length); + state.localModules.push(m); + return m; +}; + +/** + * @param {ParserState} state parser state + * @param {string} name name + * @param {string} [namedModule] named module + * @returns {LocalModule | null} local module or null + */ +module.exports.getLocalModule = (state, name, namedModule) => { + if (!state.localModules) return null; + if (namedModule) { + // resolve dependency name relative to the defining named module + name = lookup(namedModule, name); + } + for (let i = 0; i < state.localModules.length; i++) { + if (state.localModules[i].name === name) { + return state.localModules[i]; + } + } + return null; +}; diff --git a/node_modules/webpack/lib/dependencies/ModuleDecoratorDependency.js b/node_modules/webpack/lib/dependencies/ModuleDecoratorDependency.js new file mode 100644 index 00000000..fd2b3fe5 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ModuleDecoratorDependency.js @@ -0,0 +1,137 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const InitFragment = require("../InitFragment"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../DependencyTemplates")} DependencyTemplates */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class ModuleDecoratorDependency extends NullDependency { + /** + * @param {string} decorator the decorator requirement + * @param {boolean} allowExportsAccess allow to access exports from module + */ + constructor(decorator, allowExportsAccess) { + super(); + this.decorator = decorator; + this.allowExportsAccess = allowExportsAccess; + this._hashUpdate = undefined; + } + + /** + * @returns {string} a display name for the type of dependency + */ + get type() { + return "module decorator"; + } + + get category() { + return "self"; + } + + /** + * @returns {string | null} an identifier to merge equal requests + */ + getResourceIdentifier() { + return "self"; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + return this.allowExportsAccess + ? Dependency.EXPORTS_OBJECT_REFERENCED + : Dependency.NO_EXPORTS_REFERENCED; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + if (this._hashUpdate === undefined) { + this._hashUpdate = `${this.decorator}${this.allowExportsAccess}`; + } + hash.update(this._hashUpdate); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.decorator); + write(this.allowExportsAccess); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.decorator = read(); + this.allowExportsAccess = read(); + super.deserialize(context); + } +} + +makeSerializable( + ModuleDecoratorDependency, + "webpack/lib/dependencies/ModuleDecoratorDependency" +); + +ModuleDecoratorDependency.Template = class ModuleDecoratorDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { module, chunkGraph, initFragments, runtimeRequirements } + ) { + const dep = /** @type {ModuleDecoratorDependency} */ (dependency); + runtimeRequirements.add(RuntimeGlobals.moduleLoaded); + runtimeRequirements.add(RuntimeGlobals.moduleId); + runtimeRequirements.add(RuntimeGlobals.module); + runtimeRequirements.add(dep.decorator); + initFragments.push( + new InitFragment( + `/* module decorator */ ${module.moduleArgument} = ${dep.decorator}(${module.moduleArgument});\n`, + InitFragment.STAGE_PROVIDES, + 0, + `module decorator ${chunkGraph.getModuleId(module)}` + ) + ); + } +}; + +module.exports = ModuleDecoratorDependency; diff --git a/node_modules/webpack/lib/dependencies/ModuleDependency.js b/node_modules/webpack/lib/dependencies/ModuleDependency.js new file mode 100644 index 00000000..76b9d174 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ModuleDependency.js @@ -0,0 +1,98 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const DependencyTemplate = require("../DependencyTemplate"); +const RawModule = require("../RawModule"); + +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../javascript/JavascriptParser").ImportAttributes} ImportAttributes */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class ModuleDependency extends Dependency { + /** + * @param {string} request request path which needs resolving + */ + constructor(request) { + super(); + this.request = request; + this.userRequest = request; + this.range = undefined; + // TODO move it to subclasses and rename + // assertions must be serialized by subclasses that use it + /** @type {ImportAttributes | undefined} */ + this.assertions = undefined; + this._context = undefined; + } + + /** + * @returns {string | undefined} a request context + */ + getContext() { + return this._context; + } + + /** + * @returns {string | null} an identifier to merge equal requests + */ + getResourceIdentifier() { + let str = `context${this._context || ""}|module${this.request}`; + if (this.assertions !== undefined) { + str += JSON.stringify(this.assertions); + } + return str; + } + + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return true; + } + + /** + * @param {string} context context directory + * @returns {Module | null} a module + */ + createIgnoredModule(context) { + return new RawModule( + "/* (ignored) */", + `ignored|${context}|${this.request}`, + `${this.request} (ignored)` + ); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.request); + write(this.userRequest); + write(this._context); + write(this.range); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.request = read(); + this.userRequest = read(); + this._context = read(); + this.range = read(); + super.deserialize(context); + } +} + +ModuleDependency.Template = DependencyTemplate; + +module.exports = ModuleDependency; diff --git a/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsId.js b/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsId.js new file mode 100644 index 00000000..8086fc79 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsId.js @@ -0,0 +1,35 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ + +class ModuleDependencyTemplateAsId extends ModuleDependency.Template { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { runtimeTemplate, moduleGraph, chunkGraph }) { + const dep = /** @type {ModuleDependency} */ (dependency); + if (!dep.range) return; + const content = runtimeTemplate.moduleId({ + module: /** @type {Module} */ (moduleGraph.getModule(dep)), + chunkGraph, + request: dep.request, + weak: dep.weak + }); + source.replace(dep.range[0], dep.range[1] - 1, content); + } +} + +module.exports = ModuleDependencyTemplateAsId; diff --git a/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsRequireId.js b/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsRequireId.js new file mode 100644 index 00000000..9e05906c --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ModuleDependencyTemplateAsRequireId.js @@ -0,0 +1,38 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ + +class ModuleDependencyTemplateAsRequireId extends ModuleDependency.Template { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } + ) { + const dep = /** @type {ModuleDependency} */ (dependency); + if (!dep.range) return; + const content = runtimeTemplate.moduleExports({ + module: moduleGraph.getModule(dep), + chunkGraph, + request: dep.request, + weak: dep.weak, + runtimeRequirements + }); + source.replace(dep.range[0], dep.range[1] - 1, content); + } +} +module.exports = ModuleDependencyTemplateAsRequireId; diff --git a/node_modules/webpack/lib/dependencies/ModuleHotAcceptDependency.js b/node_modules/webpack/lib/dependencies/ModuleHotAcceptDependency.js new file mode 100644 index 00000000..1916a7e2 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ModuleHotAcceptDependency.js @@ -0,0 +1,41 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); +const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class ModuleHotAcceptDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ + constructor(request, range) { + super(request); + this.range = range; + this.weak = true; + } + + get type() { + return "module.hot.accept"; + } + + get category() { + return "commonjs"; + } +} + +makeSerializable( + ModuleHotAcceptDependency, + "webpack/lib/dependencies/ModuleHotAcceptDependency" +); + +ModuleHotAcceptDependency.Template = ModuleDependencyTemplateAsId; + +module.exports = ModuleHotAcceptDependency; diff --git a/node_modules/webpack/lib/dependencies/ModuleHotDeclineDependency.js b/node_modules/webpack/lib/dependencies/ModuleHotDeclineDependency.js new file mode 100644 index 00000000..70423774 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ModuleHotDeclineDependency.js @@ -0,0 +1,42 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); +const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class ModuleHotDeclineDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ + constructor(request, range) { + super(request); + + this.range = range; + this.weak = true; + } + + get type() { + return "module.hot.decline"; + } + + get category() { + return "commonjs"; + } +} + +makeSerializable( + ModuleHotDeclineDependency, + "webpack/lib/dependencies/ModuleHotDeclineDependency" +); + +ModuleHotDeclineDependency.Template = ModuleDependencyTemplateAsId; + +module.exports = ModuleHotDeclineDependency; diff --git a/node_modules/webpack/lib/dependencies/NullDependency.js b/node_modules/webpack/lib/dependencies/NullDependency.js new file mode 100644 index 00000000..c22cafc7 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/NullDependency.js @@ -0,0 +1,40 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const DependencyTemplate = require("../DependencyTemplate"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ + +class NullDependency extends Dependency { + get type() { + return "null"; + } + + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return false; + } +} + +NullDependency.Template = class NullDependencyTemplate extends ( + DependencyTemplate +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) {} +}; + +module.exports = NullDependency; diff --git a/node_modules/webpack/lib/dependencies/PrefetchDependency.js b/node_modules/webpack/lib/dependencies/PrefetchDependency.js new file mode 100644 index 00000000..59e22c59 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/PrefetchDependency.js @@ -0,0 +1,27 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const ModuleDependency = require("./ModuleDependency"); + +class PrefetchDependency extends ModuleDependency { + /** + * @param {string} request the request string + */ + constructor(request) { + super(request); + } + + get type() { + return "prefetch"; + } + + get category() { + return "esm"; + } +} + +module.exports = PrefetchDependency; diff --git a/node_modules/webpack/lib/dependencies/ProvidedDependency.js b/node_modules/webpack/lib/dependencies/ProvidedDependency.js new file mode 100644 index 00000000..9f1d3f6e --- /dev/null +++ b/node_modules/webpack/lib/dependencies/ProvidedDependency.js @@ -0,0 +1,157 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Florent Cailhol @ooflorent +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const InitFragment = require("../InitFragment"); +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../DependencyTemplates")} DependencyTemplates */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +/** + * @param {string[]|null} path the property path array + * @returns {string} the converted path + */ +const pathToString = path => + path !== null && path.length > 0 + ? path.map(part => `[${JSON.stringify(part)}]`).join("") + : ""; + +class ProvidedDependency extends ModuleDependency { + /** + * @param {string} request request + * @param {string} identifier identifier + * @param {string[]} ids ids + * @param {Range} range range + */ + constructor(request, identifier, ids, range) { + super(request); + this.identifier = identifier; + this.ids = ids; + this.range = range; + this._hashUpdate = undefined; + } + + get type() { + return "provided"; + } + + get category() { + return "esm"; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + const ids = this.ids; + if (ids.length === 0) return Dependency.EXPORTS_OBJECT_REFERENCED; + return [ids]; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + if (this._hashUpdate === undefined) { + this._hashUpdate = this.identifier + (this.ids ? this.ids.join(",") : ""); + } + hash.update(this._hashUpdate); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.identifier); + write(this.ids); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.identifier = read(); + this.ids = read(); + super.deserialize(context); + } +} + +makeSerializable( + ProvidedDependency, + "webpack/lib/dependencies/ProvidedDependency" +); + +class ProvidedDependencyTemplate extends ModuleDependency.Template { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { + runtime, + runtimeTemplate, + moduleGraph, + chunkGraph, + initFragments, + runtimeRequirements + } + ) { + const dep = /** @type {ProvidedDependency} */ (dependency); + const connection = + /** @type {ModuleGraphConnection} */ + (moduleGraph.getConnection(dep)); + const exportsInfo = moduleGraph.getExportsInfo(connection.module); + const usedName = exportsInfo.getUsedName(dep.ids, runtime); + initFragments.push( + new InitFragment( + `/* provided dependency */ var ${ + dep.identifier + } = ${runtimeTemplate.moduleExports({ + module: moduleGraph.getModule(dep), + chunkGraph, + request: dep.request, + runtimeRequirements + })}${pathToString(/** @type {string[]} */ (usedName))};\n`, + InitFragment.STAGE_PROVIDES, + 1, + `provided ${dep.identifier}` + ) + ); + source.replace(dep.range[0], dep.range[1] - 1, dep.identifier); + } +} + +ProvidedDependency.Template = ProvidedDependencyTemplate; + +module.exports = ProvidedDependency; diff --git a/node_modules/webpack/lib/dependencies/PureExpressionDependency.js b/node_modules/webpack/lib/dependencies/PureExpressionDependency.js new file mode 100644 index 00000000..3c4312c9 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/PureExpressionDependency.js @@ -0,0 +1,162 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { UsageState } = require("../ExportsInfo"); +const makeSerializable = require("../util/makeSerializable"); +const { filterRuntime, runtimeToString } = require("../util/runtime"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").RuntimeSpec} RuntimeSpec */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +class PureExpressionDependency extends NullDependency { + /** + * @param {Range} range the source range + */ + constructor(range) { + super(); + this.range = range; + /** @type {Set<string> | false} */ + this.usedByExports = false; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime current runtimes + * @returns {boolean | RuntimeSpec} runtime condition + */ + _getRuntimeCondition(moduleGraph, runtime) { + const usedByExports = this.usedByExports; + if (usedByExports !== false) { + const selfModule = + /** @type {Module} */ + (moduleGraph.getParentModule(this)); + const exportsInfo = moduleGraph.getExportsInfo(selfModule); + const runtimeCondition = filterRuntime(runtime, runtime => { + for (const exportName of usedByExports) { + if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) { + return true; + } + } + return false; + }); + return runtimeCondition; + } + return false; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + const runtimeCondition = this._getRuntimeCondition( + context.chunkGraph.moduleGraph, + context.runtime + ); + if (runtimeCondition === true) { + return; + } else if (runtimeCondition === false) { + hash.update("null"); + } else { + hash.update( + `${runtimeToString(runtimeCondition)}|${runtimeToString( + context.runtime + )}` + ); + } + hash.update(String(this.range)); + } + + /** + * @param {ModuleGraph} moduleGraph the module graph + * @returns {ConnectionState} how this dependency connects the module to referencing modules + */ + getModuleEvaluationSideEffectsState(moduleGraph) { + return false; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + write(this.usedByExports); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.range = read(); + this.usedByExports = read(); + super.deserialize(context); + } +} + +makeSerializable( + PureExpressionDependency, + "webpack/lib/dependencies/PureExpressionDependency" +); + +PureExpressionDependency.Template = class PureExpressionDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { chunkGraph, moduleGraph, runtime, runtimeTemplate, runtimeRequirements } + ) { + const dep = /** @type {PureExpressionDependency} */ (dependency); + const runtimeCondition = dep._getRuntimeCondition(moduleGraph, runtime); + if (runtimeCondition === true) { + // Do nothing + } else if (runtimeCondition === false) { + source.insert( + dep.range[0], + "(/* unused pure expression or super */ null && (" + ); + source.insert(dep.range[1], "))"); + } else { + const condition = runtimeTemplate.runtimeConditionExpression({ + chunkGraph, + runtime, + runtimeCondition, + runtimeRequirements + }); + source.insert( + dep.range[0], + `(/* runtime-dependent pure expression or super */ ${condition} ? (` + ); + source.insert(dep.range[1], ") : null)"); + } + } +}; + +module.exports = PureExpressionDependency; diff --git a/node_modules/webpack/lib/dependencies/RequireContextDependency.js b/node_modules/webpack/lib/dependencies/RequireContextDependency.js new file mode 100644 index 00000000..9aa883f2 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireContextDependency.js @@ -0,0 +1,37 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ContextDependency = require("./ContextDependency"); +const ModuleDependencyTemplateAsRequireId = require("./ModuleDependencyTemplateAsRequireId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +class RequireContextDependency extends ContextDependency { + /** + * @param {TODO} options options + * @param {Range} range range + */ + constructor(options, range) { + super(options); + + this.range = range; + } + + get type() { + return "require.context"; + } +} + +makeSerializable( + RequireContextDependency, + "webpack/lib/dependencies/RequireContextDependency" +); + +RequireContextDependency.Template = ModuleDependencyTemplateAsRequireId; + +module.exports = RequireContextDependency; diff --git a/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js b/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js new file mode 100644 index 00000000..02ce1c14 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireContextDependencyParserPlugin.js @@ -0,0 +1,66 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RequireContextDependency = require("./RequireContextDependency"); + +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +module.exports = class RequireContextDependencyParserPlugin { + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + parser.hooks.call + .for("require.context") + .tap("RequireContextDependencyParserPlugin", expr => { + let regExp = /^\.\/.*$/; + let recursive = true; + let mode = "sync"; + switch (expr.arguments.length) { + case 4: { + const modeExpr = parser.evaluateExpression(expr.arguments[3]); + if (!modeExpr.isString()) return; + mode = /** @type {string} */ (modeExpr.string); + } + // falls through + case 3: { + const regExpExpr = parser.evaluateExpression(expr.arguments[2]); + if (!regExpExpr.isRegExp()) return; + regExp = /** @type {RegExp} */ (regExpExpr.regExp); + } + // falls through + case 2: { + const recursiveExpr = parser.evaluateExpression(expr.arguments[1]); + if (!recursiveExpr.isBoolean()) return; + recursive = /** @type {boolean} */ (recursiveExpr.bool); + } + // falls through + case 1: { + const requestExpr = parser.evaluateExpression(expr.arguments[0]); + if (!requestExpr.isString()) return; + const dep = new RequireContextDependency( + { + request: requestExpr.string, + recursive, + regExp, + mode, + category: "commonjs" + }, + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + dep.optional = Boolean(parser.scope.inTry); + parser.state.current.addDependency(dep); + return true; + } + } + }); + } +}; diff --git a/node_modules/webpack/lib/dependencies/RequireContextPlugin.js b/node_modules/webpack/lib/dependencies/RequireContextPlugin.js new file mode 100644 index 00000000..30e87fb9 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireContextPlugin.js @@ -0,0 +1,163 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); +const { cachedSetProperty } = require("../util/cleverMerge"); +const ContextElementDependency = require("./ContextElementDependency"); +const RequireContextDependency = require("./RequireContextDependency"); +const RequireContextDependencyParserPlugin = require("./RequireContextDependencyParserPlugin"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +/** @type {ResolveOptions} */ +const EMPTY_RESOLVE_OPTIONS = {}; + +const PLUGIN_NAME = "RequireContextPlugin"; + +class RequireContextPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { contextModuleFactory, normalModuleFactory }) => { + compilation.dependencyFactories.set( + RequireContextDependency, + contextModuleFactory + ); + compilation.dependencyTemplates.set( + RequireContextDependency, + new RequireContextDependency.Template() + ); + + compilation.dependencyFactories.set( + ContextElementDependency, + normalModuleFactory + ); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + if ( + parserOptions.requireContext !== undefined && + !parserOptions.requireContext + ) + return; + + new RequireContextDependencyParserPlugin().apply(parser); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); + + contextModuleFactory.hooks.alternativeRequests.tap( + PLUGIN_NAME, + (items, options) => { + if (items.length === 0) return items; + + const finalResolveOptions = compiler.resolverFactory.get( + "normal", + cachedSetProperty( + options.resolveOptions || EMPTY_RESOLVE_OPTIONS, + "dependencyType", + /** @type {string} */ (options.category) + ) + ).options; + + let newItems; + if (!finalResolveOptions.fullySpecified) { + newItems = []; + for (const item of items) { + const { request, context } = item; + for (const ext of finalResolveOptions.extensions) { + if (request.endsWith(ext)) { + newItems.push({ + context, + request: request.slice(0, -ext.length) + }); + } + } + if (!finalResolveOptions.enforceExtension) { + newItems.push(item); + } + } + items = newItems; + + newItems = []; + for (const obj of items) { + const { request, context } = obj; + for (const mainFile of finalResolveOptions.mainFiles) { + if (request.endsWith(`/${mainFile}`)) { + newItems.push({ + context, + request: request.slice(0, -mainFile.length) + }); + newItems.push({ + context, + request: request.slice(0, -mainFile.length - 1) + }); + } + } + newItems.push(obj); + } + items = newItems; + } + + newItems = []; + for (const item of items) { + let hideOriginal = false; + for (const modulesItems of finalResolveOptions.modules) { + if (Array.isArray(modulesItems)) { + for (const dir of modulesItems) { + if (item.request.startsWith(`./${dir}/`)) { + newItems.push({ + context: item.context, + request: item.request.slice(dir.length + 3) + }); + hideOriginal = true; + } + } + } else { + const dir = modulesItems.replace(/\\/g, "/"); + const fullPath = + item.context.replace(/\\/g, "/") + item.request.slice(1); + if (fullPath.startsWith(dir)) { + newItems.push({ + context: item.context, + request: fullPath.slice(dir.length + 1) + }); + } + } + } + if (!hideOriginal) { + newItems.push(item); + } + } + return newItems; + } + ); + } + ); + } +} +module.exports = RequireContextPlugin; diff --git a/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js b/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js new file mode 100644 index 00000000..6cf8294e --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlock.js @@ -0,0 +1,29 @@ +/* + 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 RequireEnsureDependenciesBlock extends AsyncDependenciesBlock { + /** + * @param {ChunkGroupOptions & { entryOptions?: TODO }} chunkName chunk name + * @param {DependencyLocation} loc location info + */ + constructor(chunkName, loc) { + super(chunkName, loc, null); + } +} + +makeSerializable( + RequireEnsureDependenciesBlock, + "webpack/lib/dependencies/RequireEnsureDependenciesBlock" +); + +module.exports = RequireEnsureDependenciesBlock; diff --git a/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js b/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js new file mode 100644 index 00000000..c81fada8 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js @@ -0,0 +1,138 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RequireEnsureDependenciesBlock = require("./RequireEnsureDependenciesBlock"); +const RequireEnsureDependency = require("./RequireEnsureDependency"); +const RequireEnsureItemDependency = require("./RequireEnsureItemDependency"); +const getFunctionExpression = require("./getFunctionExpression"); + +/** @typedef {import("../ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +module.exports = class RequireEnsureDependenciesBlockParserPlugin { + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + parser.hooks.call + .for("require.ensure") + .tap("RequireEnsureDependenciesBlockParserPlugin", expr => { + let chunkName = null; + let errorExpressionArg = null; + let errorExpression = null; + switch (expr.arguments.length) { + case 4: { + const chunkNameExpr = parser.evaluateExpression(expr.arguments[3]); + if (!chunkNameExpr.isString()) return; + chunkName = chunkNameExpr.string; + } + // falls through + case 3: { + errorExpressionArg = expr.arguments[2]; + errorExpression = getFunctionExpression(errorExpressionArg); + + if (!errorExpression && !chunkName) { + const chunkNameExpr = parser.evaluateExpression( + expr.arguments[2] + ); + if (!chunkNameExpr.isString()) return; + chunkName = chunkNameExpr.string; + } + } + // falls through + case 2: { + const dependenciesExpr = parser.evaluateExpression( + expr.arguments[0] + ); + const dependenciesItems = + /** @type {BasicEvaluatedExpression[]} */ ( + dependenciesExpr.isArray() + ? dependenciesExpr.items + : [dependenciesExpr] + ); + const successExpressionArg = expr.arguments[1]; + const successExpression = + getFunctionExpression(successExpressionArg); + + if (successExpression) { + parser.walkExpressions(successExpression.expressions); + } + if (errorExpression) { + parser.walkExpressions(errorExpression.expressions); + } + + const depBlock = new RequireEnsureDependenciesBlock( + /** @type {ChunkGroupOptions & { entryOptions?: TODO }} */ + (chunkName), + /** @type {DependencyLocation} */ (expr.loc) + ); + const errorCallbackExists = + expr.arguments.length === 4 || + (!chunkName && expr.arguments.length === 3); + const dep = new RequireEnsureDependency( + /** @type {Range} */ (expr.range), + /** @type {Range} */ (expr.arguments[1].range), + errorCallbackExists && + /** @type {Range} */ (expr.arguments[2].range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + depBlock.addDependency(dep); + const old = parser.state.current; + parser.state.current = /** @type {TODO} */ (depBlock); + try { + let failed = false; + parser.inScope([], () => { + for (const ee of dependenciesItems) { + if (ee.isString()) { + const ensureDependency = new RequireEnsureItemDependency( + /** @type {string} */ (ee.string) + ); + ensureDependency.loc = + /** @type {DependencyLocation} */ + (expr.loc); + depBlock.addDependency(ensureDependency); + } else { + failed = true; + } + } + }); + if (failed) { + return; + } + if (successExpression) { + if (successExpression.fn.body.type === "BlockStatement") { + parser.walkStatement(successExpression.fn.body); + } else { + parser.walkExpression(successExpression.fn.body); + } + } + old.addBlock(depBlock); + } finally { + parser.state.current = old; + } + if (!successExpression) { + parser.walkExpression(successExpressionArg); + } + if (errorExpression) { + if (errorExpression.fn.body.type === "BlockStatement") { + parser.walkStatement(errorExpression.fn.body); + } else { + parser.walkExpression(errorExpression.fn.body); + } + } else if (errorExpressionArg) { + parser.walkExpression(errorExpressionArg); + } + return true; + } + } + }); + } +}; diff --git a/node_modules/webpack/lib/dependencies/RequireEnsureDependency.js b/node_modules/webpack/lib/dependencies/RequireEnsureDependency.js new file mode 100644 index 00000000..4fcec773 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireEnsureDependency.js @@ -0,0 +1,115 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class RequireEnsureDependency extends NullDependency { + /** + * @param {Range} range range + * @param {Range} contentRange content range + * @param {Range | false} errorHandlerRange error handler range + */ + constructor(range, contentRange, errorHandlerRange) { + super(); + + this.range = range; + this.contentRange = contentRange; + this.errorHandlerRange = errorHandlerRange; + } + + get type() { + return "require.ensure"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.range); + write(this.contentRange); + write(this.errorHandlerRange); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.range = read(); + this.contentRange = read(); + this.errorHandlerRange = read(); + + super.deserialize(context); + } +} + +makeSerializable( + RequireEnsureDependency, + "webpack/lib/dependencies/RequireEnsureDependency" +); + +RequireEnsureDependency.Template = class RequireEnsureDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply( + dependency, + source, + { runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements } + ) { + const dep = /** @type {RequireEnsureDependency} */ (dependency); + const depBlock = /** @type {AsyncDependenciesBlock} */ ( + moduleGraph.getParentBlock(dep) + ); + const promise = runtimeTemplate.blockPromise({ + chunkGraph, + block: depBlock, + message: "require.ensure", + runtimeRequirements + }); + const range = dep.range; + const contentRange = dep.contentRange; + const errorHandlerRange = dep.errorHandlerRange; + source.replace(range[0], contentRange[0] - 1, `${promise}.then((`); + if (errorHandlerRange) { + source.replace( + contentRange[1], + errorHandlerRange[0] - 1, + `).bind(null, ${RuntimeGlobals.require}))['catch'](` + ); + source.replace(errorHandlerRange[1], range[1] - 1, ")"); + } else { + source.replace( + contentRange[1], + range[1] - 1, + `).bind(null, ${RuntimeGlobals.require}))['catch'](${RuntimeGlobals.uncaughtErrorHandler})` + ); + } + } +}; + +module.exports = RequireEnsureDependency; diff --git a/node_modules/webpack/lib/dependencies/RequireEnsureItemDependency.js b/node_modules/webpack/lib/dependencies/RequireEnsureItemDependency.js new file mode 100644 index 00000000..f9a465a5 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireEnsureItemDependency.js @@ -0,0 +1,36 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); +const NullDependency = require("./NullDependency"); + +class RequireEnsureItemDependency extends ModuleDependency { + /** + * @param {string} request the request string + */ + constructor(request) { + super(request); + } + + get type() { + return "require.ensure item"; + } + + get category() { + return "commonjs"; + } +} + +makeSerializable( + RequireEnsureItemDependency, + "webpack/lib/dependencies/RequireEnsureItemDependency" +); + +RequireEnsureItemDependency.Template = NullDependency.Template; + +module.exports = RequireEnsureItemDependency; diff --git a/node_modules/webpack/lib/dependencies/RequireEnsurePlugin.js b/node_modules/webpack/lib/dependencies/RequireEnsurePlugin.js new file mode 100644 index 00000000..5a1dc31d --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireEnsurePlugin.js @@ -0,0 +1,86 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RequireEnsureDependency = require("./RequireEnsureDependency"); +const RequireEnsureItemDependency = require("./RequireEnsureItemDependency"); + +const RequireEnsureDependenciesBlockParserPlugin = require("./RequireEnsureDependenciesBlockParserPlugin"); + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); +const { + evaluateToString, + toConstantDependency +} = require("../javascript/JavascriptParserHelpers"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "RequireEnsurePlugin"; + +class RequireEnsurePlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { normalModuleFactory }) => { + compilation.dependencyFactories.set( + RequireEnsureItemDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + RequireEnsureItemDependency, + new RequireEnsureItemDependency.Template() + ); + + compilation.dependencyTemplates.set( + RequireEnsureDependency, + new RequireEnsureDependency.Template() + ); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + if ( + parserOptions.requireEnsure !== undefined && + !parserOptions.requireEnsure + ) + return; + + new RequireEnsureDependenciesBlockParserPlugin().apply(parser); + parser.hooks.evaluateTypeof + .for("require.ensure") + .tap(PLUGIN_NAME, evaluateToString("function")); + parser.hooks.typeof + .for("require.ensure") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("function")) + ); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); + } + ); + } +} +module.exports = RequireEnsurePlugin; diff --git a/node_modules/webpack/lib/dependencies/RequireHeaderDependency.js b/node_modules/webpack/lib/dependencies/RequireHeaderDependency.js new file mode 100644 index 00000000..7bf75603 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireHeaderDependency.js @@ -0,0 +1,70 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class RequireHeaderDependency extends NullDependency { + /** + * @param {Range} range range + */ + constructor(range) { + super(); + if (!Array.isArray(range)) throw new Error("range must be valid"); + this.range = range; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.range); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + * @returns {RequireHeaderDependency} RequireHeaderDependency + */ + static deserialize(context) { + const obj = new RequireHeaderDependency(context.read()); + obj.deserialize(context); + return obj; + } +} + +makeSerializable( + RequireHeaderDependency, + "webpack/lib/dependencies/RequireHeaderDependency" +); + +RequireHeaderDependency.Template = class RequireHeaderDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { runtimeRequirements }) { + const dep = /** @type {RequireHeaderDependency} */ (dependency); + runtimeRequirements.add(RuntimeGlobals.require); + source.replace(dep.range[0], dep.range[1] - 1, RuntimeGlobals.require); + } +}; + +module.exports = RequireHeaderDependency; diff --git a/node_modules/webpack/lib/dependencies/RequireIncludeDependency.js b/node_modules/webpack/lib/dependencies/RequireIncludeDependency.js new file mode 100644 index 00000000..3a25e84a --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireIncludeDependency.js @@ -0,0 +1,79 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const Template = require("../Template"); +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class RequireIncludeDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ + constructor(request, range) { + super(request); + + this.range = range; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + // This doesn't use any export + return Dependency.NO_EXPORTS_REFERENCED; + } + + get type() { + return "require.include"; + } + + get category() { + return "commonjs"; + } +} + +makeSerializable( + RequireIncludeDependency, + "webpack/lib/dependencies/RequireIncludeDependency" +); + +RequireIncludeDependency.Template = class RequireIncludeDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { runtimeTemplate }) { + const dep = /** @type {RequireIncludeDependency} */ (dependency); + const comment = runtimeTemplate.outputOptions.pathinfo + ? Template.toComment( + `require.include ${runtimeTemplate.requestShortener.shorten( + dep.request + )}` + ) + : ""; + + source.replace(dep.range[0], dep.range[1] - 1, `undefined${comment}`); + } +}; + +module.exports = RequireIncludeDependency; diff --git a/node_modules/webpack/lib/dependencies/RequireIncludeDependencyParserPlugin.js b/node_modules/webpack/lib/dependencies/RequireIncludeDependencyParserPlugin.js new file mode 100644 index 00000000..7b9de2c9 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireIncludeDependencyParserPlugin.js @@ -0,0 +1,101 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const WebpackError = require("../WebpackError"); +const { + evaluateToString, + toConstantDependency +} = require("../javascript/JavascriptParserHelpers"); +const makeSerializable = require("../util/makeSerializable"); +const RequireIncludeDependency = require("./RequireIncludeDependency"); + +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +module.exports = class RequireIncludeDependencyParserPlugin { + /** + * @param {boolean} warn true: warn about deprecation, false: don't warn + */ + constructor(warn) { + this.warn = warn; + } + + /** + * @param {JavascriptParser} parser the parser + * @returns {void} + */ + apply(parser) { + const { warn } = this; + parser.hooks.call + .for("require.include") + .tap("RequireIncludeDependencyParserPlugin", expr => { + if (expr.arguments.length !== 1) return; + const param = parser.evaluateExpression(expr.arguments[0]); + if (!param.isString()) return; + + if (warn) { + parser.state.module.addWarning( + new RequireIncludeDeprecationWarning( + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } + + const dep = new RequireIncludeDependency( + /** @type {string} */ (param.string), + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.current.addDependency(dep); + return true; + }); + parser.hooks.evaluateTypeof + .for("require.include") + .tap("RequireIncludePlugin", expr => { + if (warn) { + parser.state.module.addWarning( + new RequireIncludeDeprecationWarning( + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } + return evaluateToString("function")(expr); + }); + parser.hooks.typeof + .for("require.include") + .tap("RequireIncludePlugin", expr => { + if (warn) { + parser.state.module.addWarning( + new RequireIncludeDeprecationWarning( + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } + return toConstantDependency(parser, JSON.stringify("function"))(expr); + }); + } +}; + +class RequireIncludeDeprecationWarning extends WebpackError { + /** + * @param {DependencyLocation} loc location + */ + constructor(loc) { + super("require.include() is deprecated and will be removed soon."); + + this.name = "RequireIncludeDeprecationWarning"; + + this.loc = loc; + } +} + +makeSerializable( + RequireIncludeDeprecationWarning, + "webpack/lib/dependencies/RequireIncludeDependencyParserPlugin", + "RequireIncludeDeprecationWarning" +); diff --git a/node_modules/webpack/lib/dependencies/RequireIncludePlugin.js b/node_modules/webpack/lib/dependencies/RequireIncludePlugin.js new file mode 100644 index 00000000..af5bd021 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireIncludePlugin.js @@ -0,0 +1,62 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); +const RequireIncludeDependency = require("./RequireIncludeDependency"); +const RequireIncludeDependencyParserPlugin = require("./RequireIncludeDependencyParserPlugin"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ + +const PLUGIN_NAME = "RequireIncludePlugin"; + +class RequireIncludePlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { normalModuleFactory }) => { + compilation.dependencyFactories.set( + RequireIncludeDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + RequireIncludeDependency, + new RequireIncludeDependency.Template() + ); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + if (parserOptions.requireInclude === false) return; + const warn = parserOptions.requireInclude === undefined; + + new RequireIncludeDependencyParserPlugin(warn).apply(parser); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); + } + ); + } +} +module.exports = RequireIncludePlugin; diff --git a/node_modules/webpack/lib/dependencies/RequireResolveContextDependency.js b/node_modules/webpack/lib/dependencies/RequireResolveContextDependency.js new file mode 100644 index 00000000..dd82e922 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireResolveContextDependency.js @@ -0,0 +1,67 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const ContextDependency = require("./ContextDependency"); +const ContextDependencyTemplateAsId = require("./ContextDependencyTemplateAsId"); + +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("./ContextDependency").ContextDependencyOptions} ContextDependencyOptions */ + +class RequireResolveContextDependency extends ContextDependency { + /** + * @param {ContextDependencyOptions} options options + * @param {Range} range range + * @param {Range} valueRange value range + * @param {TODO} context context + */ + constructor(options, range, valueRange, context) { + super(options, context); + + this.range = range; + this.valueRange = valueRange; + } + + get type() { + return "amd require context"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.range); + write(this.valueRange); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.range = read(); + this.valueRange = read(); + + super.deserialize(context); + } +} + +makeSerializable( + RequireResolveContextDependency, + "webpack/lib/dependencies/RequireResolveContextDependency" +); + +RequireResolveContextDependency.Template = ContextDependencyTemplateAsId; + +module.exports = RequireResolveContextDependency; diff --git a/node_modules/webpack/lib/dependencies/RequireResolveDependency.js b/node_modules/webpack/lib/dependencies/RequireResolveDependency.js new file mode 100644 index 00000000..da0bd319 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireResolveDependency.js @@ -0,0 +1,58 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); +const ModuleDependencyAsId = require("./ModuleDependencyTemplateAsId"); + +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class RequireResolveDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + * @param {string} [context] context + */ + constructor(request, range, context) { + super(request); + + this.range = range; + this._context = context; + } + + get type() { + return "require.resolve"; + } + + get category() { + return "commonjs"; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + // This doesn't use any export + return Dependency.NO_EXPORTS_REFERENCED; + } +} + +makeSerializable( + RequireResolveDependency, + "webpack/lib/dependencies/RequireResolveDependency" +); + +RequireResolveDependency.Template = ModuleDependencyAsId; + +module.exports = RequireResolveDependency; diff --git a/node_modules/webpack/lib/dependencies/RequireResolveHeaderDependency.js b/node_modules/webpack/lib/dependencies/RequireResolveHeaderDependency.js new file mode 100644 index 00000000..2c9524c9 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RequireResolveHeaderDependency.js @@ -0,0 +1,81 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class RequireResolveHeaderDependency extends NullDependency { + /** + * @param {Range} range range + */ + constructor(range) { + super(); + + if (!Array.isArray(range)) throw new Error("range must be valid"); + + this.range = range; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.range); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + * @returns {RequireResolveHeaderDependency} RequireResolveHeaderDependency + */ + static deserialize(context) { + const obj = new RequireResolveHeaderDependency(context.read()); + obj.deserialize(context); + return obj; + } +} + +makeSerializable( + RequireResolveHeaderDependency, + "webpack/lib/dependencies/RequireResolveHeaderDependency" +); + +RequireResolveHeaderDependency.Template = class RequireResolveHeaderDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const dep = /** @type {RequireResolveHeaderDependency} */ (dependency); + source.replace(dep.range[0], dep.range[1] - 1, "/*require.resolve*/"); + } + + /** + * @param {string} name name + * @param {RequireResolveHeaderDependency} dep dependency + * @param {ReplaceSource} source source + */ + applyAsTemplateArgument(name, dep, source) { + source.replace(dep.range[0], dep.range[1] - 1, "/*require.resolve*/"); + } +}; + +module.exports = RequireResolveHeaderDependency; diff --git a/node_modules/webpack/lib/dependencies/RuntimeRequirementsDependency.js b/node_modules/webpack/lib/dependencies/RuntimeRequirementsDependency.js new file mode 100644 index 00000000..714567b7 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/RuntimeRequirementsDependency.js @@ -0,0 +1,85 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +class RuntimeRequirementsDependency extends NullDependency { + /** + * @param {string[]} runtimeRequirements runtime requirements + */ + constructor(runtimeRequirements) { + super(); + this.runtimeRequirements = new Set(runtimeRequirements); + this._hashUpdate = undefined; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + if (this._hashUpdate === undefined) { + this._hashUpdate = `${Array.from(this.runtimeRequirements).join()}`; + } + hash.update(this._hashUpdate); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.runtimeRequirements); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.runtimeRequirements = read(); + super.deserialize(context); + } +} + +makeSerializable( + RuntimeRequirementsDependency, + "webpack/lib/dependencies/RuntimeRequirementsDependency" +); + +RuntimeRequirementsDependency.Template = class RuntimeRequirementsDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { runtimeRequirements }) { + const dep = /** @type {RuntimeRequirementsDependency} */ (dependency); + for (const req of dep.runtimeRequirements) { + runtimeRequirements.add(req); + } + } +}; + +module.exports = RuntimeRequirementsDependency; diff --git a/node_modules/webpack/lib/dependencies/StaticExportsDependency.js b/node_modules/webpack/lib/dependencies/StaticExportsDependency.js new file mode 100644 index 00000000..d91b5e43 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/StaticExportsDependency.js @@ -0,0 +1,74 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency").ExportSpec} ExportSpec */ +/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ + +class StaticExportsDependency extends NullDependency { + /** + * @param {string[] | true} exports export names + * @param {boolean} canMangle true, if mangling exports names is allowed + */ + constructor(exports, canMangle) { + super(); + this.exports = exports; + this.canMangle = canMangle; + } + + get type() { + return "static exports"; + } + + /** + * Returns the exported names + * @param {ModuleGraph} moduleGraph module graph + * @returns {ExportsSpec | undefined} export names + */ + getExports(moduleGraph) { + return { + exports: this.exports, + canMangle: this.canMangle, + dependencies: undefined + }; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.exports); + write(this.canMangle); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.exports = read(); + this.canMangle = read(); + super.deserialize(context); + } +} + +makeSerializable( + StaticExportsDependency, + "webpack/lib/dependencies/StaticExportsDependency" +); + +module.exports = StaticExportsDependency; diff --git a/node_modules/webpack/lib/dependencies/SystemPlugin.js b/node_modules/webpack/lib/dependencies/SystemPlugin.js new file mode 100644 index 00000000..7eb1d141 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/SystemPlugin.js @@ -0,0 +1,167 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_DYNAMIC +} = require("../ModuleTypeConstants"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const WebpackError = require("../WebpackError"); +const { + evaluateToString, + expressionIsUnsupported, + toConstantDependency +} = require("../javascript/JavascriptParserHelpers"); +const makeSerializable = require("../util/makeSerializable"); +const ConstDependency = require("./ConstDependency"); +const SystemRuntimeModule = require("./SystemRuntimeModule"); + +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "SystemPlugin"; + +class SystemPlugin { + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { normalModuleFactory }) => { + compilation.hooks.runtimeRequirementInModule + .for(RuntimeGlobals.system) + .tap(PLUGIN_NAME, (module, set) => { + set.add(RuntimeGlobals.requireScope); + }); + + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.system) + .tap(PLUGIN_NAME, (chunk, set) => { + compilation.addRuntimeModule(chunk, new SystemRuntimeModule()); + }); + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const handler = (parser, parserOptions) => { + if (parserOptions.system === undefined || !parserOptions.system) { + return; + } + + /** + * @param {string} name name + */ + const setNotSupported = name => { + parser.hooks.evaluateTypeof + .for(name) + .tap(PLUGIN_NAME, evaluateToString("undefined")); + parser.hooks.expression + .for(name) + .tap( + PLUGIN_NAME, + expressionIsUnsupported( + parser, + `${name} is not supported by webpack.` + ) + ); + }; + + parser.hooks.typeof + .for("System.import") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("function")) + ); + parser.hooks.evaluateTypeof + .for("System.import") + .tap(PLUGIN_NAME, evaluateToString("function")); + parser.hooks.typeof + .for("System") + .tap( + PLUGIN_NAME, + toConstantDependency(parser, JSON.stringify("object")) + ); + parser.hooks.evaluateTypeof + .for("System") + .tap(PLUGIN_NAME, evaluateToString("object")); + + setNotSupported("System.set"); + setNotSupported("System.get"); + setNotSupported("System.register"); + + parser.hooks.expression.for("System").tap(PLUGIN_NAME, expr => { + const dep = new ConstDependency( + RuntimeGlobals.system, + /** @type {Range} */ (expr.range), + [RuntimeGlobals.system] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + return true; + }); + + parser.hooks.call.for("System.import").tap(PLUGIN_NAME, expr => { + parser.state.module.addWarning( + new SystemImportDeprecationWarning( + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + + return parser.hooks.importCall.call({ + type: "ImportExpression", + source: + /** @type {import("estree").Literal} */ + (expr.arguments[0]), + loc: expr.loc, + range: expr.range + }); + }); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, handler); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC) + .tap(PLUGIN_NAME, handler); + } + ); + } +} + +class SystemImportDeprecationWarning extends WebpackError { + /** + * @param {DependencyLocation} loc location + */ + constructor(loc) { + super( + "System.import() is deprecated and will be removed soon. Use import() instead.\n" + + "For more info visit https://webpack.js.org/guides/code-splitting/" + ); + + this.name = "SystemImportDeprecationWarning"; + + this.loc = loc; + } +} + +makeSerializable( + SystemImportDeprecationWarning, + "webpack/lib/dependencies/SystemPlugin", + "SystemImportDeprecationWarning" +); + +module.exports = SystemPlugin; +module.exports.SystemImportDeprecationWarning = SystemImportDeprecationWarning; diff --git a/node_modules/webpack/lib/dependencies/SystemRuntimeModule.js b/node_modules/webpack/lib/dependencies/SystemRuntimeModule.js new file mode 100644 index 00000000..a7c3fba7 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/SystemRuntimeModule.js @@ -0,0 +1,35 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Florent Cailhol @ooflorent +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); +const Template = require("../Template"); + +class SystemRuntimeModule extends RuntimeModule { + constructor() { + super("system"); + } + + /** + * @returns {string | null} runtime code + */ + generate() { + return Template.asString([ + `${RuntimeGlobals.system} = {`, + Template.indent([ + "import: function () {", + Template.indent( + "throw new Error('System.import cannot be used indirectly');" + ), + "}" + ]), + "};" + ]); + } +} + +module.exports = SystemRuntimeModule; diff --git a/node_modules/webpack/lib/dependencies/URLDependency.js b/node_modules/webpack/lib/dependencies/URLDependency.js new file mode 100644 index 00000000..0d5b0a58 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/URLDependency.js @@ -0,0 +1,170 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const RawDataUrlModule = require("../asset/RawDataUrlModule"); +const { + getDependencyUsedByExportsCondition +} = require("../optimize/InnerGraph"); +const makeSerializable = require("../util/makeSerializable"); +const memoize = require("../util/memoize"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../Dependency").GetConditionFn} GetConditionFn */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Module")} Module */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */ +/** @typedef {import("../ModuleGraphConnection").ConnectionState} ConnectionState */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +const getIgnoredRawDataUrlModule = memoize( + () => new RawDataUrlModule("data:,", "ignored-asset", "(ignored asset)") +); + +class URLDependency extends ModuleDependency { + /** + * @param {string} request request + * @param {Range} range range of the arguments of new URL( |> ... <| ) + * @param {Range} outerRange range of the full |> new URL(...) <| + * @param {boolean=} relative use relative urls instead of absolute with base uri + */ + constructor(request, range, outerRange, relative) { + super(request); + this.range = range; + this.outerRange = outerRange; + this.relative = relative || false; + /** @type {Set<string> | boolean | undefined} */ + this.usedByExports = undefined; + } + + get type() { + return "new URL()"; + } + + get category() { + return "url"; + } + + /** + * @param {ModuleGraph} moduleGraph module graph + * @returns {null | false | GetConditionFn} function to determine if the connection is active + */ + getCondition(moduleGraph) { + return getDependencyUsedByExportsCondition( + this, + this.usedByExports, + moduleGraph + ); + } + + /** + * @param {string} context context directory + * @returns {Module | null} a module + */ + createIgnoredModule(context) { + return getIgnoredRawDataUrlModule(); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.outerRange); + write(this.relative); + write(this.usedByExports); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.outerRange = read(); + this.relative = read(); + this.usedByExports = read(); + super.deserialize(context); + } +} + +URLDependency.Template = class URLDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const { + chunkGraph, + moduleGraph, + runtimeRequirements, + runtimeTemplate, + runtime + } = templateContext; + const dep = /** @type {URLDependency} */ (dependency); + const connection = moduleGraph.getConnection(dep); + // Skip rendering depending when dependency is conditional + if (connection && !connection.isTargetActive(runtime)) { + source.replace( + dep.outerRange[0], + dep.outerRange[1] - 1, + "/* unused asset import */ undefined" + ); + return; + } + + runtimeRequirements.add(RuntimeGlobals.require); + + if (dep.relative) { + runtimeRequirements.add(RuntimeGlobals.relativeUrl); + source.replace( + dep.outerRange[0], + dep.outerRange[1] - 1, + `/* asset import */ new ${ + RuntimeGlobals.relativeUrl + }(${runtimeTemplate.moduleRaw({ + chunkGraph, + module: moduleGraph.getModule(dep), + request: dep.request, + runtimeRequirements, + weak: false + })})` + ); + } else { + runtimeRequirements.add(RuntimeGlobals.baseURI); + + source.replace( + dep.range[0], + dep.range[1] - 1, + `/* asset import */ ${runtimeTemplate.moduleRaw({ + chunkGraph, + module: moduleGraph.getModule(dep), + request: dep.request, + runtimeRequirements, + weak: false + })}, ${RuntimeGlobals.baseURI}` + ); + } + } +}; + +makeSerializable(URLDependency, "webpack/lib/dependencies/URLDependency"); + +module.exports = URLDependency; diff --git a/node_modules/webpack/lib/dependencies/URLPlugin.js b/node_modules/webpack/lib/dependencies/URLPlugin.js new file mode 100644 index 00000000..abd345e8 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/URLPlugin.js @@ -0,0 +1,202 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const { pathToFileURL } = require("url"); +const CommentCompilationWarning = require("../CommentCompilationWarning"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); +const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression"); +const { approve } = require("../javascript/JavascriptParserHelpers"); +const InnerGraph = require("../optimize/InnerGraph"); +const ConstDependency = require("./ConstDependency"); +const URLDependency = require("./URLDependency"); + +/** @typedef {import("estree").NewExpression} NewExpressionNode */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../NormalModule")} NormalModule */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ + +const PLUGIN_NAME = "URLPlugin"; + +class URLPlugin { + /** + * @param {Compiler} compiler compiler + */ + apply(compiler) { + compiler.hooks.compilation.tap( + PLUGIN_NAME, + (compilation, { normalModuleFactory }) => { + compilation.dependencyFactories.set(URLDependency, normalModuleFactory); + compilation.dependencyTemplates.set( + URLDependency, + new URLDependency.Template() + ); + + /** + * @param {NormalModule} module module + * @returns {URL} file url + */ + const getUrl = module => pathToFileURL(module.resource); + + const isMetaUrl = (parser, arg) => { + const chain = parser.extractMemberExpressionChain(arg); + + if ( + chain.members.length !== 1 || + chain.object.type !== "MetaProperty" || + chain.object.meta.name !== "import" || + chain.object.property.name !== "meta" || + chain.members[0] !== "url" + ) + return false; + + return true; + }; + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const parserCallback = (parser, parserOptions) => { + if (parserOptions.url === false) return; + const relative = parserOptions.url === "relative"; + + /** + * @param {NewExpressionNode} expr expression + * @returns {undefined | string} request + */ + const getUrlRequest = expr => { + if (expr.arguments.length !== 2) return; + + const [arg1, arg2] = expr.arguments; + + if ( + arg2.type !== "MemberExpression" || + arg1.type === "SpreadElement" + ) + return; + + if (!isMetaUrl(parser, arg2)) return; + + return parser.evaluateExpression(arg1).asString(); + }; + + parser.hooks.canRename.for("URL").tap(PLUGIN_NAME, approve); + parser.hooks.evaluateNewExpression + .for("URL") + .tap(PLUGIN_NAME, expr => { + const request = getUrlRequest(expr); + if (!request) return; + const url = new URL(request, getUrl(parser.state.module)); + + return new BasicEvaluatedExpression() + .setString(url.toString()) + .setRange(/** @type {Range} */ (expr.range)); + }); + parser.hooks.new.for("URL").tap(PLUGIN_NAME, _expr => { + const expr = /** @type {NewExpressionNode} */ (_expr); + const { options: importOptions, errors: commentErrors } = + parser.parseCommentOptions(/** @type {Range} */ (expr.range)); + + if (commentErrors) { + for (const e of commentErrors) { + const { comment } = e; + parser.state.module.addWarning( + new CommentCompilationWarning( + `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`, + comment.loc + ) + ); + } + } + + if (importOptions && importOptions.webpackIgnore !== undefined) { + if (typeof importOptions.webpackIgnore !== "boolean") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + return; + } else if (importOptions.webpackIgnore) { + if (expr.arguments.length !== 2) return; + + const [, arg2] = expr.arguments; + + if ( + arg2.type !== "MemberExpression" || + !isMetaUrl(parser, arg2) + ) + return; + + const dep = new ConstDependency( + RuntimeGlobals.baseURI, + /** @type {Range} */ (arg2.range), + [RuntimeGlobals.baseURI] + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + + return true; + } + } + + const request = getUrlRequest(expr); + + if (!request) return; + + const [arg1, arg2] = expr.arguments; + const dep = new URLDependency( + request, + [ + /** @type {Range} */ (arg1.range)[0], + /** @type {Range} */ (arg2.range)[1] + ], + /** @type {Range} */ (expr.range), + relative + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.current.addDependency(dep); + InnerGraph.onUsage(parser.state, e => (dep.usedByExports = e)); + return true; + }); + parser.hooks.isPure.for("NewExpression").tap(PLUGIN_NAME, _expr => { + const expr = /** @type {NewExpressionNode} */ (_expr); + const { callee } = expr; + if (callee.type !== "Identifier") return; + const calleeInfo = parser.getFreeInfoFromVariable(callee.name); + if (!calleeInfo || calleeInfo.name !== "URL") return; + + const request = getUrlRequest(expr); + + if (request) return true; + }); + }; + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, parserCallback); + + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, parserCallback); + } + ); + } +} + +module.exports = URLPlugin; diff --git a/node_modules/webpack/lib/dependencies/UnsupportedDependency.js b/node_modules/webpack/lib/dependencies/UnsupportedDependency.js new file mode 100644 index 00000000..6796634c --- /dev/null +++ b/node_modules/webpack/lib/dependencies/UnsupportedDependency.js @@ -0,0 +1,82 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const NullDependency = require("./NullDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Dependency")} Dependency */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ + +class UnsupportedDependency extends NullDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ + constructor(request, range) { + super(); + + this.request = request; + this.range = range; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.request); + write(this.range); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.request = read(); + this.range = read(); + + super.deserialize(context); + } +} + +makeSerializable( + UnsupportedDependency, + "webpack/lib/dependencies/UnsupportedDependency" +); + +UnsupportedDependency.Template = class UnsupportedDependencyTemplate extends ( + NullDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { runtimeTemplate }) { + const dep = /** @type {UnsupportedDependency} */ (dependency); + + source.replace( + dep.range[0], + dep.range[1], + runtimeTemplate.missingModule({ + request: dep.request + }) + ); + } +}; + +module.exports = UnsupportedDependency; diff --git a/node_modules/webpack/lib/dependencies/WebAssemblyExportImportedDependency.js b/node_modules/webpack/lib/dependencies/WebAssemblyExportImportedDependency.js new file mode 100644 index 00000000..c2452ecd --- /dev/null +++ b/node_modules/webpack/lib/dependencies/WebAssemblyExportImportedDependency.js @@ -0,0 +1,93 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class WebAssemblyExportImportedDependency extends ModuleDependency { + /** + * @param {string} exportName export name + * @param {string} request request + * @param {string} name name + * @param {TODO} valueType value type + */ + constructor(exportName, request, name, valueType) { + super(request); + /** @type {string} */ + this.exportName = exportName; + /** @type {string} */ + this.name = name; + /** @type {string} */ + this.valueType = valueType; + } + + /** + * @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module + */ + couldAffectReferencingModule() { + return Dependency.TRANSITIVE; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + return [[this.name]]; + } + + get type() { + return "wasm export import"; + } + + get category() { + return "wasm"; + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.exportName); + write(this.name); + write(this.valueType); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.exportName = read(); + this.name = read(); + this.valueType = read(); + + super.deserialize(context); + } +} + +makeSerializable( + WebAssemblyExportImportedDependency, + "webpack/lib/dependencies/WebAssemblyExportImportedDependency" +); + +module.exports = WebAssemblyExportImportedDependency; diff --git a/node_modules/webpack/lib/dependencies/WebAssemblyImportDependency.js b/node_modules/webpack/lib/dependencies/WebAssemblyImportDependency.js new file mode 100644 index 00000000..de23f76f --- /dev/null +++ b/node_modules/webpack/lib/dependencies/WebAssemblyImportDependency.js @@ -0,0 +1,108 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const makeSerializable = require("../util/makeSerializable"); +const UnsupportedWebAssemblyFeatureError = require("../wasm-sync/UnsupportedWebAssemblyFeatureError"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("@webassemblyjs/ast").ModuleImportDescription} ModuleImportDescription */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../WebpackError")} WebpackError */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class WebAssemblyImportDependency extends ModuleDependency { + /** + * @param {string} request the request + * @param {string} name the imported name + * @param {ModuleImportDescription} description the WASM ast node + * @param {false | string} onlyDirectImport if only direct imports are allowed + */ + constructor(request, name, description, onlyDirectImport) { + super(request); + /** @type {string} */ + this.name = name; + /** @type {ModuleImportDescription} */ + this.description = description; + /** @type {false | string} */ + this.onlyDirectImport = onlyDirectImport; + } + + get type() { + return "wasm import"; + } + + get category() { + return "wasm"; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + return [[this.name]]; + } + + /** + * Returns errors + * @param {ModuleGraph} moduleGraph module graph + * @returns {WebpackError[] | null | undefined} errors + */ + getErrors(moduleGraph) { + const module = moduleGraph.getModule(this); + + if ( + this.onlyDirectImport && + module && + !module.type.startsWith("webassembly") + ) { + return [ + new UnsupportedWebAssemblyFeatureError( + `Import "${this.name}" from "${this.request}" with ${this.onlyDirectImport} can only be used for direct wasm to wasm dependencies` + ) + ]; + } + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + + write(this.name); + write(this.description); + write(this.onlyDirectImport); + + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + + this.name = read(); + this.description = read(); + this.onlyDirectImport = read(); + + super.deserialize(context); + } +} + +makeSerializable( + WebAssemblyImportDependency, + "webpack/lib/dependencies/WebAssemblyImportDependency" +); + +module.exports = WebAssemblyImportDependency; diff --git a/node_modules/webpack/lib/dependencies/WebpackIsIncludedDependency.js b/node_modules/webpack/lib/dependencies/WebpackIsIncludedDependency.js new file mode 100644 index 00000000..0b308734 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/WebpackIsIncludedDependency.js @@ -0,0 +1,85 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const Template = require("../Template"); +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../Compilation")} Compilation */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class WebpackIsIncludedDependency extends ModuleDependency { + /** + * @param {string} request the request string + * @param {Range} range location in source code + */ + constructor(request, range) { + super(request); + + this.weak = true; + this.range = range; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + // This doesn't use any export + return Dependency.NO_EXPORTS_REFERENCED; + } + + get type() { + return "__webpack_is_included__"; + } +} + +makeSerializable( + WebpackIsIncludedDependency, + "webpack/lib/dependencies/WebpackIsIncludedDependency" +); + +WebpackIsIncludedDependency.Template = class WebpackIsIncludedDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, { runtimeTemplate, chunkGraph, moduleGraph }) { + const dep = /** @type {WebpackIsIncludedDependency} */ (dependency); + const connection = moduleGraph.getConnection(dep); + const included = connection + ? chunkGraph.getNumberOfModuleChunks(connection.module) > 0 + : false; + const comment = runtimeTemplate.outputOptions.pathinfo + ? Template.toComment( + `__webpack_is_included__ ${runtimeTemplate.requestShortener.shorten( + dep.request + )}` + ) + : ""; + + source.replace( + dep.range[0], + dep.range[1] - 1, + `${comment}${JSON.stringify(included)}` + ); + } +}; + +module.exports = WebpackIsIncludedDependency; diff --git a/node_modules/webpack/lib/dependencies/WorkerDependency.js b/node_modules/webpack/lib/dependencies/WorkerDependency.js new file mode 100644 index 00000000..16693d1a --- /dev/null +++ b/node_modules/webpack/lib/dependencies/WorkerDependency.js @@ -0,0 +1,133 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Ivan Kopeykin @vankop +*/ + +"use strict"; + +const Dependency = require("../Dependency"); +const RuntimeGlobals = require("../RuntimeGlobals"); +const makeSerializable = require("../util/makeSerializable"); +const ModuleDependency = require("./ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("../AsyncDependenciesBlock")} AsyncDependenciesBlock */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */ +/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */ +/** @typedef {import("../DependencyTemplate").DependencyTemplateContext} DependencyTemplateContext */ +/** @typedef {import("../Entrypoint")} Entrypoint */ +/** @typedef {import("../ModuleGraph")} ModuleGraph */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */ +/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */ +/** @typedef {import("../util/Hash")} Hash */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +class WorkerDependency extends ModuleDependency { + /** + * @param {string} request request + * @param {Range} range range + * @param {object} workerDependencyOptions options + * @param {string=} workerDependencyOptions.publicPath public path for the worker + */ + constructor(request, range, workerDependencyOptions) { + super(request); + this.range = range; + // If options are updated, don't forget to update the hash and serialization functions + this.options = workerDependencyOptions; + /** Cache the hash */ + this._hashUpdate = undefined; + } + + /** + * Returns list of exports referenced by this dependency + * @param {ModuleGraph} moduleGraph module graph + * @param {RuntimeSpec} runtime the runtime for which the module is analysed + * @returns {(string[] | ReferencedExport)[]} referenced exports + */ + getReferencedExports(moduleGraph, runtime) { + return Dependency.NO_EXPORTS_REFERENCED; + } + + get type() { + return "new Worker()"; + } + + get category() { + return "worker"; + } + + /** + * Update the hash + * @param {Hash} hash hash to be updated + * @param {UpdateHashContext} context context + * @returns {void} + */ + updateHash(hash, context) { + if (this._hashUpdate === undefined) { + this._hashUpdate = JSON.stringify(this.options); + } + hash.update(this._hashUpdate); + } + + /** + * @param {ObjectSerializerContext} context context + */ + serialize(context) { + const { write } = context; + write(this.options); + super.serialize(context); + } + + /** + * @param {ObjectDeserializerContext} context context + */ + deserialize(context) { + const { read } = context; + this.options = read(); + super.deserialize(context); + } +} + +WorkerDependency.Template = class WorkerDependencyTemplate extends ( + ModuleDependency.Template +) { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {DependencyTemplateContext} templateContext the context object + * @returns {void} + */ + apply(dependency, source, templateContext) { + const { chunkGraph, moduleGraph, runtimeRequirements } = templateContext; + const dep = /** @type {WorkerDependency} */ (dependency); + const block = /** @type {AsyncDependenciesBlock} */ ( + moduleGraph.getParentBlock(dependency) + ); + const entrypoint = /** @type {Entrypoint} */ ( + chunkGraph.getBlockChunkGroup(block) + ); + const chunk = entrypoint.getEntrypointChunk(); + // We use the workerPublicPath option if provided, else we fallback to the RuntimeGlobal publicPath + const workerImportBaseUrl = dep.options.publicPath + ? `"${dep.options.publicPath}"` + : RuntimeGlobals.publicPath; + + runtimeRequirements.add(RuntimeGlobals.publicPath); + runtimeRequirements.add(RuntimeGlobals.baseURI); + runtimeRequirements.add(RuntimeGlobals.getChunkScriptFilename); + + source.replace( + dep.range[0], + dep.range[1] - 1, + `/* worker import */ ${workerImportBaseUrl} + ${ + RuntimeGlobals.getChunkScriptFilename + }(${JSON.stringify(chunk.id)}), ${RuntimeGlobals.baseURI}` + ); + } +}; + +makeSerializable(WorkerDependency, "webpack/lib/dependencies/WorkerDependency"); + +module.exports = WorkerDependency; diff --git a/node_modules/webpack/lib/dependencies/WorkerPlugin.js b/node_modules/webpack/lib/dependencies/WorkerPlugin.js new file mode 100644 index 00000000..aff03b84 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/WorkerPlugin.js @@ -0,0 +1,500 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { pathToFileURL } = require("url"); +const AsyncDependenciesBlock = require("../AsyncDependenciesBlock"); +const CommentCompilationWarning = require("../CommentCompilationWarning"); +const { + JAVASCRIPT_MODULE_TYPE_AUTO, + JAVASCRIPT_MODULE_TYPE_ESM +} = require("../ModuleTypeConstants"); +const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); +const EnableChunkLoadingPlugin = require("../javascript/EnableChunkLoadingPlugin"); +const { equals } = require("../util/ArrayHelpers"); +const createHash = require("../util/createHash"); +const { contextify } = require("../util/identifier"); +const EnableWasmLoadingPlugin = require("../wasm/EnableWasmLoadingPlugin"); +const ConstDependency = require("./ConstDependency"); +const CreateScriptUrlDependency = require("./CreateScriptUrlDependency"); +const { + harmonySpecifierTag +} = require("./HarmonyImportDependencyParserPlugin"); +const WorkerDependency = require("./WorkerDependency"); + +/** @typedef {import("estree").CallExpression} CallExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").ObjectExpression} ObjectExpression */ +/** @typedef {import("estree").Pattern} Pattern */ +/** @typedef {import("estree").Property} Property */ +/** @typedef {import("estree").SpreadElement} SpreadElement */ +/** @typedef {import("../../declarations/WebpackOptions").ChunkLoading} ChunkLoading */ +/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */ +/** @typedef {import("../../declarations/WebpackOptions").OutputModule} OutputModule */ +/** @typedef {import("../../declarations/WebpackOptions").WasmLoading} WasmLoading */ +/** @typedef {import("../../declarations/WebpackOptions").WorkerPublicPath} WorkerPublicPath */ +/** @typedef {import("../Compiler")} Compiler */ +/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ +/** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */ +/** @typedef {import("../NormalModule")} NormalModule */ +/** @typedef {import("../Parser").ParserState} ParserState */ +/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */ +/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */ +/** @typedef {import("../javascript/JavascriptParser")} Parser */ +/** @typedef {import("../javascript/JavascriptParser").Range} Range */ +/** @typedef {import("../util/createHash").Algorithm} Algorithm */ +/** @typedef {import("./HarmonyImportDependencyParserPlugin").HarmonySettings} HarmonySettings */ + +/** + * @param {NormalModule} module module + * @returns {string} url + */ +const getUrl = module => pathToFileURL(module.resource).toString(); + +const WorkerSpecifierTag = Symbol("worker specifier tag"); + +const DEFAULT_SYNTAX = [ + "Worker", + "SharedWorker", + "navigator.serviceWorker.register()", + "Worker from worker_threads" +]; + +/** @type {WeakMap<ParserState, number>} */ +const workerIndexMap = new WeakMap(); + +const PLUGIN_NAME = "WorkerPlugin"; + +class WorkerPlugin { + /** + * @param {ChunkLoading=} chunkLoading chunk loading + * @param {WasmLoading=} wasmLoading wasm loading + * @param {OutputModule=} module output module + * @param {WorkerPublicPath=} workerPublicPath worker public path + */ + constructor(chunkLoading, wasmLoading, module, workerPublicPath) { + this._chunkLoading = chunkLoading; + this._wasmLoading = wasmLoading; + this._module = module; + this._workerPublicPath = workerPublicPath; + } + + /** + * Apply the plugin + * @param {Compiler} compiler the compiler instance + * @returns {void} + */ + apply(compiler) { + if (this._chunkLoading) { + new EnableChunkLoadingPlugin(this._chunkLoading).apply(compiler); + } + if (this._wasmLoading) { + new EnableWasmLoadingPlugin(this._wasmLoading).apply(compiler); + } + const cachedContextify = contextify.bindContextCache( + compiler.context, + compiler.root + ); + compiler.hooks.thisCompilation.tap( + PLUGIN_NAME, + (compilation, { normalModuleFactory }) => { + compilation.dependencyFactories.set( + WorkerDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + WorkerDependency, + new WorkerDependency.Template() + ); + compilation.dependencyTemplates.set( + CreateScriptUrlDependency, + new CreateScriptUrlDependency.Template() + ); + + /** + * @param {JavascriptParser} parser the parser + * @param {Expression} expr expression + * @returns {[BasicEvaluatedExpression, [number, number]] | void} parsed + */ + const parseModuleUrl = (parser, expr) => { + if ( + expr.type !== "NewExpression" || + expr.callee.type === "Super" || + expr.arguments.length !== 2 + ) + return; + const [arg1, arg2] = expr.arguments; + if (arg1.type === "SpreadElement") return; + if (arg2.type === "SpreadElement") return; + const callee = parser.evaluateExpression(expr.callee); + if (!callee.isIdentifier() || callee.identifier !== "URL") return; + const arg2Value = parser.evaluateExpression(arg2); + if ( + !arg2Value.isString() || + !(/** @type {string} */ (arg2Value.string).startsWith("file://")) || + arg2Value.string !== getUrl(parser.state.module) + ) { + return; + } + const arg1Value = parser.evaluateExpression(arg1); + return [ + arg1Value, + [ + /** @type {Range} */ (arg1.range)[0], + /** @type {Range} */ (arg2.range)[1] + ] + ]; + }; + + /** + * @param {JavascriptParser} parser the parser + * @param {ObjectExpression} expr expression + * @returns {{ expressions: Record<string, Expression | Pattern>, otherElements: (Property | SpreadElement)[], values: Record<string, any>, spread: boolean, insertType: "comma" | "single", insertLocation: number }} parsed object + */ + const parseObjectExpression = (parser, expr) => { + /** @type {Record<string, any>} */ + const values = {}; + /** @type {Record<string, Expression | Pattern>} */ + const expressions = {}; + /** @type {(Property | SpreadElement)[]} */ + const otherElements = []; + let spread = false; + for (const prop of expr.properties) { + if (prop.type === "SpreadElement") { + spread = true; + } else if ( + prop.type === "Property" && + !prop.method && + !prop.computed && + prop.key.type === "Identifier" + ) { + expressions[prop.key.name] = prop.value; + if (!prop.shorthand && !prop.value.type.endsWith("Pattern")) { + const value = parser.evaluateExpression( + /** @type {Expression} */ (prop.value) + ); + if (value.isCompileTimeValue()) + values[prop.key.name] = value.asCompileTimeValue(); + } + } else { + otherElements.push(prop); + } + } + const insertType = expr.properties.length > 0 ? "comma" : "single"; + const insertLocation = /** @type {Range} */ ( + expr.properties[expr.properties.length - 1].range + )[1]; + return { + expressions, + otherElements, + values, + spread, + insertType, + insertLocation + }; + }; + + /** + * @param {Parser} parser parser parser + * @param {JavascriptParserOptions} parserOptions parserOptions + * @returns {void} + */ + const parserPlugin = (parser, parserOptions) => { + if (parserOptions.worker === false) return; + const options = !Array.isArray(parserOptions.worker) + ? ["..."] + : parserOptions.worker; + /** + * @param {CallExpression} expr expression + * @returns {boolean | void} true when handled + */ + const handleNewWorker = expr => { + if (expr.arguments.length === 0 || expr.arguments.length > 2) + return; + const [arg1, arg2] = expr.arguments; + if (arg1.type === "SpreadElement") return; + if (arg2 && arg2.type === "SpreadElement") return; + const parsedUrl = parseModuleUrl(parser, arg1); + if (!parsedUrl) return; + const [url, range] = parsedUrl; + if (!url.isString()) return; + const { + expressions, + otherElements, + values: options, + spread: hasSpreadInOptions, + insertType, + insertLocation + } = arg2 && arg2.type === "ObjectExpression" + ? parseObjectExpression(parser, arg2) + : { + /** @type {Record<string, Expression | Pattern>} */ + expressions: {}, + otherElements: [], + /** @type {Record<string, any>} */ + values: {}, + spread: false, + insertType: arg2 ? "spread" : "argument", + insertLocation: arg2 + ? /** @type {Range} */ (arg2.range) + : /** @type {Range} */ (arg1.range)[1] + }; + const { options: importOptions, errors: commentErrors } = + parser.parseCommentOptions(/** @type {Range} */ (expr.range)); + + if (commentErrors) { + for (const e of commentErrors) { + const { comment } = e; + parser.state.module.addWarning( + new CommentCompilationWarning( + `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`, + comment.loc + ) + ); + } + } + + /** @type {EntryOptions} */ + const entryOptions = {}; + + if (importOptions) { + if (importOptions.webpackIgnore !== undefined) { + if (typeof importOptions.webpackIgnore !== "boolean") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else if (importOptions.webpackIgnore) { + return false; + } + } + if (importOptions.webpackEntryOptions !== undefined) { + if ( + typeof importOptions.webpackEntryOptions !== "object" || + importOptions.webpackEntryOptions === null + ) { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackEntryOptions\` expected a object, but received: ${importOptions.webpackEntryOptions}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else { + Object.assign( + entryOptions, + importOptions.webpackEntryOptions + ); + } + } + if (importOptions.webpackChunkName !== undefined) { + if (typeof importOptions.webpackChunkName !== "string") { + parser.state.module.addWarning( + new UnsupportedFeatureWarning( + `\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`, + /** @type {DependencyLocation} */ (expr.loc) + ) + ); + } else { + entryOptions.name = importOptions.webpackChunkName; + } + } + } + + if ( + !Object.prototype.hasOwnProperty.call(entryOptions, "name") && + options && + typeof options.name === "string" + ) { + entryOptions.name = options.name; + } + + if (entryOptions.runtime === undefined) { + const i = workerIndexMap.get(parser.state) || 0; + workerIndexMap.set(parser.state, i + 1); + const name = `${cachedContextify( + parser.state.module.identifier() + )}|${i}`; + const hash = createHash( + /** @type {Algorithm} */ + (compilation.outputOptions.hashFunction) + ); + hash.update(name); + const digest = + /** @type {string} */ + (hash.digest(compilation.outputOptions.hashDigest)); + entryOptions.runtime = digest.slice( + 0, + compilation.outputOptions.hashDigestLength + ); + } + + const block = new AsyncDependenciesBlock({ + name: entryOptions.name, + entryOptions: { + chunkLoading: this._chunkLoading, + wasmLoading: this._wasmLoading, + ...entryOptions + } + }); + block.loc = expr.loc; + const dep = new WorkerDependency( + /** @type {string} */ (url.string), + range, + { + publicPath: this._workerPublicPath + } + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + block.addDependency(dep); + parser.state.module.addBlock(block); + + if (compilation.outputOptions.trustedTypes) { + const dep = new CreateScriptUrlDependency( + /** @type {Range} */ (expr.arguments[0].range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addDependency(dep); + } + + if (expressions.type) { + const expr = expressions.type; + if (options.type !== false) { + const dep = new ConstDependency( + this._module ? '"module"' : "undefined", + /** @type {Range} */ (expr.range) + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + /** @type {TODO} */ + (expressions).type = undefined; + } + } else if (insertType === "comma") { + if (this._module || hasSpreadInOptions) { + const dep = new ConstDependency( + `, type: ${this._module ? '"module"' : "undefined"}`, + insertLocation + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + } + } else if (insertType === "spread") { + const dep1 = new ConstDependency( + "Object.assign({}, ", + /** @type {Range} */ (insertLocation)[0] + ); + const dep2 = new ConstDependency( + `, { type: ${this._module ? '"module"' : "undefined"} })`, + /** @type {Range} */ (insertLocation)[1] + ); + dep1.loc = /** @type {DependencyLocation} */ (expr.loc); + dep2.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep1); + parser.state.module.addPresentationalDependency(dep2); + } else if (insertType === "argument" && this._module) { + const dep = new ConstDependency( + ', { type: "module" }', + insertLocation + ); + dep.loc = /** @type {DependencyLocation} */ (expr.loc); + parser.state.module.addPresentationalDependency(dep); + } + + parser.walkExpression(expr.callee); + for (const key of Object.keys(expressions)) { + if (expressions[key]) parser.walkExpression(expressions[key]); + } + for (const prop of otherElements) { + parser.walkProperty(prop); + } + if (insertType === "spread") { + parser.walkExpression(arg2); + } + + return true; + }; + /** + * @param {string} item item + */ + const processItem = item => { + if ( + item.startsWith("*") && + item.includes(".") && + item.endsWith("()") + ) { + const firstDot = item.indexOf("."); + const pattern = item.slice(1, firstDot); + const itemMembers = item.slice(firstDot + 1, -2); + + parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl, statement) => { + if (decl.id.type === "Identifier" && decl.id.name === pattern) { + parser.tagVariable(decl.id.name, WorkerSpecifierTag); + return true; + } + }); + parser.hooks.pattern.for(pattern).tap(PLUGIN_NAME, pattern => { + parser.tagVariable(pattern.name, WorkerSpecifierTag); + return true; + }); + parser.hooks.callMemberChain + .for(WorkerSpecifierTag) + .tap(PLUGIN_NAME, (expression, members) => { + if (itemMembers !== members.join(".")) { + return; + } + + return handleNewWorker(expression); + }); + } else if (item.endsWith("()")) { + parser.hooks.call + .for(item.slice(0, -2)) + .tap(PLUGIN_NAME, handleNewWorker); + } else { + const match = /^(.+?)(\(\))?\s+from\s+(.+)$/.exec(item); + if (match) { + const ids = match[1].split("."); + const call = match[2]; + const source = match[3]; + (call ? parser.hooks.call : parser.hooks.new) + .for(harmonySpecifierTag) + .tap(PLUGIN_NAME, expr => { + const settings = /** @type {HarmonySettings} */ ( + parser.currentTagData + ); + if ( + !settings || + settings.source !== source || + !equals(settings.ids, ids) + ) { + return; + } + return handleNewWorker(expr); + }); + } else { + parser.hooks.new.for(item).tap(PLUGIN_NAME, handleNewWorker); + } + } + }; + for (const item of options) { + if (item === "...") { + for (const itemFromDefault of DEFAULT_SYNTAX) { + processItem(itemFromDefault); + } + } else processItem(item); + } + }; + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_AUTO) + .tap(PLUGIN_NAME, parserPlugin); + normalModuleFactory.hooks.parser + .for(JAVASCRIPT_MODULE_TYPE_ESM) + .tap(PLUGIN_NAME, parserPlugin); + } + ); + } +} +module.exports = WorkerPlugin; diff --git a/node_modules/webpack/lib/dependencies/getFunctionExpression.js b/node_modules/webpack/lib/dependencies/getFunctionExpression.js new file mode 100644 index 00000000..f4495b50 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/getFunctionExpression.js @@ -0,0 +1,64 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +/** @typedef {import("estree").ArrowFunctionExpression} ArrowFunctionExpression */ +/** @typedef {import("estree").Expression} Expression */ +/** @typedef {import("estree").FunctionExpression} FunctionExpression */ +/** @typedef {import("estree").SpreadElement} SpreadElement */ + +/** + * @param {Expression | SpreadElement} expr expressions + * @returns {{fn: FunctionExpression | ArrowFunctionExpression, expressions: (Expression | SpreadElement)[], needThis: boolean | undefined } | undefined} function expression with additional information + */ +module.exports = expr => { + // <FunctionExpression> + if ( + expr.type === "FunctionExpression" || + expr.type === "ArrowFunctionExpression" + ) { + return { + fn: expr, + expressions: [], + needThis: false + }; + } + + // <FunctionExpression>.bind(<Expression>) + if ( + expr.type === "CallExpression" && + expr.callee.type === "MemberExpression" && + expr.callee.object.type === "FunctionExpression" && + expr.callee.property.type === "Identifier" && + expr.callee.property.name === "bind" && + expr.arguments.length === 1 + ) { + return { + fn: expr.callee.object, + expressions: [expr.arguments[0]], + needThis: undefined + }; + } + // (function(_this) {return <FunctionExpression>})(this) (Coffeescript) + if ( + expr.type === "CallExpression" && + expr.callee.type === "FunctionExpression" && + expr.callee.body.type === "BlockStatement" && + expr.arguments.length === 1 && + expr.arguments[0].type === "ThisExpression" && + expr.callee.body.body && + expr.callee.body.body.length === 1 && + expr.callee.body.body[0].type === "ReturnStatement" && + expr.callee.body.body[0].argument && + expr.callee.body.body[0].argument.type === "FunctionExpression" + ) { + return { + fn: expr.callee.body.body[0].argument, + expressions: [], + needThis: true + }; + } +}; diff --git a/node_modules/webpack/lib/dependencies/processExportInfo.js b/node_modules/webpack/lib/dependencies/processExportInfo.js new file mode 100644 index 00000000..9bafcae6 --- /dev/null +++ b/node_modules/webpack/lib/dependencies/processExportInfo.js @@ -0,0 +1,67 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ + +"use strict"; + +const { UsageState } = require("../ExportsInfo"); + +/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */ +/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */ + +/** @typedef {string[][]} ReferencedExports */ + +/** + * @param {RuntimeSpec} runtime the runtime + * @param {ReferencedExports} referencedExports list of referenced exports, will be added to + * @param {string[]} prefix export prefix + * @param {ExportInfo=} exportInfo the export info + * @param {boolean} defaultPointsToSelf when true, using default will reference itself + * @param {Set<ExportInfo>} alreadyVisited already visited export info (to handle circular reexports) + */ +const processExportInfo = ( + runtime, + referencedExports, + prefix, + exportInfo, + defaultPointsToSelf = false, + alreadyVisited = new Set() +) => { + if (!exportInfo) { + referencedExports.push(prefix); + return; + } + const used = exportInfo.getUsed(runtime); + if (used === UsageState.Unused) return; + if (alreadyVisited.has(exportInfo)) { + referencedExports.push(prefix); + return; + } + alreadyVisited.add(exportInfo); + if ( + used !== UsageState.OnlyPropertiesUsed || + !exportInfo.exportsInfo || + exportInfo.exportsInfo.otherExportsInfo.getUsed(runtime) !== + UsageState.Unused + ) { + alreadyVisited.delete(exportInfo); + referencedExports.push(prefix); + return; + } + const exportsInfo = exportInfo.exportsInfo; + for (const exportInfo of exportsInfo.orderedExports) { + processExportInfo( + runtime, + referencedExports, + defaultPointsToSelf && exportInfo.name === "default" + ? prefix + : prefix.concat(exportInfo.name), + exportInfo, + false, + alreadyVisited + ); + } + alreadyVisited.delete(exportInfo); +}; +module.exports = processExportInfo; |
