use parser state instead of module to store harmony/dynamic exports state
this is important for incremental build
This commit is contained in:
parent
be92913e58
commit
3b4a7455df
|
@ -218,7 +218,7 @@ class AMDDefineDependencyParserPlugin {
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DynamicExports.bailout(parser.state.module);
|
DynamicExports.bailout(parser.state);
|
||||||
let fnParams = null;
|
let fnParams = null;
|
||||||
let fnParamsOffset = 0;
|
let fnParamsOffset = 0;
|
||||||
if (fn) {
|
if (fn) {
|
||||||
|
|
|
@ -64,20 +64,20 @@ class CommonJsExportsParserPlugin {
|
||||||
*/
|
*/
|
||||||
apply(parser) {
|
apply(parser) {
|
||||||
const enableStructuredExports = () => {
|
const enableStructuredExports = () => {
|
||||||
DynamicExports.enable(parser.state.module);
|
DynamicExports.enable(parser.state);
|
||||||
};
|
};
|
||||||
const checkNamespace = (members, valueExpr) => {
|
const checkNamespace = (members, valueExpr) => {
|
||||||
if (!DynamicExports.isEnabled(parser.state.module)) return;
|
if (!DynamicExports.isEnabled(parser.state)) return;
|
||||||
if (members.length > 0 && members[0] === "__esModule") {
|
if (members.length > 0 && members[0] === "__esModule") {
|
||||||
if (isTruthyLiteral(valueExpr)) {
|
if (isTruthyLiteral(valueExpr)) {
|
||||||
DynamicExports.setFlagged(parser.state.module);
|
DynamicExports.setFlagged(parser.state);
|
||||||
} else {
|
} else {
|
||||||
DynamicExports.bailout(parser.state.module);
|
DynamicExports.bailout(parser.state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const bailout = () => {
|
const bailout = () => {
|
||||||
DynamicExports.bailout(parser.state.module);
|
DynamicExports.bailout(parser.state);
|
||||||
};
|
};
|
||||||
|
|
||||||
// metadata //
|
// metadata //
|
||||||
|
@ -92,7 +92,7 @@ class CommonJsExportsParserPlugin {
|
||||||
parser.hooks.assignMemberChain
|
parser.hooks.assignMemberChain
|
||||||
.for("exports")
|
.for("exports")
|
||||||
.tap("CommonJsExportsParserPlugin", (expr, members) => {
|
.tap("CommonJsExportsParserPlugin", (expr, members) => {
|
||||||
if (HarmonyExports.isEnabled(parser.state.module)) return;
|
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||||
enableStructuredExports();
|
enableStructuredExports();
|
||||||
checkNamespace(members, expr.right);
|
checkNamespace(members, expr.right);
|
||||||
const dep = new CommonJsExportsDependency(
|
const dep = new CommonJsExportsDependency(
|
||||||
|
@ -107,7 +107,7 @@ class CommonJsExportsParserPlugin {
|
||||||
parser.hooks.assignMemberChain
|
parser.hooks.assignMemberChain
|
||||||
.for("this")
|
.for("this")
|
||||||
.tap("CommonJsExportsParserPlugin", (expr, members) => {
|
.tap("CommonJsExportsParserPlugin", (expr, members) => {
|
||||||
if (HarmonyExports.isEnabled(parser.state.module)) return;
|
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||||
if (!parser.scope.topLevelScope) return;
|
if (!parser.scope.topLevelScope) return;
|
||||||
enableStructuredExports();
|
enableStructuredExports();
|
||||||
checkNamespace(members, expr.right);
|
checkNamespace(members, expr.right);
|
||||||
|
@ -123,7 +123,7 @@ class CommonJsExportsParserPlugin {
|
||||||
parser.hooks.assignMemberChain
|
parser.hooks.assignMemberChain
|
||||||
.for("module")
|
.for("module")
|
||||||
.tap("CommonJsExportsParserPlugin", (expr, members) => {
|
.tap("CommonJsExportsParserPlugin", (expr, members) => {
|
||||||
if (HarmonyExports.isEnabled(parser.state.module)) return;
|
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||||
if (members[0] !== "exports" || members.length <= 1) return;
|
if (members[0] !== "exports" || members.length <= 1) return;
|
||||||
enableStructuredExports();
|
enableStructuredExports();
|
||||||
checkNamespace(members, expr.right);
|
checkNamespace(members, expr.right);
|
||||||
|
@ -176,7 +176,7 @@ class CommonJsExportsParserPlugin {
|
||||||
parser.hooks.expression
|
parser.hooks.expression
|
||||||
.for("exports")
|
.for("exports")
|
||||||
.tap("CommonJsExportsParserPlugin", expr => {
|
.tap("CommonJsExportsParserPlugin", expr => {
|
||||||
if (HarmonyExports.isEnabled(parser.state.module)) return;
|
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||||
bailout();
|
bailout();
|
||||||
const dep = new CommonJsSelfReferenceDependency(
|
const dep = new CommonJsSelfReferenceDependency(
|
||||||
expr.range,
|
expr.range,
|
||||||
|
@ -190,7 +190,7 @@ class CommonJsExportsParserPlugin {
|
||||||
parser.hooks.expression
|
parser.hooks.expression
|
||||||
.for("module.exports")
|
.for("module.exports")
|
||||||
.tap("CommonJsExportsParserPlugin", expr => {
|
.tap("CommonJsExportsParserPlugin", expr => {
|
||||||
if (HarmonyExports.isEnabled(parser.state.module)) return;
|
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||||
bailout();
|
bailout();
|
||||||
const dep = new CommonJsSelfReferenceDependency(
|
const dep = new CommonJsSelfReferenceDependency(
|
||||||
expr.range,
|
expr.range,
|
||||||
|
@ -204,7 +204,7 @@ class CommonJsExportsParserPlugin {
|
||||||
parser.hooks.expression
|
parser.hooks.expression
|
||||||
.for("this")
|
.for("this")
|
||||||
.tap("CommonJsExportsParserPlugin", expr => {
|
.tap("CommonJsExportsParserPlugin", expr => {
|
||||||
if (HarmonyExports.isEnabled(parser.state.module)) return;
|
if (HarmonyExports.isEnabled(parser.state)) return;
|
||||||
if (!parser.scope.topLevelScope) return;
|
if (!parser.scope.topLevelScope) return;
|
||||||
bailout();
|
bailout();
|
||||||
const dep = new CommonJsSelfReferenceDependency(expr.range, "this", []);
|
const dep = new CommonJsSelfReferenceDependency(expr.range, "this", []);
|
||||||
|
@ -216,7 +216,7 @@ class CommonJsExportsParserPlugin {
|
||||||
// Bailouts //
|
// Bailouts //
|
||||||
parser.hooks.expression.for("module").tap("CommonJsPlugin", expr => {
|
parser.hooks.expression.for("module").tap("CommonJsPlugin", expr => {
|
||||||
bailout();
|
bailout();
|
||||||
const isHarmony = HarmonyExports.isEnabled(parser.state.module);
|
const isHarmony = HarmonyExports.isEnabled(parser.state);
|
||||||
const dep = new ModuleDecoratorDependency(
|
const dep = new ModuleDecoratorDependency(
|
||||||
isHarmony
|
isHarmony
|
||||||
? RuntimeGlobals.harmonyModuleDecorator
|
? RuntimeGlobals.harmonyModuleDecorator
|
||||||
|
|
|
@ -5,53 +5,53 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/** @typedef {import("../NormalModule")} NormalModule */
|
/** @typedef {import("../Parser").ParserState} ParserState */
|
||||||
|
|
||||||
/** @type {WeakMap<NormalModule, boolean>} */
|
/** @type {WeakMap<ParserState, boolean>} */
|
||||||
const moduleExportsState = new WeakMap();
|
const parserStateExportsState = new WeakMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {NormalModule} module the module
|
* @param {ParserState} parserState parser state
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
exports.bailout = module => {
|
exports.bailout = parserState => {
|
||||||
const value = moduleExportsState.get(module);
|
const value = parserStateExportsState.get(parserState);
|
||||||
moduleExportsState.set(module, false);
|
parserStateExportsState.set(parserState, false);
|
||||||
if (value === true) {
|
if (value === true) {
|
||||||
module.buildMeta.exportsType = undefined;
|
parserState.module.buildMeta.exportsType = undefined;
|
||||||
module.buildMeta.defaultObject = false;
|
parserState.module.buildMeta.defaultObject = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {NormalModule} module the module
|
* @param {ParserState} parserState parser state
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
exports.enable = module => {
|
exports.enable = parserState => {
|
||||||
const value = moduleExportsState.get(module);
|
const value = parserStateExportsState.get(parserState);
|
||||||
if (value === false) return;
|
if (value === false) return;
|
||||||
moduleExportsState.set(module, true);
|
parserStateExportsState.set(parserState, true);
|
||||||
if (value !== true) {
|
if (value !== true) {
|
||||||
module.buildMeta.exportsType = "default";
|
parserState.module.buildMeta.exportsType = "default";
|
||||||
module.buildMeta.defaultObject = "redirect";
|
parserState.module.buildMeta.defaultObject = "redirect";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {NormalModule} module the module
|
* @param {ParserState} parserState parser state
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
exports.setFlagged = module => {
|
exports.setFlagged = parserState => {
|
||||||
const value = moduleExportsState.get(module);
|
const value = parserStateExportsState.get(parserState);
|
||||||
if (value !== true) return;
|
if (value !== true) return;
|
||||||
module.buildMeta.exportsType = "flagged";
|
parserState.module.buildMeta.exportsType = "flagged";
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {NormalModule} module the module
|
* @param {ParserState} parserState parser state
|
||||||
* @returns {boolean} true, when enabled
|
* @returns {boolean} true, when enabled
|
||||||
*/
|
*/
|
||||||
exports.isEnabled = module => {
|
exports.isEnabled = parserState => {
|
||||||
const value = moduleExportsState.get(module);
|
const value = parserStateExportsState.get(parserState);
|
||||||
return value === true;
|
return value === true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,8 +50,8 @@ module.exports = class HarmonyDetectionParserPlugin {
|
||||||
index: -3
|
index: -3
|
||||||
};
|
};
|
||||||
module.addPresentationalDependency(compatDep);
|
module.addPresentationalDependency(compatDep);
|
||||||
DynamicExports.bailout(module);
|
DynamicExports.bailout(parser.state);
|
||||||
HarmonyExports.enable(module, isStrictHarmony);
|
HarmonyExports.enable(parser.state, isStrictHarmony);
|
||||||
parser.scope.isStrict = true;
|
parser.scope.isStrict = true;
|
||||||
module.buildMeta.async = isAsync;
|
module.buildMeta.async = isAsync;
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ module.exports = class HarmonyDetectionParserPlugin {
|
||||||
"The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enabled it)"
|
"The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enabled it)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!HarmonyExports.isEnabled(parser.state.module)) {
|
if (!HarmonyExports.isEnabled(parser.state)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Top-level-await is only supported in EcmaScript Modules"
|
"Top-level-await is only supported in EcmaScript Modules"
|
||||||
);
|
);
|
||||||
|
@ -73,13 +73,13 @@ module.exports = class HarmonyDetectionParserPlugin {
|
||||||
});
|
});
|
||||||
|
|
||||||
const skipInHarmony = () => {
|
const skipInHarmony = () => {
|
||||||
if (HarmonyExports.isEnabled(parser.state.module)) {
|
if (HarmonyExports.isEnabled(parser.state)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const nullInHarmony = () => {
|
const nullInHarmony = () => {
|
||||||
if (HarmonyExports.isEnabled(parser.state.module)) {
|
if (HarmonyExports.isEnabled(parser.state)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,36 +5,36 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/** @typedef {import("../NormalModule")} NormalModule */
|
/** @typedef {import("../Parser").ParserState} ParserState */
|
||||||
|
|
||||||
/** @type {WeakMap<NormalModule, boolean>} */
|
/** @type {WeakMap<ParserState, boolean>} */
|
||||||
const moduleExportsState = new WeakMap();
|
const parserStateExportsState = new WeakMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {NormalModule} module the module
|
* @param {ParserState} parserState parser state
|
||||||
* @param {boolean} isStrictHarmony strict harmony mode should be enabled
|
* @param {boolean} isStrictHarmony strict harmony mode should be enabled
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
exports.enable = (module, isStrictHarmony) => {
|
exports.enable = (parserState, isStrictHarmony) => {
|
||||||
const value = moduleExportsState.get(module);
|
const value = parserStateExportsState.get(parserState);
|
||||||
if (value === false) return;
|
if (value === false) return;
|
||||||
moduleExportsState.set(module, true);
|
parserStateExportsState.set(parserState, true);
|
||||||
if (value !== true) {
|
if (value !== true) {
|
||||||
module.buildMeta.exportsType = "namespace";
|
parserState.module.buildMeta.exportsType = "namespace";
|
||||||
module.buildInfo.strict = true;
|
parserState.module.buildInfo.strict = true;
|
||||||
module.buildInfo.exportsArgument = "__webpack_exports__";
|
parserState.module.buildInfo.exportsArgument = "__webpack_exports__";
|
||||||
if (isStrictHarmony) {
|
if (isStrictHarmony) {
|
||||||
module.buildMeta.strictHarmonyModule = true;
|
parserState.module.buildMeta.strictHarmonyModule = true;
|
||||||
module.buildInfo.moduleArgument = "__webpack_module__";
|
parserState.module.buildInfo.moduleArgument = "__webpack_module__";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {NormalModule} module the module
|
* @param {ParserState} parserState parser state
|
||||||
* @returns {boolean} true, when enabled
|
* @returns {boolean} true, when enabled
|
||||||
*/
|
*/
|
||||||
exports.isEnabled = module => {
|
exports.isEnabled = parserState => {
|
||||||
const value = moduleExportsState.get(module);
|
const value = parserStateExportsState.get(parserState);
|
||||||
return value === true;
|
return value === true;
|
||||||
};
|
};
|
||||||
|
|
|
@ -169,7 +169,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||||
hotAcceptCallback.tap(
|
hotAcceptCallback.tap(
|
||||||
"HarmonyImportDependencyParserPlugin",
|
"HarmonyImportDependencyParserPlugin",
|
||||||
(expr, requests) => {
|
(expr, requests) => {
|
||||||
if (!HarmonyExports.isEnabled(parser.state.module)) {
|
if (!HarmonyExports.isEnabled(parser.state)) {
|
||||||
// This is not a harmony module, skip it
|
// This is not a harmony module, skip it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
||||||
hotAcceptWithoutCallback.tap(
|
hotAcceptWithoutCallback.tap(
|
||||||
"HarmonyImportDependencyParserPlugin",
|
"HarmonyImportDependencyParserPlugin",
|
||||||
(expr, requests) => {
|
(expr, requests) => {
|
||||||
if (!HarmonyExports.isEnabled(parser.state.module)) {
|
if (!HarmonyExports.isEnabled(parser.state)) {
|
||||||
// This is not a harmony module, skip it
|
// This is not a harmony module, skip it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ class HarmonyTopLevelThisParserPlugin {
|
||||||
.for("this")
|
.for("this")
|
||||||
.tap("HarmonyTopLevelThisParserPlugin", node => {
|
.tap("HarmonyTopLevelThisParserPlugin", node => {
|
||||||
if (!parser.scope.topLevelScope) return;
|
if (!parser.scope.topLevelScope) return;
|
||||||
if (HarmonyExports.isEnabled(parser.state.module)) {
|
if (HarmonyExports.isEnabled(parser.state)) {
|
||||||
const dep = new ConstDependency("undefined", node.range, null);
|
const dep = new ConstDependency("undefined", node.range, null);
|
||||||
dep.loc = node.loc;
|
dep.loc = node.loc;
|
||||||
parser.state.module.addPresentationalDependency(dep);
|
parser.state.module.addPresentationalDependency(dep);
|
||||||
|
|
|
@ -7,9 +7,8 @@
|
||||||
|
|
||||||
const ChunkGraph = require("../ChunkGraph");
|
const ChunkGraph = require("../ChunkGraph");
|
||||||
const ModuleGraph = require("../ModuleGraph");
|
const ModuleGraph = require("../ModuleGraph");
|
||||||
const NormalModule = require("../NormalModule");
|
|
||||||
const { STAGE_DEFAULT } = require("../OptimizationStages");
|
const { STAGE_DEFAULT } = require("../OptimizationStages");
|
||||||
const HarmonyExports = require("../dependencies/HarmonyExports");
|
const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency");
|
||||||
const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
|
const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency");
|
||||||
const ModuleHotAcceptDependency = require("../dependencies/ModuleHotAcceptDependency");
|
const ModuleHotAcceptDependency = require("../dependencies/ModuleHotAcceptDependency");
|
||||||
const ModuleHotDeclineDependency = require("../dependencies/ModuleHotDeclineDependency");
|
const ModuleHotDeclineDependency = require("../dependencies/ModuleHotDeclineDependency");
|
||||||
|
@ -114,9 +113,9 @@ class ModuleConcatenationPlugin {
|
||||||
if (
|
if (
|
||||||
!module.buildMeta ||
|
!module.buildMeta ||
|
||||||
module.buildMeta.exportsType !== "namespace" ||
|
module.buildMeta.exportsType !== "namespace" ||
|
||||||
!(
|
module.presentationalDependencies === undefined ||
|
||||||
module instanceof NormalModule &&
|
!module.presentationalDependencies.some(
|
||||||
HarmonyExports.isEnabled(module)
|
d => d instanceof HarmonyCompatibilityDependency
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
setBailoutReason(module, "Module is not an ECMAScript module");
|
setBailoutReason(module, "Module is not an ECMAScript module");
|
||||||
|
|
|
@ -4,8 +4,8 @@ it("should abort when module is declined by parent", (done) => {
|
||||||
expect(a).toBe(1);
|
expect(a).toBe(1);
|
||||||
NEXT(require("../../update")((err) => {
|
NEXT(require("../../update")((err) => {
|
||||||
try {
|
try {
|
||||||
expect(/Aborted because of declined dependency: \.\/b\.js in \.\/a\.js/.test(err.message)).toBe(true);
|
expect(err.message).toMatch(/Aborted because of declined dependency: \.\/b\.js in \.\/a\.js/);
|
||||||
expect(/Update propagation: \.\/c\.js -> \.\/b\.js -> \.\/a\.js/.test(err.message)).toBe(true);
|
expect(err.message).toMatch(/Update propagation: \.\/c\.js -> \.\/b\.js -> \.\/a\.js/);
|
||||||
done();
|
done();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
done(e);
|
done(e);
|
||||||
|
|
|
@ -4,8 +4,8 @@ it("should abort when module is declined by itself", (done) => {
|
||||||
expect(a).toBe(1);
|
expect(a).toBe(1);
|
||||||
NEXT(require("../../update")((err) => {
|
NEXT(require("../../update")((err) => {
|
||||||
try {
|
try {
|
||||||
expect(/Aborted because of self decline: \.\/a\.js/.test(err.message)).toBe(true);
|
expect(err.message).toMatch(/Aborted because of self decline: \.\/a\.js/);
|
||||||
expect(/Update propagation: \.\/c\.js -> \.\/b\.js -> \.\/a\.js/.test(err.message)).toBe(true);
|
expect(err.message).toMatch(/Update propagation: \.\/c\.js -> \.\/b\.js -> \.\/a\.js/);
|
||||||
done();
|
done();
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
done(e);
|
done(e);
|
||||||
|
|
|
@ -6,8 +6,8 @@ it("should abort when module is not accepted", (done) => {
|
||||||
expect(b).toBe(1);
|
expect(b).toBe(1);
|
||||||
NEXT(require("../../update")((err) => {
|
NEXT(require("../../update")((err) => {
|
||||||
try {
|
try {
|
||||||
expect(/Aborted because \.\/c\.js is not accepted/.test(err.message)).toBe(true);
|
expect(err.message).toMatch(/Aborted because \.\/c\.js is not accepted/);
|
||||||
expect(/Update propagation: \.\/c\.js -> \.\/b\.js -> \.\/index\.js/.test(err.message)).toBe(true);
|
expect(err.message).toMatch(/Update propagation: \.\/c\.js -> \.\/b\.js -> \.\/index\.js/);
|
||||||
done();
|
done();
|
||||||
} catch(e) { done(e); }
|
} catch(e) { done(e); }
|
||||||
}));
|
}));
|
||||||
|
|
Loading…
Reference in New Issue