mirror of https://github.com/webpack/webpack.git
add support for reexporting in CommonJS
and necessary refactoring + fixes for that
This commit is contained in:
parent
0090eb941c
commit
71cf7f4dc8
|
|
@ -490,6 +490,7 @@ class ContextModule extends Module {
|
|||
const fakeMap = Object.create(null);
|
||||
for (const module of sortedModules) {
|
||||
const exportsType = module.getExportsType(
|
||||
moduleGraph,
|
||||
this.options.namespaceObject === "strict"
|
||||
);
|
||||
const id = chunkGraph.getModuleId(module);
|
||||
|
|
|
|||
|
|
@ -425,9 +425,6 @@ class ExportsInfo {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
if (this._sideEffectsOnlyInfo.getUsed(runtime) !== UsageState.Unused) {
|
||||
return true;
|
||||
}
|
||||
for (const exportInfo of this._exports.values()) {
|
||||
if (exportInfo.getUsed(runtime) !== UsageState.Unused) {
|
||||
return true;
|
||||
|
|
@ -641,7 +638,10 @@ class ExportsInfo {
|
|||
getUsedName(name, runtime) {
|
||||
if (Array.isArray(name)) {
|
||||
// TODO improve this
|
||||
if (name.length === 0) return name;
|
||||
if (name.length === 0) {
|
||||
if (!this.isUsed(runtime)) return false;
|
||||
return name;
|
||||
}
|
||||
let info = this.getReadOnlyExportInfo(name[0]);
|
||||
const x = info.getUsedName(name[0], runtime);
|
||||
if (x === false) return false;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ const makeSerializable = require("./util/makeSerializable");
|
|||
* @property {string=} exportsArgument
|
||||
* @property {boolean=} strict
|
||||
* @property {string=} moduleConcatenationBailout
|
||||
* @property {("default" | "namespace" | "flagged")=} exportsType
|
||||
* @property {("default" | "namespace" | "flagged" | "dynamic")=} exportsType
|
||||
* @property {(false | "redirect" | "redirect-warn")=} defaultObject
|
||||
* @property {boolean=} strictHarmonyModule
|
||||
* @property {boolean=} async
|
||||
|
|
@ -263,6 +263,10 @@ class Module extends DependenciesBlock {
|
|||
).getUsedExports(this, undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @returns {(string | OptimizationBailoutFunction)[]} list
|
||||
*/
|
||||
get optimizationBailout() {
|
||||
return ModuleGraph.getModuleGraphForModule(
|
||||
this,
|
||||
|
|
@ -372,6 +376,7 @@ class Module extends DependenciesBlock {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleGraph} moduleGraph the module graph
|
||||
* @param {boolean} strict the importing module is strict
|
||||
* @returns {"namespace" | "default-only" | "default-with-named" | "dynamic"} export type
|
||||
* "namespace": Exports is already a namespace object. namespace = exports.
|
||||
|
|
@ -379,7 +384,7 @@ class Module extends DependenciesBlock {
|
|||
* "default-only": Provide a namespace object with only default export. namespace = { default: exports }
|
||||
* "default-with-named": Provide a namespace object with named and default export. namespace = { ...exports, default: exports }
|
||||
*/
|
||||
getExportsType(strict) {
|
||||
getExportsType(moduleGraph, strict) {
|
||||
switch (this.buildMeta && this.buildMeta.exportsType) {
|
||||
case "flagged":
|
||||
return strict ? "default-only" : "namespace";
|
||||
|
|
@ -393,6 +398,44 @@ class Module extends DependenciesBlock {
|
|||
default:
|
||||
return "default-only";
|
||||
}
|
||||
case "dynamic": {
|
||||
if (strict) return "default-only";
|
||||
// Try to figure out value of __esModule by following reexports
|
||||
const handleDefault = () => {
|
||||
switch (this.buildMeta.defaultObject) {
|
||||
case "redirect":
|
||||
case "redirect-warn":
|
||||
return "default-with-named";
|
||||
default:
|
||||
return "default-only";
|
||||
}
|
||||
};
|
||||
const exportInfo = moduleGraph.getExportInfo(this, "__esModule");
|
||||
if (exportInfo.provided === false) {
|
||||
return handleDefault();
|
||||
}
|
||||
const target = exportInfo.getTarget(moduleGraph);
|
||||
if (
|
||||
!target ||
|
||||
!target.export ||
|
||||
target.export.length !== 1 ||
|
||||
target.export[0] !== "__esModule"
|
||||
) {
|
||||
return "dynamic";
|
||||
}
|
||||
switch (
|
||||
target.module.buildMeta &&
|
||||
target.module.buildMeta.exportsType
|
||||
) {
|
||||
case "flagged":
|
||||
case "namespace":
|
||||
return "namespace";
|
||||
case "default":
|
||||
return handleDefault();
|
||||
default:
|
||||
return "dynamic";
|
||||
}
|
||||
}
|
||||
default:
|
||||
return strict ? "default-only" : "dynamic";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ exports.exports = "__webpack_exports__";
|
|||
exports.thisAsExports = "top-level-this-exports";
|
||||
|
||||
/**
|
||||
* top-level this need to be the exports object
|
||||
* runtime need to return the exports of the last entry module
|
||||
*/
|
||||
exports.returnExportsFromRuntime = "return-exports-from-runtime";
|
||||
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ class RuntimeTemplate {
|
|||
request,
|
||||
weak
|
||||
});
|
||||
const exportsType = module.getExportsType(strict);
|
||||
const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);
|
||||
switch (exportsType) {
|
||||
case "namespace":
|
||||
return this.moduleRaw({
|
||||
|
|
@ -461,7 +461,7 @@ class RuntimeTemplate {
|
|||
request,
|
||||
weak
|
||||
});
|
||||
const exportsType = module.getExportsType(strict);
|
||||
const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);
|
||||
let fakeType = 0;
|
||||
switch (exportsType) {
|
||||
case "namespace":
|
||||
|
|
@ -590,6 +590,7 @@ class RuntimeTemplate {
|
|||
const optDeclaration = update ? "" : "var ";
|
||||
|
||||
const exportsType = module.getExportsType(
|
||||
chunkGraph.moduleGraph,
|
||||
originModule.buildMeta.strictHarmonyModule
|
||||
);
|
||||
runtimeRequirements.add(RuntimeGlobals.require);
|
||||
|
|
@ -646,6 +647,7 @@ class RuntimeTemplate {
|
|||
exportName = exportName ? [exportName] : [];
|
||||
}
|
||||
const exportsType = module.getExportsType(
|
||||
moduleGraph,
|
||||
originModule.buildMeta.strictHarmonyModule
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -680,7 +680,13 @@ const applyOptimizationDefaults = (
|
|||
apply: compiler => {
|
||||
// Lazy load the Terser plugin
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
new TerserPlugin().apply(compiler);
|
||||
new TerserPlugin({
|
||||
terserOptions: {
|
||||
compress: {
|
||||
passes: 2
|
||||
}
|
||||
}
|
||||
}).apply(compiler);
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
};
|
||||
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
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")} Dependency */
|
||||
/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
|
||||
/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
|
||||
/** @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 = false;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "cjs export require";
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.getModule(this);
|
||||
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]
|
||||
};
|
||||
} 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.getModule(this);
|
||||
const reexportInfo = this.getStarReexports(moduleGraph, undefined, from);
|
||||
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]
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
exports: true,
|
||||
from: ids.length === 0 ? from : undefined,
|
||||
canMangle: false,
|
||||
dependencies: [from]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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.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.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
|
||||
});
|
||||
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;
|
||||
|
|
@ -6,9 +6,9 @@
|
|||
"use strict";
|
||||
|
||||
const InitFragment = require("../InitFragment");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const propertyAccess = require("../util/propertyAccess");
|
||||
const { handleDependencyBase } = require("./CommonJsDependencyHelpers");
|
||||
const NullDependency = require("./NullDependency");
|
||||
|
||||
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
||||
|
|
@ -94,42 +94,11 @@ CommonJsExportsDependency.Template = class CommonJsExportsDependencyTemplate ext
|
|||
.getExportsInfo(module)
|
||||
.getUsedName(dep.names, runtime);
|
||||
|
||||
let base = undefined;
|
||||
let type;
|
||||
switch (dep.base) {
|
||||
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 ${dep.base}`);
|
||||
}
|
||||
const [type, base] = handleDependencyBase(
|
||||
dep.base,
|
||||
module,
|
||||
runtimeRequirements
|
||||
);
|
||||
|
||||
switch (type) {
|
||||
case "expression":
|
||||
|
|
|
|||
|
|
@ -6,19 +6,21 @@
|
|||
"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 */
|
||||
|
||||
/** @type {WeakMap<NormalModule, boolean>} */
|
||||
const moduleExportsState = new WeakMap();
|
||||
|
||||
const getValueOfPropertyDescription = expr => {
|
||||
if (expr.type !== "ObjectExpression") return;
|
||||
for (const property of expr.properties) {
|
||||
|
|
@ -49,14 +51,43 @@ const isFalsyLiteral = expr => {
|
|||
return false;
|
||||
};
|
||||
|
||||
class CommonJsExportsParserPlugin {
|
||||
static bailout(module) {
|
||||
const value = moduleExportsState.get(module);
|
||||
moduleExportsState.set(module, false);
|
||||
if (value === true) {
|
||||
module.buildMeta.exportsType = undefined;
|
||||
module.buildMeta.defaultObject = 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -66,18 +97,24 @@ class CommonJsExportsParserPlugin {
|
|||
const enableStructuredExports = () => {
|
||||
DynamicExports.enable(parser.state);
|
||||
};
|
||||
const checkNamespace = (members, valueExpr) => {
|
||||
const checkNamespace = (topLevel, members, valueExpr) => {
|
||||
if (!DynamicExports.isEnabled(parser.state)) return;
|
||||
if (members.length > 0 && members[0] === "__esModule") {
|
||||
if (isTruthyLiteral(valueExpr)) {
|
||||
if (isTruthyLiteral(valueExpr) && topLevel) {
|
||||
DynamicExports.setFlagged(parser.state);
|
||||
} else {
|
||||
DynamicExports.bailout(parser.state);
|
||||
DynamicExports.setDynamic(parser.state);
|
||||
}
|
||||
}
|
||||
};
|
||||
const bailout = () => {
|
||||
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 //
|
||||
|
|
@ -89,60 +126,74 @@ class CommonJsExportsParserPlugin {
|
|||
.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) => {
|
||||
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||
enableStructuredExports();
|
||||
checkNamespace(members, expr.right);
|
||||
const dep = new CommonJsExportsDependency(
|
||||
expr.left.range,
|
||||
null,
|
||||
"exports",
|
||||
members
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
return handleAssignExport(expr, "exports", members);
|
||||
});
|
||||
parser.hooks.assignMemberChain
|
||||
.for("this")
|
||||
.tap("CommonJsExportsParserPlugin", (expr, members) => {
|
||||
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||
if (!parser.scope.topLevelScope) return;
|
||||
enableStructuredExports();
|
||||
checkNamespace(members, expr.right);
|
||||
const dep = new CommonJsExportsDependency(
|
||||
expr.left.range,
|
||||
null,
|
||||
"this",
|
||||
members
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
return handleAssignExport(expr, "this", members);
|
||||
});
|
||||
parser.hooks.assignMemberChain
|
||||
.for("module")
|
||||
.tap("CommonJsExportsParserPlugin", (expr, members) => {
|
||||
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||
if (members[0] !== "exports" || members.length <= 1) return;
|
||||
enableStructuredExports();
|
||||
checkNamespace(members, expr.right);
|
||||
const dep = new CommonJsExportsDependency(
|
||||
expr.left.range,
|
||||
null,
|
||||
"module.exports",
|
||||
members.slice(1)
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
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;
|
||||
|
|
@ -162,7 +213,11 @@ class CommonJsExportsParserPlugin {
|
|||
if (typeof property !== "string") return;
|
||||
enableStructuredExports();
|
||||
const descArg = expr.arguments[2];
|
||||
checkNamespace([property], getValueOfPropertyDescription(descArg));
|
||||
checkNamespace(
|
||||
parser.statementPath.length === 1,
|
||||
[property],
|
||||
getValueOfPropertyDescription(descArg)
|
||||
);
|
||||
const dep = new CommonJsExportsDependency(
|
||||
expr.range,
|
||||
expr.arguments[2].range,
|
||||
|
|
@ -177,44 +232,87 @@ class CommonJsExportsParserPlugin {
|
|||
});
|
||||
|
||||
// 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 as ${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 => {
|
||||
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||
bailout();
|
||||
const dep = new CommonJsSelfReferenceDependency(
|
||||
expr.range,
|
||||
"exports",
|
||||
[]
|
||||
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
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
});
|
||||
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 => {
|
||||
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||
bailout();
|
||||
const dep = new CommonJsSelfReferenceDependency(
|
||||
expr.range,
|
||||
"module.exports",
|
||||
[]
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
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 (HarmonyExports.isEnabled(parser.state)) return;
|
||||
if (!parser.scope.topLevelScope) return;
|
||||
bailout();
|
||||
const dep = new CommonJsSelfReferenceDependency(expr.range, "this", []);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
return handleAccessExport(expr, "this", []);
|
||||
});
|
||||
|
||||
// Bailouts //
|
||||
|
|
|
|||
|
|
@ -5,7 +5,10 @@
|
|||
|
||||
"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 */
|
||||
|
|
@ -40,7 +43,7 @@ class CommonJsFullRequireDependency extends ModuleDependency {
|
|||
const importedModule = moduleGraph.getModule(this);
|
||||
if (
|
||||
!importedModule ||
|
||||
importedModule.getExportsType(false) !== "namespace"
|
||||
importedModule.getExportsType(moduleGraph, false) !== "namespace"
|
||||
) {
|
||||
return [this.names.slice(0, -1)];
|
||||
}
|
||||
|
|
@ -96,29 +99,24 @@ CommonJsFullRequireDependency.Template = class CommonJsFullRequireDependencyTemp
|
|||
const dep = /** @type {CommonJsFullRequireDependency} */ (dependency);
|
||||
if (!dep.range) return;
|
||||
const importedModule = moduleGraph.getModule(dep);
|
||||
const exports = runtimeTemplate.moduleExports({
|
||||
let requireExpr = runtimeTemplate.moduleExports({
|
||||
module: importedModule,
|
||||
chunkGraph,
|
||||
request: dep.request,
|
||||
weak: dep.weak,
|
||||
runtimeRequirements
|
||||
});
|
||||
const exportExpr = runtimeTemplate.exportFromImport({
|
||||
moduleGraph,
|
||||
module: importedModule,
|
||||
request: dep.request,
|
||||
exportName: dep.names,
|
||||
originModule: module,
|
||||
asiSafe: dep.asiSafe,
|
||||
isCall: dep.call,
|
||||
callContext: undefined,
|
||||
defaultInterop: false,
|
||||
importVar: exports,
|
||||
initFragments,
|
||||
runtime,
|
||||
runtimeRequirements
|
||||
});
|
||||
source.replace(dep.range[0], dep.range[1] - 1, exportExpr);
|
||||
const ids = dep.names;
|
||||
const usedImported = moduleGraph
|
||||
.getExportsInfo(importedModule)
|
||||
.getUsedName(ids, runtime);
|
||||
if (usedImported) {
|
||||
const comment = equals(usedImported, ids)
|
||||
? ""
|
||||
: Template.toNormalComment(propertyAccess(ids)) + " ";
|
||||
requireExpr += `${comment}${propertyAccess(usedImported)}`;
|
||||
}
|
||||
source.replace(dep.range[0], dep.range[1] - 1, requireExpr);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ const {
|
|||
evaluateToIdentifier,
|
||||
toConstantDependency
|
||||
} = require("../javascript/JavascriptParserHelpers");
|
||||
const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency");
|
||||
|
||||
class CommonJsPlugin {
|
||||
constructor(options) {
|
||||
|
|
@ -99,6 +100,15 @@ class CommonJsPlugin {
|
|||
new CommonJsExportsDependency.Template()
|
||||
);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
CommonJsExportRequireDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
CommonJsExportRequireDependency,
|
||||
new CommonJsExportRequireDependency.Template()
|
||||
);
|
||||
|
||||
const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
|
|
@ -203,7 +213,9 @@ class CommonJsPlugin {
|
|||
);
|
||||
|
||||
new CommonJsImportsParserPlugin(options).apply(parser);
|
||||
new CommonJsExportsParserPlugin().apply(parser);
|
||||
new CommonJsExportsParserPlugin(compilation.moduleGraph).apply(
|
||||
parser
|
||||
);
|
||||
};
|
||||
|
||||
normalModuleFactory.hooks.parser
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { UsageState } = require("../ExportsInfo");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const { equals } = require("../util/ArrayHelpers");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const propertyAccess = require("../util/propertyAccess");
|
||||
const NullDependency = require("./NullDependency");
|
||||
|
|
@ -20,11 +20,12 @@ const NullDependency = require("./NullDependency");
|
|||
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
||||
|
||||
class CommonJsSelfReferenceDependency extends NullDependency {
|
||||
constructor(range, base, names) {
|
||||
constructor(range, base, names, call) {
|
||||
super();
|
||||
this.range = range;
|
||||
this.base = base;
|
||||
this.names = names;
|
||||
this.call = call;
|
||||
}
|
||||
|
||||
get type() {
|
||||
|
|
@ -49,7 +50,7 @@ class CommonJsSelfReferenceDependency extends NullDependency {
|
|||
* @returns {(string[] | ReferencedExport)[]} referenced exports
|
||||
*/
|
||||
getReferencedExports(moduleGraph, runtime) {
|
||||
return [this.names];
|
||||
return [this.call ? this.names.slice(0, -1) : this.names];
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
|
|
@ -57,6 +58,7 @@ class CommonJsSelfReferenceDependency extends NullDependency {
|
|||
write(this.range);
|
||||
write(this.base);
|
||||
write(this.names);
|
||||
write(this.call);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
|
|
@ -65,6 +67,7 @@ class CommonJsSelfReferenceDependency extends NullDependency {
|
|||
this.range = read();
|
||||
this.base = read();
|
||||
this.names = read();
|
||||
this.call = read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
|
@ -90,13 +93,6 @@ CommonJsSelfReferenceDependency.Template = class CommonJsSelfReferenceDependency
|
|||
let used;
|
||||
if (dep.names.length === 0) {
|
||||
used = dep.names;
|
||||
} else if (module.buildMeta && module.buildMeta.exportsType === "default") {
|
||||
const defaultInfo = moduleGraph.getExportInfo(module, "default");
|
||||
if (defaultInfo.getUsed(runtime) === UsageState.Used) {
|
||||
used = dep.names;
|
||||
} else {
|
||||
used = defaultInfo.exportsInfo.getUsedName(dep.names, runtime);
|
||||
}
|
||||
} else {
|
||||
used = moduleGraph.getExportsInfo(module).getUsedName(dep.names, runtime);
|
||||
}
|
||||
|
|
@ -124,7 +120,7 @@ CommonJsSelfReferenceDependency.Template = class CommonJsSelfReferenceDependency
|
|||
throw new Error(`Unsupported base ${dep.base}`);
|
||||
}
|
||||
|
||||
if (base === dep.base && used.join() === dep.names.join()) {
|
||||
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
|
||||
|
|
@ -135,7 +131,7 @@ CommonJsSelfReferenceDependency.Template = class CommonJsSelfReferenceDependency
|
|||
source.replace(
|
||||
dep.range[0],
|
||||
dep.range[1] - 1,
|
||||
`/* self exports access */ ${base}${propertyAccess(used)}`
|
||||
`${base}${propertyAccess(used)}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -44,7 +44,19 @@ exports.enable = parserState => {
|
|||
exports.setFlagged = parserState => {
|
||||
const value = parserStateExportsState.get(parserState);
|
||||
if (value !== true) return;
|
||||
parserState.module.buildMeta.exportsType = "flagged";
|
||||
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";
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { UsageState } = require("../ExportsInfo");
|
||||
const InitFragment = require("../InitFragment");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
|
|
@ -45,9 +46,11 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
|
|||
runtime
|
||||
}
|
||||
) {
|
||||
// TODO avoid getUsedExports
|
||||
const usedExports = moduleGraph.getUsedExports(module, runtime);
|
||||
if (usedExports === true || usedExports === null) {
|
||||
const exportsInfo = moduleGraph.getExportsInfo(module);
|
||||
if (
|
||||
exportsInfo.getReadOnlyExportInfo("__esModule").getUsed(runtime) !==
|
||||
UsageState.Unused
|
||||
) {
|
||||
const content = runtimeTemplate.defineEsModuleFlagStatement({
|
||||
exportsArgument: module.exportsArgument,
|
||||
runtimeRequirements
|
||||
|
|
@ -63,17 +66,15 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
|
|||
}
|
||||
if (moduleGraph.isAsync(module)) {
|
||||
runtimeRequirements.add(RuntimeGlobals.module);
|
||||
if (usedExports !== false)
|
||||
runtimeRequirements.add(RuntimeGlobals.exports);
|
||||
const used = exportsInfo.isUsed(runtime);
|
||||
if (used) runtimeRequirements.add(RuntimeGlobals.exports);
|
||||
initFragments.push(
|
||||
new InitFragment(
|
||||
`${module.moduleArgument}.exports = (async () => {\n`,
|
||||
InitFragment.STAGE_ASYNC_BOUNDARY,
|
||||
0,
|
||||
undefined,
|
||||
usedExports !== false
|
||||
? `\nreturn ${module.exportsArgument};\n})();`
|
||||
: "\n})();"
|
||||
used ? `\nreturn ${module.exportsArgument};\n})();` : "\n})();"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ const makeSerializable = require("../util/makeSerializable");
|
|||
const propertyAccess = require("../util/propertyAccess");
|
||||
const HarmonyExportInitFragment = require("./HarmonyExportInitFragment");
|
||||
const HarmonyImportDependency = require("./HarmonyImportDependency");
|
||||
const processExportInfo = require("./processExportInfo");
|
||||
|
||||
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
|
||||
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
||||
|
|
@ -37,54 +38,6 @@ const HarmonyImportDependency = require("./HarmonyImportDependency");
|
|||
|
||||
const idsSymbol = Symbol("HarmonyExportImportedSpecifierDependency.ids");
|
||||
|
||||
/**
|
||||
* @param {RuntimeSpec} runtime the runtime
|
||||
* @param {string[][]} referencedExports list of referenced exports, will be added to
|
||||
* @param {string[]} prefix export prefix
|
||||
* @param {ExportInfo=} exportInfo the export info
|
||||
* @param {boolean} defaultPointsToSelf when true, using default will reference itself
|
||||
* @param {Set<ExportInfo>} alreadyVisited already visited export info (to handle circular reexports)
|
||||
*/
|
||||
const processExportInfo = (
|
||||
runtime,
|
||||
referencedExports,
|
||||
prefix,
|
||||
exportInfo,
|
||||
defaultPointsToSelf = false,
|
||||
alreadyVisited = new Set()
|
||||
) => {
|
||||
if (!exportInfo) {
|
||||
referencedExports.push(prefix);
|
||||
return;
|
||||
}
|
||||
if (alreadyVisited.has(exportInfo)) return;
|
||||
alreadyVisited.add(exportInfo);
|
||||
const used = exportInfo.getUsed(runtime);
|
||||
if (used === UsageState.Unused) return;
|
||||
if (
|
||||
used !== UsageState.OnlyPropertiesUsed ||
|
||||
!exportInfo.exportsInfo ||
|
||||
exportInfo.exportsInfo.otherExportsInfo.getUsed(runtime) !==
|
||||
UsageState.Unused
|
||||
) {
|
||||
referencedExports.push(prefix);
|
||||
return;
|
||||
}
|
||||
const exportsInfo = exportInfo.exportsInfo;
|
||||
for (const exportInfo of exportsInfo.orderedExports) {
|
||||
processExportInfo(
|
||||
runtime,
|
||||
referencedExports,
|
||||
defaultPointsToSelf && exportInfo.name === "default"
|
||||
? prefix
|
||||
: prefix.concat(exportInfo.name),
|
||||
exportInfo,
|
||||
false,
|
||||
alreadyVisited
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
class NormalReexportItem {
|
||||
/**
|
||||
* @param {string} name export name
|
||||
|
|
@ -229,6 +182,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
}
|
||||
|
||||
const importedExportsType = importedModule.getExportsType(
|
||||
moduleGraph,
|
||||
parentModule.buildMeta.strictHarmonyModule
|
||||
);
|
||||
|
||||
|
|
@ -403,7 +357,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
if (exportInfo.getUsed(runtime) === UsageState.Unused) continue;
|
||||
exports.add(name);
|
||||
if (importedExportInfo.provided === true) continue;
|
||||
checked.add(exportInfo.name);
|
||||
checked.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ class HarmonyImportDependency extends ModuleDependency {
|
|||
|
||||
const parentModule = moduleGraph.getParentModule(this);
|
||||
const exportsType = importedModule.getExportsType(
|
||||
moduleGraph,
|
||||
parentModule.buildMeta.strictHarmonyModule
|
||||
);
|
||||
switch (exportsType) {
|
||||
|
|
@ -199,16 +200,18 @@ class HarmonyImportDependency extends ModuleDependency {
|
|||
*/
|
||||
updateHash(hash, context) {
|
||||
const { chunkGraph } = context;
|
||||
const { moduleGraph } = chunkGraph;
|
||||
super.updateHash(hash, context);
|
||||
const importedModule = chunkGraph.moduleGraph.getModule(this);
|
||||
const importedModule = moduleGraph.getModule(this);
|
||||
if (importedModule) {
|
||||
const parentModule = chunkGraph.moduleGraph.getParentModule(this);
|
||||
const parentModule = moduleGraph.getParentModule(this);
|
||||
hash.update(
|
||||
importedModule.getExportsType(
|
||||
moduleGraph,
|
||||
parentModule.buildMeta && parentModule.buildMeta.strictHarmonyModule
|
||||
)
|
||||
);
|
||||
if (chunkGraph.moduleGraph.isAsync(importedModule)) hash.update("async");
|
||||
if (moduleGraph.isAsync(importedModule)) hash.update("async");
|
||||
}
|
||||
hash.update(`${this.sourceOrder}`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,10 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|||
const selfModule = moduleGraph.getParentModule(this);
|
||||
const importedModule = moduleGraph.getModule(this);
|
||||
switch (
|
||||
importedModule.getExportsType(selfModule.buildMeta.strictHarmonyModule)
|
||||
importedModule.getExportsType(
|
||||
moduleGraph,
|
||||
selfModule.buildMeta.strictHarmonyModule
|
||||
)
|
||||
) {
|
||||
case "default-only":
|
||||
case "default-with-named":
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { UsageState } = require("../ExportsInfo");
|
||||
|
||||
/** @typedef {import("../ExportsInfo").ExportInfo} ExportInfo */
|
||||
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
||||
|
||||
/**
|
||||
* @param {RuntimeSpec} runtime the runtime
|
||||
* @param {string[][]} referencedExports list of referenced exports, will be added to
|
||||
* @param {string[]} prefix export prefix
|
||||
* @param {ExportInfo=} exportInfo the export info
|
||||
* @param {boolean} defaultPointsToSelf when true, using default will reference itself
|
||||
* @param {Set<ExportInfo>} alreadyVisited already visited export info (to handle circular reexports)
|
||||
*/
|
||||
const processExportInfo = (
|
||||
runtime,
|
||||
referencedExports,
|
||||
prefix,
|
||||
exportInfo,
|
||||
defaultPointsToSelf = false,
|
||||
alreadyVisited = new Set()
|
||||
) => {
|
||||
if (!exportInfo) {
|
||||
referencedExports.push(prefix);
|
||||
return;
|
||||
}
|
||||
const used = exportInfo.getUsed(runtime);
|
||||
if (used === UsageState.Unused) return;
|
||||
if (alreadyVisited.has(exportInfo)) {
|
||||
referencedExports.push(prefix);
|
||||
return;
|
||||
}
|
||||
alreadyVisited.add(exportInfo);
|
||||
if (
|
||||
used !== UsageState.OnlyPropertiesUsed ||
|
||||
!exportInfo.exportsInfo ||
|
||||
exportInfo.exportsInfo.otherExportsInfo.getUsed(runtime) !==
|
||||
UsageState.Unused
|
||||
) {
|
||||
alreadyVisited.delete(exportInfo);
|
||||
referencedExports.push(prefix);
|
||||
return;
|
||||
}
|
||||
const exportsInfo = exportInfo.exportsInfo;
|
||||
for (const exportInfo of exportsInfo.orderedExports) {
|
||||
processExportInfo(
|
||||
runtime,
|
||||
referencedExports,
|
||||
defaultPointsToSelf && exportInfo.name === "default"
|
||||
? prefix
|
||||
: prefix.concat(exportInfo.name),
|
||||
exportInfo,
|
||||
false,
|
||||
alreadyVisited
|
||||
);
|
||||
}
|
||||
alreadyVisited.delete(exportInfo);
|
||||
};
|
||||
module.exports = processExportInfo;
|
||||
|
|
@ -17,6 +17,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|||
/** @typedef {import("estree").ArrayExpression} ArrayExpressionNode */
|
||||
/** @typedef {import("estree").BinaryExpression} BinaryExpressionNode */
|
||||
/** @typedef {import("estree").BlockStatement} BlockStatementNode */
|
||||
/** @typedef {import("estree").SequenceExpression} SequenceExpressionNode */
|
||||
/** @typedef {import("estree").CallExpression} CallExpressionNode */
|
||||
/** @typedef {import("estree").ClassDeclaration} ClassDeclarationNode */
|
||||
/** @typedef {import("estree").ClassExpression} ClassExpressionNode */
|
||||
|
|
@ -235,7 +236,7 @@ class JavascriptParser extends Parser {
|
|||
/** @type {HookMap<SyncBailHook<[ExpressionNode], boolean | void>>} */
|
||||
call: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** Something like "a.b()" */
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode, string[]], boolean | void>>} */
|
||||
/** @type {HookMap<SyncBailHook<[CallExpressionNode, string[]], boolean | void>>} */
|
||||
callMemberChain: new HookMap(
|
||||
() => new SyncBailHook(["expression", "members"])
|
||||
),
|
||||
|
|
@ -294,6 +295,7 @@ class JavascriptParser extends Parser {
|
|||
this.state = undefined;
|
||||
this.comments = undefined;
|
||||
this.semicolons = undefined;
|
||||
/** @type {(StatementNode|ExpressionNode)[]} */
|
||||
this.statementPath = undefined;
|
||||
this.prevStatement = undefined;
|
||||
this.currentTagData = undefined;
|
||||
|
|
@ -983,7 +985,7 @@ class JavascriptParser extends Parser {
|
|||
.setSideEffects(param.couldHaveSideEffects())
|
||||
.setRange(expr.range);
|
||||
});
|
||||
["substr", "substring"].forEach(fn => {
|
||||
["substr", "substring", "slice"].forEach(fn => {
|
||||
this.hooks.evaluateCallExpressionMember
|
||||
.for(fn)
|
||||
.tap("JavascriptParser", (expr, param) => {
|
||||
|
|
@ -2242,8 +2244,29 @@ class JavascriptParser extends Parser {
|
|||
this.scope.topLevelScope = wasTopLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SequenceExpressionNode} expression the sequence
|
||||
*/
|
||||
walkSequenceExpression(expression) {
|
||||
if (expression.expressions) this.walkExpressions(expression.expressions);
|
||||
if (!expression.expressions) return;
|
||||
// We treat sequence expressions like statements when they are one statement level
|
||||
// This has some benefits for optimizations that only work on statement level
|
||||
const currentStatement = this.statementPath[this.statementPath.length - 1];
|
||||
if (
|
||||
currentStatement === expression ||
|
||||
(currentStatement.type === "ExpressionStatement" &&
|
||||
currentStatement.expression === expression)
|
||||
) {
|
||||
const old = this.statementPath.pop();
|
||||
for (const expr of expression.expressions) {
|
||||
this.statementPath.push(expr);
|
||||
this.walkExpression(expr);
|
||||
this.statementPath.pop();
|
||||
}
|
||||
this.statementPath.push(old);
|
||||
} else {
|
||||
this.walkExpressions(expression.expressions);
|
||||
}
|
||||
}
|
||||
|
||||
walkUpdateExpression(expression) {
|
||||
|
|
@ -2325,8 +2348,8 @@ class JavascriptParser extends Parser {
|
|||
});
|
||||
return;
|
||||
}
|
||||
this.walkExpression(expression.right);
|
||||
if (expression.left.type.endsWith("Pattern")) {
|
||||
this.walkExpression(expression.right);
|
||||
this.enterPattern(expression.left, (name, decl) => {
|
||||
if (!this.callHooksForName(this.hooks.assign, name, expression)) {
|
||||
this.defineVariable(name);
|
||||
|
|
@ -2349,8 +2372,10 @@ class JavascriptParser extends Parser {
|
|||
return;
|
||||
}
|
||||
}
|
||||
this.walkExpression(expression.right);
|
||||
this.walkExpression(expression.left);
|
||||
} else {
|
||||
this.walkExpression(expression.right);
|
||||
this.walkExpression(expression.left);
|
||||
}
|
||||
}
|
||||
|
|
@ -2565,14 +2590,20 @@ class JavascriptParser extends Parser {
|
|||
if (exprInfo) {
|
||||
switch (exprInfo.type) {
|
||||
case "expression": {
|
||||
const result1 = this.callHooksForInfo(
|
||||
this.hooks.expression,
|
||||
exprInfo.name,
|
||||
expression
|
||||
);
|
||||
if (result1 === true) return;
|
||||
const members = exprInfo.getMembers();
|
||||
const result = this.callHooksForInfo(
|
||||
const result2 = this.callHooksForInfo(
|
||||
this.hooks.expressionMemberChain,
|
||||
exprInfo.rootInfo,
|
||||
expression,
|
||||
members
|
||||
);
|
||||
if (result === true) return;
|
||||
if (result2 === true) return;
|
||||
this.walkMemberExpressionWithExpressionName(
|
||||
expression,
|
||||
exprInfo.name,
|
||||
|
|
@ -2616,12 +2647,6 @@ class JavascriptParser extends Parser {
|
|||
members,
|
||||
onUnhandled
|
||||
) {
|
||||
const result = this.callHooksForInfo(
|
||||
this.hooks.expression,
|
||||
name,
|
||||
expression
|
||||
);
|
||||
if (result === true) return;
|
||||
if (expression.object.type === "MemberExpression") {
|
||||
// optimize the case where expression.object is a MemberExpression too.
|
||||
// we can keep info here when calling walkMemberExpression directly
|
||||
|
|
@ -2629,6 +2654,12 @@ class JavascriptParser extends Parser {
|
|||
expression.property.name || `${expression.property.value}`;
|
||||
name = name.slice(0, -property.length - 1);
|
||||
members.pop();
|
||||
const result = this.callHooksForInfo(
|
||||
this.hooks.expression,
|
||||
name,
|
||||
expression.object
|
||||
);
|
||||
if (result === true) return;
|
||||
this.walkMemberExpressionWithExpressionName(
|
||||
expression.object,
|
||||
name,
|
||||
|
|
@ -3170,6 +3201,15 @@ class JavascriptParser extends Parser {
|
|||
);
|
||||
}
|
||||
|
||||
isStatementLevelExpression(expr) {
|
||||
const currentStatement = this.statementPath[this.statementPath.length - 1];
|
||||
return (
|
||||
expr === currentStatement ||
|
||||
(currentStatement.type === "ExpressionStatement" &&
|
||||
currentStatement.expression === expr)
|
||||
);
|
||||
}
|
||||
|
||||
getTagData(name, tag) {
|
||||
const info = this.scope.definitions.get(name);
|
||||
if (info instanceof VariableInfo) {
|
||||
|
|
|
|||
|
|
@ -256,7 +256,10 @@ const getExternalImport = (
|
|||
asiSafe
|
||||
) => {
|
||||
let exprStart = info.name;
|
||||
const exportsType = importedModule.getExportsType(strictHarmonyModule);
|
||||
const exportsType = importedModule.getExportsType(
|
||||
moduleGraph,
|
||||
strictHarmonyModule
|
||||
);
|
||||
if (exportName.length === 0) {
|
||||
switch (exportsType) {
|
||||
case "default-only":
|
||||
|
|
@ -1197,6 +1200,7 @@ class ConcatenatedModule extends Module {
|
|||
if (
|
||||
info.module.buildMeta.exportsType === "default" ||
|
||||
info.module.buildMeta.exportsType === "flagged" ||
|
||||
info.module.buildMeta.exportsType === "dynamic" ||
|
||||
!info.module.buildMeta.exportsType
|
||||
) {
|
||||
const externalNameInterop = this.findNewName(
|
||||
|
|
@ -1208,7 +1212,10 @@ class ConcatenatedModule extends Module {
|
|||
allUsedNames.add(externalNameInterop);
|
||||
info.interopNamespaceObjectName = externalNameInterop;
|
||||
}
|
||||
if (!info.module.buildMeta.exportsType) {
|
||||
if (
|
||||
info.module.buildMeta.exportsType === "dynamic" ||
|
||||
!info.module.buildMeta.exportsType
|
||||
) {
|
||||
const externalNameInterop = this.findNewName(
|
||||
"default",
|
||||
allUsedNames,
|
||||
|
|
@ -1436,6 +1443,7 @@ class ConcatenatedModule extends Module {
|
|||
);
|
||||
} else if (
|
||||
info.module.buildMeta.exportsType === "flagged" ||
|
||||
info.module.buildMeta.exportsType === "dynamic" ||
|
||||
!info.module.buildMeta.exportsType
|
||||
) {
|
||||
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
|
||||
|
|
|
|||
|
|
@ -51,17 +51,23 @@ const mangleExportsInfo = (deterministic, exportsInfo, canBeArray) => {
|
|||
/** @type {ExportInfo[]} */
|
||||
const mangleableExports = [];
|
||||
const empty = canBeArray ? ARRAY : OBJECT;
|
||||
// Don't rename 1-2 char exports or exports that can't be mangled
|
||||
for (const exportInfo of exportsInfo.ownedExports) {
|
||||
const name = exportInfo.name;
|
||||
if (!exportInfo.hasUsedName()) {
|
||||
if (
|
||||
// Can the export be mangled?
|
||||
exportInfo.canMangle !== true ||
|
||||
// Never rename 1 char exports
|
||||
(name.length === 1 && /^[a-zA-Z0-9_$]/.test(name)) ||
|
||||
// Don't rename 2 char exports in deterministic mode
|
||||
(deterministic &&
|
||||
name.length === 2 &&
|
||||
/^[a-zA-Z_$][a-zA-Z0-9_$]|^[1-9][0-9]/.test(name)) ||
|
||||
(exportInfo.provided !== true && exportInfo.name in empty)
|
||||
// Don't rename exports that are not provided and in prototype chain of JSON
|
||||
(exportInfo.provided !== true && exportInfo.name in empty) ||
|
||||
// Don't rename exports that are neither provided nor used
|
||||
(exportInfo.provided === false &&
|
||||
exportInfo.getUsed(undefined) === UsageState.Unused)
|
||||
) {
|
||||
exportInfo.setUsedName(name);
|
||||
usedNames.add(name);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ module.exports = {
|
|||
require("../dependencies/CachedConstDependency"),
|
||||
"dependencies/CommonJsRequireContextDependency": () =>
|
||||
require("../dependencies/CommonJsRequireContextDependency"),
|
||||
"dependencies/CommonJsExportRequireDependency": () =>
|
||||
require("../dependencies/CommonJsExportRequireDependency"),
|
||||
"dependencies/CommonJsExportsDependency": () =>
|
||||
require("../dependencies/CommonJsExportsDependency"),
|
||||
"dependencies/CommonJsFullRequireDependency": () =>
|
||||
|
|
|
|||
|
|
@ -521,10 +521,10 @@ exports[`StatsTestCases should print correct stats for chunks-development 1`] =
|
|||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
PublicPath: (none)
|
||||
asset b_js.bundle.js 901 bytes [emitted]
|
||||
asset bundle.js 9.75 KiB [emitted] (name: main)
|
||||
asset b_js.bundle.js 968 bytes [emitted]
|
||||
asset bundle.js 9.82 KiB [emitted] (name: main)
|
||||
asset c_js.bundle.js 1.1 KiB [emitted]
|
||||
asset d_js-e_js.bundle.js 1.25 KiB [emitted]
|
||||
asset d_js-e_js.bundle.js 1.38 KiB [emitted]
|
||||
Entrypoint main = bundle.js
|
||||
chunk b_js.bundle.js 22 bytes <{main}> [rendered]
|
||||
> ./b ./index.js 2:0-16
|
||||
|
|
@ -600,6 +600,19 @@ Entrypoint <CLR=BOLD>main</CLR> = <CLR=32>main.js</CLR>
|
|||
<CLR=BOLD>./index.js</CLR> 1 bytes <CLR=32>[built]</CLR>"
|
||||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for common-libs 1`] = `
|
||||
"Hash: cb2d8154f4c30528e43b
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
asset react.js 3.12 KiB [emitted] [minimized] (name: react)
|
||||
asset react.js.LICENSE.txt 295 bytes [emitted]
|
||||
Entrypoint react = react.js
|
||||
./react.js 69 bytes [built]
|
||||
../../../node_modules/react/index.js 190 bytes [built]
|
||||
../../../node_modules/react/cjs/react.production.min.js 6.52 KiB [built]
|
||||
../../../node_modules/object-assign/index.js 2.06 KiB [built]"
|
||||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for commons-chunk-min-size-0 1`] = `
|
||||
"Hash: b96c5a233eb1688dd315
|
||||
Time: X ms
|
||||
|
|
@ -2114,18 +2127,22 @@ chunk {996} (runtime: main) 996.js 22 bytes <{179}> [rendered]
|
|||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
[847] ./a.js 22 bytes {179} [depth 1] [built]
|
||||
[used exports unknown]
|
||||
CommonJS bailout: module.exports is used directly at 1:0-14
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
[996] ./b.js 22 bytes {996} [depth 1] [built]
|
||||
[used exports unknown]
|
||||
CommonJS bailout: module.exports is used directly at 1:0-14
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
[460] ./c.js 54 bytes {460} [depth 1] [built]
|
||||
[used exports unknown]
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
[767] ./d.js 22 bytes {524} [depth 2] [built]
|
||||
[used exports unknown]
|
||||
CommonJS bailout: module.exports is used directly at 1:0-14
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
[390] ./e.js 22 bytes {524} [depth 2] [built]
|
||||
[used exports unknown]
|
||||
CommonJS bailout: module.exports is used directly at 1:0-14
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
webpack/runtime/ensure chunk 326 bytes {179} [runtime]
|
||||
[no exports]
|
||||
|
|
@ -2342,6 +2359,7 @@ chunk {179} (runtime: main) main.js (main) 73 bytes (javascript) 4.88 KiB (runti
|
|||
> ./index main
|
||||
[847] ./a.js 22 bytes {179} [depth 1] [built]
|
||||
[used exports unknown]
|
||||
CommonJS bailout: module.exports is used directly at 1:0-14
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
cjs self exports reference [847] ./a.js 1:0-14
|
||||
cjs require ./a [10] ./index.js 1:0-14
|
||||
|
|
@ -2380,12 +2398,14 @@ chunk {524} (runtime: main) 524.js 44 bytes <{460}> [rendered]
|
|||
> [460] ./c.js 1:0-52
|
||||
[767] ./d.js 22 bytes {524} [depth 2] [built]
|
||||
[used exports unknown]
|
||||
CommonJS bailout: module.exports is used directly at 1:0-14
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
require.ensure item ./d [460] ./c.js 1:0-52
|
||||
cjs self exports reference [767] ./d.js 1:0-14
|
||||
X ms [10] -> X ms [460] -> X ms (resolving: X ms, restoring: X ms, integration: X ms, building: X ms, storing: X ms)
|
||||
[390] ./e.js 22 bytes {524} [depth 2] [built]
|
||||
[used exports unknown]
|
||||
CommonJS bailout: module.exports is used directly at 1:0-14
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
require.ensure item ./e [460] ./c.js 1:0-52
|
||||
cjs self exports reference [390] ./e.js 1:0-14
|
||||
|
|
@ -2394,6 +2414,7 @@ chunk {996} (runtime: main) 996.js 22 bytes <{179}> [rendered]
|
|||
> ./b [10] ./index.js 2:0-16
|
||||
[996] ./b.js 22 bytes {996} [depth 1] [built]
|
||||
[used exports unknown]
|
||||
CommonJS bailout: module.exports is used directly at 1:0-14
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
cjs self exports reference [996] ./b.js 1:0-14
|
||||
amd require ./b [10] ./index.js 2:0-16
|
||||
|
|
@ -2944,6 +2965,7 @@ Entrypoint entry = entry.js
|
|||
ModuleConcatenation bailout: Cannot concat with ./ref-from-cjs.js: Module ./ref-from-cjs.js is referenced from these modules with unsupported syntax: ./cjs.js (referenced with cjs require)
|
||||
./entry.js 32 bytes [built]
|
||||
./cjs.js 59 bytes [built]
|
||||
CommonJS bailout: module.exports is used directly at 3:0-14
|
||||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
./ref-from-cjs.js 45 bytes [built]
|
||||
./eval.js 35 bytes [built]
|
||||
|
|
@ -3065,9 +3087,9 @@ Entrypoint main = main.js
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for side-effects-optimization 1`] = `
|
||||
"Hash: d26335b5c063fdfc2a88c8cd6c316db9be4953d2
|
||||
"Hash: dfef98e0ef4320bb5e7c18a1362fdec91250a8dc
|
||||
Child
|
||||
Hash: d26335b5c063fdfc2a88
|
||||
Hash: dfef98e0ef4320bb5e7c
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
asset main.js 207 bytes [emitted] [minimized] (name: main)
|
||||
|
|
@ -3088,7 +3110,7 @@ Child
|
|||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
+ 4 hidden modules
|
||||
Child
|
||||
Hash: c8cd6c316db9be4953d2
|
||||
Hash: 18a1362fdec91250a8dc
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
asset main.no-side.js 1.24 KiB [emitted] [minimized] (name: main)
|
||||
|
|
@ -4269,7 +4291,7 @@ Child global:
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for tree-shaking 1`] = `
|
||||
"Hash: e0f1716012b18c82ad97
|
||||
"Hash: 9b742a666c2c28e22fdf
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
asset bundle.js 7.09 KiB [emitted] (name: main)
|
||||
|
|
|
|||
|
|
@ -3478,7 +3478,7 @@ declare abstract class JavascriptParser extends Parser {
|
|||
topLevelAwait: SyncBailHook<[Expression], boolean | void>;
|
||||
call: HookMap<SyncBailHook<[Expression], boolean | void>>;
|
||||
callMemberChain: HookMap<
|
||||
SyncBailHook<[Expression, string[]], boolean | void>
|
||||
SyncBailHook<[CallExpression, string[]], boolean | void>
|
||||
>;
|
||||
memberChainOfCallMemberChain: HookMap<
|
||||
SyncBailHook<
|
||||
|
|
@ -3513,9 +3513,56 @@ declare abstract class JavascriptParser extends Parser {
|
|||
state: Record<string, any> & ParserStateBase;
|
||||
comments: any;
|
||||
semicolons: any;
|
||||
statementEndPos: any;
|
||||
lastStatementEndPos: any;
|
||||
statementStartPos: any;
|
||||
statementPath: (
|
||||
| UnaryExpression
|
||||
| ThisExpression
|
||||
| ArrayExpression
|
||||
| ObjectExpression
|
||||
| FunctionExpression
|
||||
| ArrowFunctionExpression
|
||||
| YieldExpression
|
||||
| SimpleLiteral
|
||||
| RegExpLiteral
|
||||
| UpdateExpression
|
||||
| BinaryExpression
|
||||
| AssignmentExpression
|
||||
| LogicalExpression
|
||||
| MemberExpression
|
||||
| ConditionalExpression
|
||||
| SimpleCallExpression
|
||||
| NewExpression
|
||||
| SequenceExpression
|
||||
| TemplateLiteral
|
||||
| TaggedTemplateExpression
|
||||
| ClassExpression
|
||||
| MetaProperty
|
||||
| Identifier
|
||||
| AwaitExpression
|
||||
| ImportExpression
|
||||
| ChainExpression
|
||||
| ExpressionStatement
|
||||
| BlockStatement
|
||||
| EmptyStatement
|
||||
| DebuggerStatement
|
||||
| WithStatement
|
||||
| ReturnStatement
|
||||
| LabeledStatement
|
||||
| BreakStatement
|
||||
| ContinueStatement
|
||||
| IfStatement
|
||||
| SwitchStatement
|
||||
| ThrowStatement
|
||||
| TryStatement
|
||||
| WhileStatement
|
||||
| DoWhileStatement
|
||||
| ForStatement
|
||||
| ForInStatement
|
||||
| ForOfStatement
|
||||
| FunctionDeclaration
|
||||
| VariableDeclaration
|
||||
| ClassDeclaration
|
||||
)[];
|
||||
prevStatement: any;
|
||||
currentTagData: any;
|
||||
initializeEvaluating(): void;
|
||||
getRenameIdentifier(expr?: any): string;
|
||||
|
|
@ -3584,7 +3631,7 @@ declare abstract class JavascriptParser extends Parser {
|
|||
walkObjectExpression(expression?: any): void;
|
||||
walkFunctionExpression(expression?: any): void;
|
||||
walkArrowFunctionExpression(expression?: any): void;
|
||||
walkSequenceExpression(expression?: any): void;
|
||||
walkSequenceExpression(expression: SequenceExpression): void;
|
||||
walkUpdateExpression(expression?: any): void;
|
||||
walkUnaryExpression(expression?: any): void;
|
||||
walkLeftRightExpression(expression?: any): void;
|
||||
|
|
@ -3664,6 +3711,7 @@ declare abstract class JavascriptParser extends Parser {
|
|||
evaluate(source?: any): BasicEvaluatedExpression;
|
||||
getComments(range?: any): any;
|
||||
isAsiPosition(pos?: any): any;
|
||||
isStatementLevelExpression(expr?: any): boolean;
|
||||
getTagData(name?: any, tag?: any): any;
|
||||
tagVariable(name?: any, tag?: any, data?: any): void;
|
||||
defineVariable(name?: any): void;
|
||||
|
|
@ -3759,7 +3807,7 @@ declare interface KnownBuildMeta {
|
|||
exportsArgument?: string;
|
||||
strict?: boolean;
|
||||
moduleConcatenationBailout?: string;
|
||||
exportsType?: "namespace" | "default" | "flagged";
|
||||
exportsType?: "namespace" | "dynamic" | "default" | "flagged";
|
||||
defaultObject?: false | "redirect" | "redirect-warn";
|
||||
strictHarmonyModule?: boolean;
|
||||
async?: boolean;
|
||||
|
|
@ -4176,6 +4224,7 @@ declare class Module extends DependenciesBlock {
|
|||
readonly exportsArgument: string;
|
||||
readonly moduleArgument: string;
|
||||
getExportsType(
|
||||
moduleGraph: ModuleGraph,
|
||||
strict: boolean
|
||||
): "namespace" | "default-only" | "default-with-named" | "dynamic";
|
||||
addPresentationalDependency(presentationalDependency: Dependency): void;
|
||||
|
|
|
|||
Loading…
Reference in New Issue