This commit is contained in:
lalBi94
2023-03-05 13:23:23 +01:00
commit 7bc56c09b5
14034 changed files with 1834369 additions and 0 deletions

View File

@@ -0,0 +1,221 @@
/*
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 */
/** @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, __webpack_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, __webpack_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, __webpack_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, __webpack_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 {
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";
}
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);
}
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);
}
localModuleVar(dependency) {
return (
dependency.localModule &&
dependency.localModule.used &&
dependency.localModule.variableName()
);
}
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;
}
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, texts.shift());
current = dependency.arrayRange[1];
}
if (dependency.objectRange) {
source.replace(current, dependency.objectRange[0] - 1, texts.shift());
current = dependency.objectRange[1];
} else if (dependency.functionRange) {
source.replace(current, dependency.functionRange[0] - 1, texts.shift());
current = dependency.functionRange[1];
}
source.replace(current, dependency.range[1] - 1, texts.shift());
if (texts.length > 0) throw new Error("Implementation error");
}
};
module.exports = AMDDefineDependency;

View File

@@ -0,0 +1,354 @@
/*
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");
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;
};
const isUnboundFunctionExpression = expr => {
if (expr.type === "FunctionExpression") return true;
if (expr.type === "ArrowFunctionExpression") return true;
return false;
};
const isCallable = expr => {
if (isUnboundFunctionExpression(expr)) return true;
if (isBoundFunctionExpression(expr)) return true;
return false;
};
class AMDDefineDependencyParserPlugin {
constructor(options) {
this.options = options;
}
apply(parser) {
parser.hooks.call
.for("define")
.tap(
"AMDDefineDependencyParserPlugin",
this.processCallDefine.bind(this, parser)
);
}
processArray(parser, expr, param, identifiers, namedModule) {
if (param.isArray()) {
param.items.forEach((param, idx) => {
if (
param.isString() &&
["require", "module", "exports"].includes(param.string)
)
identifiers[idx] = param.string;
const result = this.processItem(parser, expr, param, namedModule);
if (result === undefined) {
this.processContext(parser, expr, param);
}
});
return true;
} else if (param.isConstArray()) {
const deps = [];
param.array.forEach((request, idx) => {
let dep;
let localModule;
if (request === "require") {
identifiers[idx] = request;
dep = "__webpack_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 = expr.loc;
parser.state.module.addPresentationalDependency(dep);
} else {
dep = this.newRequireItemDependency(request);
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
}
deps.push(dep);
});
const dep = this.newRequireArrayDependency(deps, param.range);
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.module.addPresentationalDependency(dep);
return true;
}
}
processItem(parser, expr, param, namedModule) {
if (param.isConditional()) {
param.options.forEach(param => {
const result = this.processItem(parser, expr, param);
if (result === undefined) {
this.processContext(parser, expr, param);
}
});
return true;
} else if (param.isString()) {
let dep, localModule;
if (param.string === "require") {
dep = new ConstDependency("__webpack_require__", param.range, [
RuntimeGlobals.require
]);
} else if (param.string === "exports") {
dep = new ConstDependency("exports", param.range, [
RuntimeGlobals.exports
]);
} else if (param.string === "module") {
dep = new ConstDependency("module", param.range, [
RuntimeGlobals.module
]);
} else if (
(localModule = getLocalModule(parser.state, param.string, namedModule))
) {
localModule.flagUsed();
dep = new LocalModuleDependency(localModule, param.range, false);
} else {
dep = this.newRequireItemDependency(param.string, param.range);
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
return true;
}
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
}
}
processContext(parser, expr, param) {
const dep = ContextDependencyHelpers.create(
AMDRequireContextDependency,
param.range,
param,
expr,
this.options,
{
category: "amd"
},
parser
);
if (!dep) return;
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
return true;
}
processCallDefine(parser, expr) {
let array, fn, obj, 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 = expr.arguments[0];
}
break;
case 2:
if (expr.arguments[0].type === "Literal") {
namedModule = 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 = 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 = expr.arguments[1];
}
}
break;
case 3:
// define("…", […], f() {…})
namedModule = 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 = expr.arguments[2];
}
break;
default:
return;
}
DynamicExports.bailout(parser.state);
let fnParams = null;
let fnParamsOffset = 0;
if (fn) {
if (isUnboundFunctionExpression(fn)) {
fnParams = fn.params;
} else if (isBoundFunctionExpression(fn)) {
fnParams = fn.callee.object.params;
fnParamsOffset = fn.arguments.length - 1;
if (fnParamsOffset < 0) {
fnParamsOffset = 0;
}
}
}
let fnRenames = new Map();
if (array) {
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;
});
}
}
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 = 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;
parser.inScope(
fn.callee.object.params.filter(
i => !["require", "module", "exports"].includes(i.name)
),
() => {
for (const [name, varInfo] of fnRenames) {
parser.setVariable(name, varInfo);
}
parser.scope.inTry = inTry;
if (fn.callee.object.body.type === "BlockStatement") {
parser.detectMode(fn.callee.object.body.body);
const prev = parser.prevStatement;
parser.preWalkStatement(fn.callee.object.body);
parser.prevStatement = prev;
parser.walkStatement(fn.callee.object.body);
} else {
parser.walkExpression(fn.callee.object.body);
}
}
);
if (fn.arguments) {
parser.walkExpressions(fn.arguments);
}
} else if (fn || obj) {
parser.walkExpression(fn || obj);
}
const dep = this.newDefineDependency(
expr.range,
array ? array.range : null,
fn ? fn.range : null,
obj ? obj.range : null,
namedModule ? namedModule : null
);
dep.loc = expr.loc;
if (namedModule) {
dep.localModule = addLocalModule(parser.state, namedModule);
}
parser.state.module.addPresentationalDependency(dep);
return true;
}
newDefineDependency(
range,
arrayRange,
functionRange,
objectRange,
namedModule
) {
return new AMDDefineDependency(
range,
arrayRange,
functionRange,
objectRange,
namedModule
);
}
newRequireArrayDependency(depsArray, range) {
return new AMDRequireArrayDependency(depsArray, range);
}
newRequireItemDependency(request, range) {
return new AMDRequireItemDependency(request, range);
}
}
module.exports = AMDDefineDependencyParserPlugin;

216
node_modules/webpack/lib/dependencies/AMDPlugin.js generated vendored Normal file
View File

@@ -0,0 +1,216 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
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").ModuleOptionsNormalized} ModuleOptions */
/** @typedef {import("../Compiler")} Compiler */
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(
"AMDPlugin",
(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("AMDPlugin", (module, set) => {
set.add(RuntimeGlobals.require);
});
compilation.hooks.runtimeRequirementInModule
.for(RuntimeGlobals.amdOptions)
.tap("AMDPlugin", (module, set) => {
set.add(RuntimeGlobals.requireScope);
});
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.amdDefine)
.tap("AMDPlugin", (chunk, set) => {
compilation.addRuntimeModule(chunk, new AMDDefineRuntimeModule());
});
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.amdOptions)
.tap("AMDPlugin", (chunk, set) => {
compilation.addRuntimeModule(
chunk,
new AMDOptionsRuntimeModule(amdOptions)
);
});
const handler = (parser, parserOptions) => {
if (parserOptions.amd !== undefined && !parserOptions.amd) return;
const tapOptionsHooks = (optionExpr, rootName, getMembers) => {
parser.hooks.expression
.for(optionExpr)
.tap(
"AMDPlugin",
toConstantDependency(parser, RuntimeGlobals.amdOptions, [
RuntimeGlobals.amdOptions
])
);
parser.hooks.evaluateIdentifier
.for(optionExpr)
.tap(
"AMDPlugin",
evaluateToIdentifier(optionExpr, rootName, getMembers, true)
);
parser.hooks.evaluateTypeof
.for(optionExpr)
.tap("AMDPlugin", evaluateToString("object"));
parser.hooks.typeof
.for(optionExpr)
.tap(
"AMDPlugin",
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("AMDPlugin", expr => {
const dep = new ConstDependency(
RuntimeGlobals.amdDefine,
expr.range,
[RuntimeGlobals.amdDefine]
);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
});
parser.hooks.typeof
.for("define")
.tap(
"AMDPlugin",
toConstantDependency(parser, JSON.stringify("function"))
);
parser.hooks.evaluateTypeof
.for("define")
.tap("AMDPlugin", evaluateToString("function"));
parser.hooks.canRename.for("define").tap("AMDPlugin", approve);
parser.hooks.rename.for("define").tap("AMDPlugin", expr => {
const dep = new ConstDependency(
RuntimeGlobals.amdDefine,
expr.range,
[RuntimeGlobals.amdDefine]
);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return false;
});
parser.hooks.typeof
.for("require")
.tap(
"AMDPlugin",
toConstantDependency(parser, JSON.stringify("function"))
);
parser.hooks.evaluateTypeof
.for("require")
.tap("AMDPlugin", evaluateToString("function"));
};
normalModuleFactory.hooks.parser
.for("javascript/auto")
.tap("AMDPlugin", handler);
normalModuleFactory.hooks.parser
.for("javascript/dynamic")
.tap("AMDPlugin", handler);
}
);
}
}
module.exports = AMDPlugin;

View File

@@ -0,0 +1,99 @@
/*
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 */
class AMDRequireArrayDependency extends NullDependency {
constructor(depsArray, range) {
super();
this.depsArray = depsArray;
this.range = range;
}
get type() {
return "amd require array";
}
get category() {
return "amd";
}
serialize(context) {
const { write } = context;
write(this.depsArray);
write(this.range);
super.serialize(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);
}
getContent(dep, templateContext) {
const requires = dep.depsArray.map(dependency => {
return this.contentForDependency(dependency, templateContext);
});
return `[${requires.join(", ")}]`;
}
contentForDependency(
dep,
{ runtimeTemplate, moduleGraph, chunkGraph, runtimeRequirements }
) {
if (typeof dep === "string") {
return dep;
}
if (dep.localModule) {
return dep.localModule.variableName();
} else {
return runtimeTemplate.moduleExports({
module: moduleGraph.getModule(dep),
chunkGraph,
request: dep.request,
runtimeRequirements
});
}
}
};
module.exports = AMDRequireArrayDependency;

View File

@@ -0,0 +1,53 @@
/*
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");
class AMDRequireContextDependency extends ContextDependency {
constructor(options, range, valueRange) {
super(options);
this.range = range;
this.valueRange = valueRange;
}
get type() {
return "amd require context";
}
get category() {
return "amd";
}
serialize(context) {
const { write } = context;
write(this.range);
write(this.valueRange);
super.serialize(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;

View File

@@ -0,0 +1,22 @@
/*
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");
class AMDRequireDependenciesBlock extends AsyncDependenciesBlock {
constructor(loc, request) {
super(null, loc, request);
}
}
makeSerializable(
AMDRequireDependenciesBlock,
"webpack/lib/dependencies/AMDRequireDependenciesBlock"
);
module.exports = AMDRequireDependenciesBlock;

View File

@@ -0,0 +1,279 @@
/*
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");
class AMDRequireDependenciesBlockParserPlugin {
constructor(options) {
this.options = options;
}
processFunctionArgument(parser, expression) {
let bindThis = true;
const fnData = getFunctionExpression(expression);
if (fnData) {
parser.inScope(
fnData.fn.params.filter(i => {
return !["require", "module", "exports"].includes(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;
}
apply(parser) {
parser.hooks.call
.for("require")
.tap(
"AMDRequireDependenciesBlockParserPlugin",
this.processCallRequire.bind(this, parser)
);
}
processArray(parser, expr, param) {
if (param.isArray()) {
for (const p of param.items) {
const result = this.processItem(parser, expr, p);
if (result === undefined) {
this.processContext(parser, expr, p);
}
}
return true;
} else if (param.isConstArray()) {
const deps = [];
for (const request of param.array) {
let dep, localModule;
if (request === "require") {
dep = "__webpack_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 = expr.loc;
parser.state.module.addPresentationalDependency(dep);
} else {
dep = this.newRequireItemDependency(request);
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
}
deps.push(dep);
}
const dep = this.newRequireArrayDependency(deps, param.range);
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.module.addPresentationalDependency(dep);
return true;
}
}
processItem(parser, expr, param) {
if (param.isConditional()) {
for (const p of 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, localModule;
if (param.string === "require") {
dep = new ConstDependency("__webpack_require__", param.string, [
RuntimeGlobals.require
]);
} else if (param.string === "module") {
dep = new ConstDependency(
parser.state.module.buildInfo.moduleArgument,
param.range,
[RuntimeGlobals.module]
);
} else if (param.string === "exports") {
dep = new ConstDependency(
parser.state.module.buildInfo.exportsArgument,
param.range,
[RuntimeGlobals.exports]
);
} else if ((localModule = getLocalModule(parser.state, param.string))) {
localModule.flagUsed();
dep = new LocalModuleDependency(localModule, param.range, false);
} else {
dep = this.newRequireItemDependency(param.string, param.range);
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
return true;
}
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
}
}
processContext(parser, expr, param) {
const dep = ContextDependencyHelpers.create(
AMDRequireContextDependency,
param.range,
param,
expr,
this.options,
{
category: "amd"
},
parser
);
if (!dep) return;
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
return true;
}
processArrayForRequestString(param) {
if (param.isArray()) {
const result = param.items.map(item =>
this.processItemForRequestString(item)
);
if (result.every(Boolean)) return result.join(" ");
} else if (param.isConstArray()) {
return param.array.join(" ");
}
}
processItemForRequestString(param) {
if (param.isConditional()) {
const result = param.options.map(item =>
this.processItemForRequestString(item)
);
if (result.every(Boolean)) return result.join("|");
} else if (param.isString()) {
return param.string;
}
}
processCallRequire(parser, expr) {
let param;
let depBlock;
let dep;
let result;
const old = parser.state.current;
if (expr.arguments.length >= 1) {
param = parser.evaluateExpression(expr.arguments[0]);
depBlock = this.newRequireDependenciesBlock(
expr.loc,
this.processArrayForRequestString(param)
);
dep = this.newRequireDependency(
expr.range,
param.range,
expr.arguments.length > 1 ? expr.arguments[1].range : null,
expr.arguments.length > 2 ? expr.arguments[2].range : null
);
dep.loc = expr.loc;
depBlock.addDependency(dep);
parser.state.current = depBlock;
}
if (expr.arguments.length === 1) {
parser.inScope([], () => {
result = this.processArray(parser, expr, param);
});
parser.state.current = old;
if (!result) return;
parser.state.current.addBlock(depBlock);
return true;
}
if (expr.arguments.length === 2 || expr.arguments.length === 3) {
try {
parser.inScope([], () => {
result = this.processArray(parser, expr, param);
});
if (!result) {
const dep = new UnsupportedDependency("unsupported", expr.range);
old.addPresentationalDependency(dep);
if (parser.state.module) {
parser.state.module.addError(
new UnsupportedFeatureWarning(
"Cannot statically analyse 'require(…, …)' in line " +
expr.loc.start.line,
expr.loc
)
);
}
depBlock = null;
return true;
}
dep.functionBindThis = this.processFunctionArgument(
parser,
expr.arguments[1]
);
if (expr.arguments.length === 3) {
dep.errorCallbackBindThis = this.processFunctionArgument(
parser,
expr.arguments[2]
);
}
} finally {
parser.state.current = old;
if (depBlock) parser.state.current.addBlock(depBlock);
}
return true;
}
}
newRequireDependenciesBlock(loc, request) {
return new AMDRequireDependenciesBlock(loc, request);
}
newRequireDependency(
outerRange,
arrayRange,
functionRange,
errorCallbackRange
) {
return new AMDRequireDependency(
outerRange,
arrayRange,
functionRange,
errorCallbackRange
);
}
newRequireItemDependency(request, range) {
return new AMDRequireItemDependency(request, range);
}
newRequireArrayDependency(depsArray, range) {
return new AMDRequireArrayDependency(depsArray, range);
}
}
module.exports = AMDRequireDependenciesBlockParserPlugin;

View File

@@ -0,0 +1,174 @@
/*
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 */
class AMDRequireDependency extends NullDependency {
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";
}
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);
}
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, __webpack_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;

View File

@@ -0,0 +1,35 @@
/*
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");
class AMDRequireItemDependency extends ModuleDependency {
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;

View File

@@ -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} 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} runtime code
*/
generate() {
return Template.asString([
`${RuntimeGlobals.amdOptions} = ${JSON.stringify(this.options)};`
]);
}
}
exports.AMDDefineRuntimeModule = AMDDefineRuntimeModule;
exports.AMDOptionsRuntimeModule = AMDOptionsRuntimeModule;

View File

@@ -0,0 +1,106 @@
/*
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("../util/Hash")} Hash */
class CachedConstDependency extends NullDependency {
constructor(expression, range, identifier) {
super();
this.expression = expression;
this.range = range;
this.identifier = identifier;
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 = "" + this.identifier + this.range + this.expression;
hash.update(this._hashUpdate);
}
serialize(context) {
const { write } = context;
write(this.expression);
write(this.range);
write(this.identifier);
super.serialize(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;

View File

@@ -0,0 +1,49 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
exports.handleDependencyBase = (depBase, module, runtimeRequirements) => {
let base = undefined;
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];
};

View File

@@ -0,0 +1,374 @@
/*
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("../Module")} Module */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
const idsSymbol = Symbol("CommonJsExportRequireDependency.ids");
const EMPTY_OBJECT = {};
class CommonJsExportRequireDependency extends ModuleDependency {
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 moduleGraph.getMeta(this)[idsSymbol] || this.ids;
}
/**
* @param {ModuleGraph} moduleGraph the module graph
* @param {string[]} ids the imported ids
* @returns {void}
*/
setIds(moduleGraph, ids) {
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;
} else {
return [
{
name: ids,
canMangle: false
}
];
}
};
if (this.resultUsed) return getFullResult();
let exportsInfo = moduleGraph.getExportsInfo(
moduleGraph.getParentModule(this)
);
for (const name of this.names) {
const 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) {
const ids = this.getIds(moduleGraph);
if (this.names.length === 1) {
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
};
} else {
const from = moduleGraph.getConnection(this);
if (!from) return;
const reexportInfo = this.getStarReexports(
moduleGraph,
undefined,
from.module
);
if (reexportInfo) {
return {
exports: Array.from(reexportInfo.exports, name => {
return {
name,
from,
export: ids.concat(name),
canMangle: !(name in EMPTY_OBJECT) && false
};
}),
// TODO handle deep reexports
dependencies: [from.module]
};
} else {
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>}} information
*/
getStarReexports(
moduleGraph,
runtime,
importedModule = moduleGraph.getModule(this)
) {
let importedExportsInfo = moduleGraph.getExportsInfo(importedModule);
const ids = this.getIds(moduleGraph);
if (ids.length > 0)
importedExportsInfo = importedExportsInfo.getNestedExportsInfo(ids);
let exportsInfo = moduleGraph.getExportsInfo(
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 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 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 };
}
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);
}
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;

View File

@@ -0,0 +1,160 @@
/*
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 */
const EMPTY_OBJECT = {};
class CommonJsExportsDependency extends NullDependency {
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
};
}
serialize(context) {
const { write } = context;
write(this.range);
write(this.valueRange);
write(this.base);
write(this.names);
super.serialize(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],
dep.valueRange[0] - 1,
"__webpack_unused_export__ = ("
);
source.replace(dep.valueRange[1], dep.range[1] - 1, ")");
return;
}
source.replace(
dep.range[0],
dep.valueRange[0] - 1,
`Object.defineProperty(${base}${propertyAccess(
used.slice(0, -1)
)}, ${JSON.stringify(used[used.length - 1])}, (`
);
source.replace(dep.valueRange[1], dep.range[1] - 1, "))");
return;
}
}
};
module.exports = CommonJsExportsDependency;

View File

@@ -0,0 +1,335 @@
/*
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").Expression} ExpressionNode */
/** @typedef {import("../NormalModule")} NormalModule */
/** @typedef {import("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
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;
}
};
const isTruthyLiteral = expr => {
switch (expr.type) {
case "Literal":
return !!expr.value;
case "UnaryExpression":
if (expr.operator === "!") return isFalsyLiteral(expr.argument);
}
return false;
};
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 {ExpressionNode} 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 {
constructor(moduleGraph) {
this.moduleGraph = moduleGraph;
}
/**
* @param {JavascriptParser} parser the parser
*/
apply(parser) {
const enableStructuredExports = () => {
DynamicExports.enable(parser.state);
};
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);
}
}
};
const bailout = reason => {
DynamicExports.bailout(parser.state);
if (reason) bailoutHint(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 //
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(
expr.range,
null,
base,
members,
requireCall.argument.string,
requireCall.ids,
!parser.isStatementLevelExpression(expr)
);
dep.loc = expr.loc;
dep.optional = !!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(
expr.left.range,
null,
base,
remainingMembers
);
dep.loc = expr.loc;
parser.state.module.addDependency(dep);
parser.walkExpression(expr.right);
return true;
};
parser.hooks.assignMemberChain
.for("exports")
.tap("CommonJsExportsParserPlugin", (expr, members) => {
return 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 {import("estree").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(
expr.range,
expr.arguments[2].range,
`Object.defineProperty(${exportsArg.identifier})`,
[property]
);
dep.loc = expr.loc;
parser.state.module.addDependency(dep);
parser.walkExpression(expr.arguments[2]);
return true;
});
// Self reference //
const handleAccessExport = (expr, base, members, call = undefined) => {
if (HarmonyExports.isEnabled(parser.state)) return;
if (members.length === 0) {
bailout(`${base} is used directly at ${formatLocation(expr.loc)}`);
}
if (call && members.length === 1) {
bailoutHint(
`${base}${propertyAccess(
members
)}(...) prevents optimization as ${base} is passed as call context at ${formatLocation(
expr.loc
)}`
);
}
const dep = new CommonJsSelfReferenceDependency(
expr.range,
base,
members,
!!call
);
dep.loc = expr.loc;
parser.state.module.addDependency(dep);
if (call) {
parser.walkExpressions(call.arguments);
}
return true;
};
parser.hooks.callMemberChain
.for("exports")
.tap("CommonJsExportsParserPlugin", (expr, members) => {
return handleAccessExport(expr.callee, "exports", members, expr);
});
parser.hooks.expressionMemberChain
.for("exports")
.tap("CommonJsExportsParserPlugin", (expr, members) => {
return handleAccessExport(expr, "exports", members);
});
parser.hooks.expression
.for("exports")
.tap("CommonJsExportsParserPlugin", expr => {
return 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 => {
return 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 = expr.loc;
parser.state.module.addDependency(dep);
return true;
});
}
}
module.exports = CommonJsExportsParserPlugin;

View File

@@ -0,0 +1,136 @@
/*
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 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("../util/runtime").RuntimeSpec} RuntimeSpec */
class CommonJsFullRequireDependency extends ModuleDependency {
/**
* @param {string} request the request string
* @param {[number, number]} range location in source code
* @param {string[]} names accessed properties on module
*/
constructor(request, range, names) {
super(request);
this.range = range;
this.names = names;
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];
}
serialize(context) {
const { write } = context;
write(this.names);
write(this.call);
write(this.asiSafe);
super.serialize(context);
}
deserialize(context) {
const { read } = context;
this.names = 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
});
if (importedModule) {
const ids = dep.names;
const usedImported = moduleGraph
.getExportsInfo(importedModule)
.getUsedName(ids, runtime);
if (usedImported) {
const comment = equals(usedImported, ids)
? ""
: Template.toNormalComment(propertyAccess(ids)) + " ";
const access = `${comment}${propertyAccess(usedImported)}`;
requireExpr =
dep.asiSafe === true
? `(${requireExpr}${access})`
: `${requireExpr}${access}`;
}
}
source.replace(dep.range[0], dep.range[1] - 1, requireExpr);
}
};
makeSerializable(
CommonJsFullRequireDependency,
"webpack/lib/dependencies/CommonJsFullRequireDependency"
);
module.exports = CommonJsFullRequireDependency;

File diff suppressed because it is too large Load Diff

280
node_modules/webpack/lib/dependencies/CommonJsPlugin.js generated vendored Normal file
View File

@@ -0,0 +1,280 @@
/*
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 {
evaluateToIdentifier,
toConstantDependency
} = require("../javascript/JavascriptParserHelpers");
const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency");
class CommonJsPlugin {
apply(compiler) {
compiler.hooks.compilation.tap(
"CommonJsPlugin",
(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("CommonJsPlugin", (module, set) => {
set.add(RuntimeGlobals.module);
set.add(RuntimeGlobals.requireScope);
});
compilation.hooks.runtimeRequirementInModule
.for(RuntimeGlobals.nodeModuleDecorator)
.tap("CommonJsPlugin", (module, set) => {
set.add(RuntimeGlobals.module);
set.add(RuntimeGlobals.requireScope);
});
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.harmonyModuleDecorator)
.tap("CommonJsPlugin", (chunk, set) => {
compilation.addRuntimeModule(
chunk,
new HarmonyModuleDecoratorRuntimeModule()
);
});
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.nodeModuleDecorator)
.tap("CommonJsPlugin", (chunk, set) => {
compilation.addRuntimeModule(
chunk,
new NodeModuleDecoratorRuntimeModule()
);
});
const handler = (parser, parserOptions) => {
if (parserOptions.commonjs !== undefined && !parserOptions.commonjs)
return;
parser.hooks.typeof
.for("module")
.tap(
"CommonJsPlugin",
toConstantDependency(parser, JSON.stringify("object"))
);
parser.hooks.expression
.for("require.main")
.tap(
"CommonJsPlugin",
toConstantDependency(
parser,
`${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}]`,
[RuntimeGlobals.moduleCache, RuntimeGlobals.entryModuleId]
)
);
parser.hooks.expression
.for("module.loaded")
.tap("CommonJsPlugin", expr => {
parser.state.module.buildInfo.moduleConcatenationBailout =
"module.loaded";
const dep = new RuntimeRequirementsDependency([
RuntimeGlobals.moduleLoaded
]);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
});
parser.hooks.expression
.for("module.id")
.tap("CommonJsPlugin", expr => {
parser.state.module.buildInfo.moduleConcatenationBailout =
"module.id";
const dep = new RuntimeRequirementsDependency([
RuntimeGlobals.moduleId
]);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
});
parser.hooks.evaluateIdentifier.for("module.hot").tap(
"CommonJsPlugin",
evaluateToIdentifier("module.hot", "module", () => ["hot"], null)
);
new CommonJsImportsParserPlugin(parserOptions).apply(parser);
new CommonJsExportsParserPlugin(compilation.moduleGraph).apply(
parser
);
};
normalModuleFactory.hooks.parser
.for("javascript/auto")
.tap("CommonJsPlugin", handler);
normalModuleFactory.hooks.parser
.for("javascript/dynamic")
.tap("CommonJsPlugin", handler);
}
);
}
}
class HarmonyModuleDecoratorRuntimeModule extends RuntimeModule {
constructor() {
super("harmony module decorator");
}
/**
* @returns {string} runtime code
*/
generate() {
const { runtimeTemplate } = 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} runtime code
*/
generate() {
const { runtimeTemplate } = this.compilation;
return Template.asString([
`${RuntimeGlobals.nodeModuleDecorator} = ${runtimeTemplate.basicFunction(
"module",
[
"module.paths = [];",
"if (!module.children) module.children = [];",
"return module;"
]
)};`
]);
}
}
module.exports = CommonJsPlugin;

View File

@@ -0,0 +1,55 @@
/*
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");
class CommonJsRequireContextDependency extends ContextDependency {
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";
}
serialize(context) {
const { write } = context;
write(this.range);
write(this.valueRange);
write(this.inShorthand);
super.serialize(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;

View File

@@ -0,0 +1,35 @@
/*
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");
class CommonJsRequireDependency extends ModuleDependency {
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;

View File

@@ -0,0 +1,141 @@
/*
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("../util/runtime").RuntimeSpec} RuntimeSpec */
class CommonJsSelfReferenceDependency extends NullDependency {
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];
}
serialize(context) {
const { write } = context;
write(this.range);
write(this.base);
write(this.names);
write(this.call);
super.serialize(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);
let used;
if (dep.names.length === 0) {
used = dep.names;
} else {
used = 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 = undefined;
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;

View File

@@ -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 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("../util/Hash")} Hash */
class ConstDependency extends NullDependency {
/**
* @param {string} expression the expression
* @param {number|[number, number]} range the source range
* @param {string[]=} 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;
}
serialize(context) {
const { write } = context;
write(this.expression);
write(this.range);
write(this.runtimeRequirements);
super.serialize(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;

View File

@@ -0,0 +1,160 @@
/*
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 */
const getCriticalDependencyWarning = memoize(() =>
require("./CriticalDependencyWarning")
);
/** @typedef {ContextOptions & { request: string }} ContextDependencyOptions */
const regExpToString = r => (r ? 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 | 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;
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[]} 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;
}
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);
}
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;

View File

@@ -0,0 +1,245 @@
/*
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("../javascript/BasicEvaluatedExpression")} BasicEvaluatedExpression */
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
/** @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 => {
return str.replace(/[-[\]\\/{}()*+?.^$|]/g, "\\$&");
};
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: [number, number], valueRange: [number, number], ...args: any[]): ContextDependency }} ContextDependencyConstructor */
/**
* @param {ContextDependencyConstructor} Dep the Dependency class
* @param {[number, number]} 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
*/
exports.create = (
Dep,
range,
param,
expr,
options,
contextOptions,
parser,
...depArgs
) => {
if (param.isTemplateString()) {
let prefixRaw = param.quasis[0].string;
let postfixRaw =
param.quasis.length > 1
? param.quasis[param.quasis.length - 1].string
: "";
const valueRange = 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 = param.quasis.slice(1, param.quasis.length - 1);
const innerRegExp =
options.wrappedContextRegExp.source +
innerQuasis
.map(q => quoteMeta(q.string) + 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: options.wrappedContextRecursive,
regExp,
mode: "sync",
...contextOptions
},
range,
valueRange,
...depArgs
);
dep.loc = expr.loc;
const replaces = [];
param.parts.forEach((part, i) => {
if (i % 2 === 0) {
// Quasis or merged quasi
let range = part.range;
let value = part.string;
if (param.templateStringKind === "cooked") {
value = JSON.stringify(value);
value = value.slice(1, value.length - 1);
}
if (i === 0) {
// prefix
value = prefix;
range = [param.range[0], part.range[1]];
value =
(param.templateStringKind === "cooked" ? "`" : "String.raw`") +
value;
} else if (i === param.parts.length - 1) {
// postfix
value = postfix;
range = [part.range[0], 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
return;
}
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()))
) {
let prefixRaw =
param.prefix && param.prefix.isString() ? param.prefix.string : "";
let postfixRaw =
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 = param.range;
const { context, prefix } = splitContextFromPrefix(prefixRaw);
const {
path: postfix,
query,
fragment
} = parseResource(postfixRaw, parser);
const regExp = new RegExp(
`^${quoteMeta(prefix)}${options.wrappedContextRegExp.source}${quoteMeta(
postfix
)}$`
);
const dep = new Dep(
{
request: context + query + fragment,
recursive: options.wrappedContextRecursive,
regExp,
mode: "sync",
...contextOptions
},
range,
valueRange,
...depArgs
);
dep.loc = 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;
} else {
const dep = new Dep(
{
request: options.exprContextRequest,
recursive: options.exprContextRecursive,
regExp: /** @type {RegExp} */ (options.exprContextRegExp),
mode: "sync",
...contextOptions
},
range,
param.range,
...depArgs
);
dep.loc = expr.loc;
dep.critical =
options.exprContextCritical &&
"the request of a dependency is an expression";
parser.walkExpression(param.expression);
return dep;
}
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
class ContextElementDependency extends ModuleDependency {
/**
* @param {string} request request
* @param {string|undefined} userRequest user request
* @param {string} typePrefix type prefix
* @param {string} category category
* @param {string[][]=} referencedExports referenced exports
* @param {string=} context context
*/
constructor(
request,
userRequest,
typePrefix,
category,
referencedExports,
context
) {
super(request);
this.referencedExports = referencedExports;
this._typePrefix = typePrefix;
this._category = category;
this._context = context || undefined;
if (userRequest) {
this.userRequest = userRequest;
}
}
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;
}
serialize(context) {
const { write } = context;
write(this._typePrefix);
write(this._category);
write(this.referencedExports);
super.serialize(context);
}
deserialize(context) {
const { read } = context;
this._typePrefix = read();
this._category = read();
this.referencedExports = read();
super.deserialize(context);
}
}
makeSerializable(
ContextElementDependency,
"webpack/lib/dependencies/ContextElementDependency"
);
module.exports = ContextElementDependency;

View File

@@ -0,0 +1,66 @@
/*
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 */
class CreateScriptUrlDependency extends NullDependency {
/**
* @param {[number, number]} range range
*/
constructor(range) {
super();
this.range = range;
}
get type() {
return "create script url";
}
serialize(context) {
const { write } = context;
write(this.range);
super.serialize(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;

View File

@@ -0,0 +1,25 @@
/*
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 {
constructor(message) {
super();
this.name = "CriticalDependencyWarning";
this.message = "Critical dependency: " + message;
}
}
makeSerializable(
CriticalDependencyWarning,
"webpack/lib/dependencies/CriticalDependencyWarning"
);
module.exports = CriticalDependencyWarning;

View File

@@ -0,0 +1,85 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Ivan Kopeykin @vankop
*/
"use strict";
const makeSerializable = require("../util/makeSerializable");
const NullDependency = require("./NullDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
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";
}
/**
* Returns the exported names
* @param {ModuleGraph} moduleGraph module graph
* @returns {ExportsSpec | undefined} export names
*/
getExports(moduleGraph) {
const name = this.name;
return {
exports: [
{
name,
canMangle: true
}
],
dependencies: undefined
};
}
serialize(context) {
const { write } = context;
write(this.name);
write(this.value);
super.serialize(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, { cssExports }) {
const dep = /** @type {CssExportDependency} */ (dependency);
cssExports.set(dep.name, dep.value);
}
};
makeSerializable(
CssExportDependency,
"webpack/lib/dependencies/CssExportDependency"
);
module.exports = CssExportDependency;

View File

@@ -0,0 +1,75 @@
/*
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("../util/Hash")} Hash */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
class CssImportDependency extends ModuleDependency {
/**
* @param {string} request request
* @param {[number, number]} range range of the argument
* @param {string | undefined} supports list of supports conditions
* @param {string | undefined} media list of media conditions
*/
constructor(request, range, supports, media) {
super(request);
this.range = range;
this.supports = supports;
this.media = media;
}
get type() {
return "css @import";
}
get category() {
return "css-import";
}
/**
* @param {string} context context directory
* @returns {Module} a module
*/
createIgnoredModule(context) {
return null;
}
}
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;

View File

@@ -0,0 +1,119 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Ivan Kopeykin @vankop
*/
"use strict";
const makeSerializable = require("../util/makeSerializable");
const NullDependency = require("./NullDependency");
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
/** @typedef {import("../Dependency")} Dependency */
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
class CssLocalIdentifierDependency extends NullDependency {
/**
* @param {string} name name
* @param {[number, number]} 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";
}
/**
* Returns the exported names
* @param {ModuleGraph} moduleGraph module graph
* @returns {ExportsSpec | undefined} export names
*/
getExports(moduleGraph) {
const name = this.name;
return {
exports: [
{
name,
canMangle: true
}
],
dependencies: undefined
};
}
serialize(context) {
const { write } = context;
write(this.name);
write(this.range);
write(this.prefix);
super.serialize(context);
}
deserialize(context) {
const { read } = context;
this.name = read();
this.range = read();
this.prefix = read();
super.deserialize(context);
}
}
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, moduleGraph, chunkGraph, runtime, runtimeTemplate, cssExports }
) {
const dep = /** @type {CssLocalIdentifierDependency} */ (dependency);
const used = moduleGraph
.getExportInfo(module, dep.name)
.getUsedName(dep.name, runtime);
const moduleId = chunkGraph.getModuleId(module);
const identifier =
dep.prefix +
(runtimeTemplate.outputOptions.uniqueName
? runtimeTemplate.outputOptions.uniqueName + "-"
: "") +
(used ? moduleId + "-" + used : "-");
source.replace(
dep.range[0],
dep.range[1] - 1,
escapeCssIdentifier(identifier, dep.prefix)
);
if (used) cssExports.set(used, identifier);
}
};
makeSerializable(
CssLocalIdentifierDependency,
"webpack/lib/dependencies/CssLocalIdentifierDependency"
);
module.exports = CssLocalIdentifierDependency;

View File

@@ -0,0 +1,101 @@
/*
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("../util/runtime").RuntimeSpec} RuntimeSpec */
class CssSelfLocalIdentifierDependency extends CssLocalIdentifierDependency {
/**
* @param {string} name name
* @param {[number, number]} 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]];
}
serialize(context) {
const { write } = context;
write(this.declaredSet);
super.serialize(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;

View File

@@ -0,0 +1,132 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Ivan Kopeykin @vankop
*/
"use strict";
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("../util/Hash")} Hash */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
const getRawDataUrlModule = memoize(() => require("../asset/RawDataUrlModule"));
class CssUrlDependency extends ModuleDependency {
/**
* @param {string} request request
* @param {[number, number]} range range of the argument
* @param {string} cssFunctionKind kind of css function, e. g. url(), image()
*/
constructor(request, range, cssFunctionKind) {
super(request);
this.range = range;
this.cssFunctionKind = cssFunctionKind;
}
get type() {
return "css url()";
}
get category() {
return "url";
}
/**
* @param {string} context context directory
* @returns {Module} a module
*/
createIgnoredModule(context) {
const RawDataUrlModule = getRawDataUrlModule();
return new RawDataUrlModule("data:,", `ignored-asset`, `(ignored asset)`);
}
serialize(context) {
const { write } = context;
write(this.cssFunctionKind);
super.serialize(context);
}
deserialize(context) {
const { read } = context;
this.cssFunctionKind = read();
super.deserialize(context);
}
}
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}`)}"`;
} else {
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,
{ runtime, moduleGraph, runtimeTemplate, codeGenerationResults }
) {
const dep = /** @type {CssUrlDependency} */ (dependency);
source.replace(
dep.range[0],
dep.range[1] - 1,
`${dep.cssFunctionKind}(${cssEscapeString(
runtimeTemplate.assetUrl({
publicPath: "",
runtime,
module: moduleGraph.getModule(dep),
codeGenerationResults
})
)})`
);
}
};
makeSerializable(CssUrlDependency, "webpack/lib/dependencies/CssUrlDependency");
module.exports = CssUrlDependency;

View File

@@ -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 DelegatedSourceDependency extends ModuleDependency {
constructor(request) {
super(request);
}
get type() {
return "delegated source";
}
get category() {
return "esm";
}
}
makeSerializable(
DelegatedSourceDependency,
"webpack/lib/dependencies/DelegatedSourceDependency"
);
module.exports = DelegatedSourceDependency;

View File

@@ -0,0 +1,47 @@
/*
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");
class DllEntryDependency extends Dependency {
constructor(dependencies, name) {
super();
this.dependencies = dependencies;
this.name = name;
}
get type() {
return "dll entry";
}
serialize(context) {
const { write } = context;
write(this.dependencies);
write(this.name);
super.serialize(context);
}
deserialize(context) {
const { read } = context;
this.dependencies = read();
this.name = read();
super.deserialize(context);
}
}
makeSerializable(
DllEntryDependency,
"webpack/lib/dependencies/DllEntryDependency"
);
module.exports = DllEntryDependency;

View File

@@ -0,0 +1,69 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("../Parser").ParserState} ParserState */
/** @type {WeakMap<ParserState, boolean>} */
const parserStateExportsState = new WeakMap();
/**
* @param {ParserState} parserState parser state
* @returns {void}
*/
exports.bailout = parserState => {
const value = parserStateExportsState.get(parserState);
parserStateExportsState.set(parserState, false);
if (value === true) {
parserState.module.buildMeta.exportsType = undefined;
parserState.module.buildMeta.defaultObject = false;
}
};
/**
* @param {ParserState} parserState parser state
* @returns {void}
*/
exports.enable = parserState => {
const value = parserStateExportsState.get(parserState);
if (value === false) return;
parserStateExportsState.set(parserState, true);
if (value !== true) {
parserState.module.buildMeta.exportsType = "default";
parserState.module.buildMeta.defaultObject = "redirect";
}
};
/**
* @param {ParserState} parserState parser state
* @returns {void}
*/
exports.setFlagged = parserState => {
const value = parserStateExportsState.get(parserState);
if (value !== true) return;
const buildMeta = parserState.module.buildMeta;
if (buildMeta.exportsType === "dynamic") return;
buildMeta.exportsType = "flagged";
};
/**
* @param {ParserState} parserState parser state
* @returns {void}
*/
exports.setDynamic = parserState => {
const value = parserStateExportsState.get(parserState);
if (value !== true) return;
parserState.module.buildMeta.exportsType = "dynamic";
};
/**
* @param {ParserState} parserState parser state
* @returns {boolean} true, when enabled
*/
exports.isEnabled = parserState => {
const value = parserStateExportsState.get(parserState);
return value === true;
};

View File

@@ -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;

View File

@@ -0,0 +1,143 @@
/*
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("../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();
}
}
}
switch (property) {
case "canMangle": {
const exportsInfo = moduleGraph.getExportsInfo(module);
const exportInfo = exportsInfo.getExportInfo(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 undefined;
case UsageState.Unknown:
return null;
default:
throw new Error(`Unexpected UsageState ${state}`);
}
}
case "provideInfo":
return moduleGraph.getExportsInfo(module).isExportProvided(exportName);
}
return undefined;
};
class ExportsInfoDependency extends NullDependency {
constructor(range, exportName, property) {
super();
this.range = range;
this.exportName = exportName;
this.property = property;
}
serialize(context) {
const { write } = context;
write(this.range);
write(this.exportName);
write(this.property);
super.serialize(context);
}
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;

View File

@@ -0,0 +1,134 @@
/*
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("./HarmonyAcceptImportDependency")} HarmonyAcceptImportDependency */
class HarmonyAcceptDependency extends NullDependency {
/**
* @param {[number, number]} 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";
}
serialize(context) {
const { write } = context;
write(this.range);
write(this.dependencies);
write(this.hasCallback);
super.serialize(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;

View File

@@ -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 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 {
constructor(request) {
super(request, 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;

View File

@@ -0,0 +1,91 @@
/*
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 */
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); } }${
module.buildMeta.async ? ", 1" : ""
});`
)
);
}
}
};
module.exports = HarmonyCompatibilityDependency;

View File

@@ -0,0 +1,97 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const DynamicExports = require("./DynamicExports");
const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency");
const HarmonyExports = require("./HarmonyExports");
module.exports = class HarmonyDetectionParserPlugin {
constructor(options) {
const { topLevelAwait = false } = options || {};
this.topLevelAwait = topLevelAwait;
}
apply(parser) {
parser.hooks.program.tap("HarmonyDetectionParserPlugin", ast => {
const isStrictHarmony = parser.state.module.type === "javascript/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 enabled it)"
);
}
if (!HarmonyExports.isEnabled(parser.state)) {
throw new Error(
"Top-level-await is only supported in EcmaScript Modules"
);
}
module.buildMeta.async = true;
});
const skipInHarmony = () => {
if (HarmonyExports.isEnabled(parser.state)) {
return true;
}
};
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);
}
}
};

View File

@@ -0,0 +1,127 @@
/*
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 */
/**
* 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 {
constructor(request, sourceOrder, ids, name, range, assertions, operator) {
super(request, sourceOrder, ids, name, range, false, assertions);
this.operator = operator;
}
get type() {
return `evaluated X ${this.operator} harmony import specifier`;
}
serialize(context) {
super.serialize(context);
const { write } = context;
write(this.operator);
}
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(connection.module);
const ids = dep.getIds(moduleGraph);
let value;
const exportsType = connection.module.getExportsType(
moduleGraph,
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": {
if (ids[0] === "__esModule") {
value = ids.length === 1 || undefined;
} else {
value = 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;

View File

@@ -0,0 +1,185 @@
/*
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,
getAssertions
} = require("./HarmonyImportDependencyParserPlugin");
const HarmonyImportSideEffectDependency = require("./HarmonyImportSideEffectDependency");
const { HarmonyStarExportsList } = HarmonyExportImportedSpecifierDependency;
module.exports = class HarmonyExportDependencyParserPlugin {
constructor(options) {
this.exportPresenceMode =
options.reexportExportsPresence !== undefined
? ExportPresenceModes.fromUserOption(options.reexportExportsPresence)
: options.exportsPresence !== undefined
? ExportPresenceModes.fromUserOption(options.exportsPresence)
: options.strictExportPresence
? ExportPresenceModes.ERROR
: ExportPresenceModes.AUTO;
}
apply(parser) {
const { exportPresenceMode } = this;
parser.hooks.export.tap(
"HarmonyExportDependencyParserPlugin",
statement => {
const dep = new HarmonyExportHeaderDependency(
statement.declaration && statement.declaration.range,
statement.range
);
dep.loc = Object.create(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("", statement.range);
clearDep.loc = Object.create(statement.loc);
clearDep.loc.index = -1;
parser.state.module.addPresentationalDependency(clearDep);
const sideEffectDep = new HarmonyImportSideEffectDependency(
source,
parser.state.lastHarmonyImportOrder,
getAssertions(statement)
);
sideEffectDep.loc = Object.create(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 comments = parser.getComments([
statement.range[0],
expr.range[0]
]);
const dep = new HarmonyExportExpressionDependency(
expr.range,
statement.range,
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
? {
id: expr.id ? expr.id.name : undefined,
range: [
expr.range[0],
expr.params.length > 0
? expr.params[0].range[0]
: expr.body.range[0]
],
prefix: `${expr.async ? "async " : ""}function${
expr.generator ? "*" : ""
} `,
suffix: `(${expr.params.length > 0 ? "" : ") "}`
}
: undefined
);
dep.loc = Object.create(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);
let dep;
const harmonyNamedExports = (parser.state.harmonyNamedExports =
parser.state.harmonyNamedExports || new Set());
harmonyNamedExports.add(name);
InnerGraph.addVariableUsage(parser, id, name);
if (settings) {
dep = new HarmonyExportImportedSpecifierDependency(
settings.source,
settings.sourceOrder,
settings.ids,
name,
harmonyNamedExports,
null,
exportPresenceMode,
null,
settings.assertions
);
} else {
dep = new HarmonyExportSpecifierDependency(id, name);
}
dep.loc = Object.create(statement.loc);
dep.loc.index = idx;
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(
source,
parser.state.lastHarmonyImportOrder,
id ? [id] : [],
name,
harmonyNamedExports,
harmonyStarExports && harmonyStarExports.slice(),
exportPresenceMode,
harmonyStarExports
);
if (harmonyStarExports) {
harmonyStarExports.push(dep);
}
dep.loc = Object.create(statement.loc);
dep.loc.index = idx;
parser.state.current.addDependency(dep);
return true;
}
);
}
};

View File

@@ -0,0 +1,190 @@
/*
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 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 */
class HarmonyExportExpressionDependency extends NullDependency {
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;
}
serialize(context) {
const { write } = context;
write(this.range);
write(this.rangeStatement);
write(this.prefix);
write(this.declarationId);
super.serialize(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 {
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}[${JSON.stringify(
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;

View File

@@ -0,0 +1,65 @@
/*
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 */
class HarmonyExportHeaderDependency extends NullDependency {
constructor(range, rangeStatement) {
super();
this.range = range;
this.rangeStatement = rangeStatement;
}
get type() {
return "harmony export header";
}
serialize(context) {
const { write } = context;
write(this.range);
write(this.rangeStatement);
super.serialize(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;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
/*
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");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
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();
/**
* @typedef {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
);
}
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 {Context} context context
* @returns {string|Source} 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 */ ${JSON.stringify(
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;

View File

@@ -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 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 */
class HarmonyExportSpecifierDependency extends NullDependency {
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;
}
serialize(context) {
const { write } = context;
write(this.id);
write(this.name);
super.serialize(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;

Some files were not shown because too many files have changed in this diff Show More