Merge pull request #11075 from vankop/import-meta
add import.meta support
This commit is contained in:
commit
d9435e0e3e
|
@ -4,6 +4,7 @@
|
|||
"words": [
|
||||
"webpack",
|
||||
"webpack's",
|
||||
"endregion",
|
||||
"entrypoint",
|
||||
"entrypoints",
|
||||
"splitted",
|
||||
|
|
|
@ -12,9 +12,11 @@ const Compilation = require("./Compilation");
|
|||
const HotUpdateChunk = require("./HotUpdateChunk");
|
||||
const NormalModule = require("./NormalModule");
|
||||
const RuntimeGlobals = require("./RuntimeGlobals");
|
||||
const ConstDependency = require("./dependencies/ConstDependency");
|
||||
const ImportMetaHotAcceptDependency = require("./dependencies/ImportMetaHotAcceptDependency");
|
||||
const ImportMetaHotDeclineDependency = require("./dependencies/ImportMetaHotDeclineDependency");
|
||||
const ModuleHotAcceptDependency = require("./dependencies/ModuleHotAcceptDependency");
|
||||
const ModuleHotDeclineDependency = require("./dependencies/ModuleHotDeclineDependency");
|
||||
const ModuleHotDependency = require("./dependencies/ModuleHotDependency");
|
||||
const HotModuleReplacementRuntimeModule = require("./hmr/HotModuleReplacementRuntimeModule");
|
||||
const JavascriptParser = require("./javascript/JavascriptParser");
|
||||
const {
|
||||
|
@ -81,24 +83,98 @@ class HotModuleReplacementPlugin {
|
|||
return callback();
|
||||
}
|
||||
);
|
||||
const runtimeRequirements = [RuntimeGlobals.module];
|
||||
|
||||
const addParserPlugins = (parser, parserOptions) => {
|
||||
const createAcceptHandler = (parser, ParamDependency) => {
|
||||
const {
|
||||
hotAcceptCallback,
|
||||
hotAcceptWithoutCallback
|
||||
} = HotModuleReplacementPlugin.getParserHooks(parser);
|
||||
|
||||
parser.hooks.expression
|
||||
.for("__webpack_hash__")
|
||||
.tap(
|
||||
"HotModuleReplacementPlugin",
|
||||
toConstantDependency(parser, `${RuntimeGlobals.getFullHash}()`, [
|
||||
RuntimeGlobals.getFullHash
|
||||
])
|
||||
return expr => {
|
||||
const module = parser.state.module;
|
||||
const dep = new ConstDependency(
|
||||
`${module.moduleArgument}.hot.accept`,
|
||||
expr.callee.range,
|
||||
runtimeRequirements
|
||||
);
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("__webpack_hash__")
|
||||
.tap("HotModuleReplacementPlugin", evaluateToString("string"));
|
||||
dep.loc = expr.loc;
|
||||
module.addPresentationalDependency(dep);
|
||||
if (expr.arguments.length >= 1) {
|
||||
const arg = parser.evaluateExpression(expr.arguments[0]);
|
||||
let params = [];
|
||||
let requests = [];
|
||||
if (arg.isString()) {
|
||||
params = [arg];
|
||||
} else if (arg.isArray()) {
|
||||
params = arg.items.filter(param => param.isString());
|
||||
}
|
||||
if (params.length > 0) {
|
||||
params.forEach((param, idx) => {
|
||||
const request = param.string;
|
||||
const dep = new ParamDependency(request, param.range);
|
||||
dep.optional = true;
|
||||
dep.loc = Object.create(expr.loc);
|
||||
dep.loc.index = idx;
|
||||
module.addDependency(dep);
|
||||
requests.push(request);
|
||||
});
|
||||
if (expr.arguments.length > 1) {
|
||||
hotAcceptCallback.call(expr.arguments[1], requests);
|
||||
parser.walkExpression(expr.arguments[1]); // other args are ignored
|
||||
return true;
|
||||
} else {
|
||||
hotAcceptWithoutCallback.call(expr, requests);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
parser.walkExpressions(expr.arguments);
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
const createDeclineHandler = (parser, ParamDependency) => expr => {
|
||||
const module = parser.state.module;
|
||||
const dep = new ConstDependency(
|
||||
`${module.moduleArgument}.hot.decline`,
|
||||
expr.callee.range,
|
||||
runtimeRequirements
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
module.addPresentationalDependency(dep);
|
||||
if (expr.arguments.length === 1) {
|
||||
const arg = parser.evaluateExpression(expr.arguments[0]);
|
||||
let params = [];
|
||||
if (arg.isString()) {
|
||||
params = [arg];
|
||||
} else if (arg.isArray()) {
|
||||
params = arg.items.filter(param => param.isString());
|
||||
}
|
||||
params.forEach((param, idx) => {
|
||||
const dep = new ParamDependency(param.string, param.range);
|
||||
dep.optional = true;
|
||||
dep.loc = Object.create(expr.loc);
|
||||
dep.loc.index = idx;
|
||||
module.addDependency(dep);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const createHMRExpressionHandler = parser => expr => {
|
||||
const module = parser.state.module;
|
||||
const dep = new ConstDependency(
|
||||
`${module.moduleArgument}.hot`,
|
||||
expr.range,
|
||||
runtimeRequirements
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
};
|
||||
|
||||
const applyModuleHot = parser => {
|
||||
parser.hooks.evaluateIdentifier.for("module.hot").tap(
|
||||
{
|
||||
name: "HotModuleReplacementPlugin",
|
||||
|
@ -115,77 +191,61 @@ class HotModuleReplacementPlugin {
|
|||
);
|
||||
parser.hooks.call
|
||||
.for("module.hot.accept")
|
||||
.tap("HotModuleReplacementPlugin", expr => {
|
||||
const dep = new ModuleHotDependency(expr.callee.range, "accept");
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
if (expr.arguments.length >= 1) {
|
||||
const arg = parser.evaluateExpression(expr.arguments[0]);
|
||||
let params = [];
|
||||
let requests = [];
|
||||
if (arg.isString()) {
|
||||
params = [arg];
|
||||
} else if (arg.isArray()) {
|
||||
params = arg.items.filter(param => param.isString());
|
||||
}
|
||||
if (params.length > 0) {
|
||||
params.forEach((param, idx) => {
|
||||
const request = param.string;
|
||||
const dep = new ModuleHotAcceptDependency(request, param.range);
|
||||
dep.optional = true;
|
||||
dep.loc = Object.create(expr.loc);
|
||||
dep.loc.index = idx;
|
||||
parser.state.module.addDependency(dep);
|
||||
requests.push(request);
|
||||
});
|
||||
if (expr.arguments.length > 1) {
|
||||
hotAcceptCallback.call(expr.arguments[1], requests);
|
||||
parser.walkExpression(expr.arguments[1]); // other args are ignored
|
||||
return true;
|
||||
} else {
|
||||
hotAcceptWithoutCallback.call(expr, requests);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
parser.walkExpressions(expr.arguments);
|
||||
return true;
|
||||
});
|
||||
.tap(
|
||||
"HotModuleReplacementPlugin",
|
||||
createAcceptHandler(parser, ModuleHotAcceptDependency)
|
||||
);
|
||||
parser.hooks.call
|
||||
.for("module.hot.decline")
|
||||
.tap("HotModuleReplacementPlugin", expr => {
|
||||
const dep = new ModuleHotDependency(expr.callee.range, "decline");
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
if (expr.arguments.length === 1) {
|
||||
const arg = parser.evaluateExpression(expr.arguments[0]);
|
||||
let params = [];
|
||||
if (arg.isString()) {
|
||||
params = [arg];
|
||||
} else if (arg.isArray()) {
|
||||
params = arg.items.filter(param => param.isString());
|
||||
}
|
||||
params.forEach((param, idx) => {
|
||||
const dep = new ModuleHotDeclineDependency(
|
||||
param.string,
|
||||
param.range
|
||||
);
|
||||
dep.optional = true;
|
||||
dep.loc = Object.create(expr.loc);
|
||||
dep.loc.index = idx;
|
||||
parser.state.module.addDependency(dep);
|
||||
});
|
||||
}
|
||||
return true;
|
||||
});
|
||||
.tap(
|
||||
"HotModuleReplacementPlugin",
|
||||
createDeclineHandler(parser, ModuleHotDeclineDependency)
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("module.hot")
|
||||
.tap("HotModuleReplacementPlugin", createHMRExpressionHandler(parser));
|
||||
};
|
||||
|
||||
const applyImportMetaHot = parser => {
|
||||
parser.hooks.evaluateIdentifier
|
||||
.for("import.meta.webpackHot")
|
||||
.tap("HotModuleReplacementPlugin", expr => {
|
||||
const dep = new ModuleHotDependency(expr.range);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addDependency(dep);
|
||||
return true;
|
||||
return evaluateToIdentifier(
|
||||
"import.meta.webpackHot",
|
||||
"import.meta",
|
||||
() => ["webpackHot"],
|
||||
true
|
||||
)(expr);
|
||||
});
|
||||
parser.hooks.call
|
||||
.for("import.meta.webpackHot.accept")
|
||||
.tap(
|
||||
"HotModuleReplacementPlugin",
|
||||
createAcceptHandler(parser, ImportMetaHotAcceptDependency)
|
||||
);
|
||||
parser.hooks.call
|
||||
.for("import.meta.webpackHot.decline")
|
||||
.tap(
|
||||
"HotModuleReplacementPlugin",
|
||||
createDeclineHandler(parser, ImportMetaHotDeclineDependency)
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("import.meta.webpackHot")
|
||||
.tap("HotModuleReplacementPlugin", createHMRExpressionHandler(parser));
|
||||
};
|
||||
|
||||
const applyWebpackHash = parser => {
|
||||
parser.hooks.expression
|
||||
.for("__webpack_hash__")
|
||||
.tap(
|
||||
"HotModuleReplacementPlugin",
|
||||
toConstantDependency(parser, `${RuntimeGlobals.getFullHash}()`, [
|
||||
RuntimeGlobals.getFullHash
|
||||
])
|
||||
);
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("__webpack_hash__")
|
||||
.tap("HotModuleReplacementPlugin", evaluateToString("string"));
|
||||
};
|
||||
|
||||
compiler.hooks.compilation.tap(
|
||||
|
@ -195,6 +255,7 @@ class HotModuleReplacementPlugin {
|
|||
// It should not affect child compilations
|
||||
if (compilation.compiler !== compiler) return;
|
||||
|
||||
//#region module.hot.* API
|
||||
compilation.dependencyFactories.set(
|
||||
ModuleHotAcceptDependency,
|
||||
normalModuleFactory
|
||||
|
@ -203,7 +264,6 @@ class HotModuleReplacementPlugin {
|
|||
ModuleHotAcceptDependency,
|
||||
new ModuleHotAcceptDependency.Template()
|
||||
);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
ModuleHotDeclineDependency,
|
||||
normalModuleFactory
|
||||
|
@ -212,11 +272,26 @@ class HotModuleReplacementPlugin {
|
|||
ModuleHotDeclineDependency,
|
||||
new ModuleHotDeclineDependency.Template()
|
||||
);
|
||||
//#endregion
|
||||
|
||||
compilation.dependencyTemplates.set(
|
||||
ModuleHotDependency,
|
||||
new ModuleHotDependency.Template()
|
||||
//#region import.meta.webpackHot.* API
|
||||
compilation.dependencyFactories.set(
|
||||
ImportMetaHotAcceptDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
ImportMetaHotAcceptDependency,
|
||||
new ImportMetaHotAcceptDependency.Template()
|
||||
);
|
||||
compilation.dependencyFactories.set(
|
||||
ImportMetaHotDeclineDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
compilation.dependencyTemplates.set(
|
||||
ImportMetaHotDeclineDependency,
|
||||
new ImportMetaHotDeclineDependency.Template()
|
||||
);
|
||||
//#endregion
|
||||
|
||||
compilation.hooks.record.tap(
|
||||
"HotModuleReplacementPlugin",
|
||||
|
@ -428,13 +503,25 @@ class HotModuleReplacementPlugin {
|
|||
}
|
||||
);
|
||||
|
||||
// TODO add HMR support for javascript/esm
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/auto")
|
||||
.tap("HotModuleReplacementPlugin", addParserPlugins);
|
||||
.tap("HotModuleReplacementPlugin", parser => {
|
||||
applyWebpackHash(parser);
|
||||
applyModuleHot(parser);
|
||||
applyImportMetaHot(parser);
|
||||
});
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/dynamic")
|
||||
.tap("HotModuleReplacementPlugin", addParserPlugins);
|
||||
.tap("HotModuleReplacementPlugin", parser => {
|
||||
applyWebpackHash(parser);
|
||||
applyModuleHot(parser);
|
||||
});
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/esm")
|
||||
.tap("HotModuleReplacementPlugin", parser => {
|
||||
applyWebpackHash(parser);
|
||||
applyImportMetaHot(parser);
|
||||
});
|
||||
|
||||
NormalModule.getCompilationHooks(compilation).loader.tap(
|
||||
"HotModuleReplacementPlugin",
|
||||
|
|
|
@ -33,6 +33,7 @@ const ResolverCachePlugin = require("./cache/ResolverCachePlugin");
|
|||
|
||||
const CommonJsPlugin = require("./dependencies/CommonJsPlugin");
|
||||
const HarmonyModulesPlugin = require("./dependencies/HarmonyModulesPlugin");
|
||||
const ImportMetaPlugin = require("./dependencies/ImportMetaPlugin");
|
||||
const ImportPlugin = require("./dependencies/ImportPlugin");
|
||||
const LoaderPlugin = require("./dependencies/LoaderPlugin");
|
||||
const RequireContextPlugin = require("./dependencies/RequireContextPlugin");
|
||||
|
@ -346,6 +347,7 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
).apply(compiler);
|
||||
new ImportPlugin(options.module).apply(compiler);
|
||||
new SystemPlugin(options.module).apply(compiler);
|
||||
new ImportMetaPlugin().apply(compiler);
|
||||
|
||||
new DefaultStatsFactoryPlugin().apply(compiler);
|
||||
new DefaultStatsPresetPlugin().apply(compiler);
|
||||
|
|
|
@ -8,12 +8,16 @@
|
|||
const Dependency = require("../Dependency");
|
||||
const DependencyTemplate = require("../DependencyTemplate");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const CriticalDependencyWarning = require("./CriticalDependencyWarning");
|
||||
const memorize = require("../util/memorize");
|
||||
|
||||
/** @typedef {import("../ContextModule").ContextOptions} ContextOptions */
|
||||
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
||||
/** @typedef {import("../WebpackError")} WebpackError */
|
||||
|
||||
const getCriticalDependencyWarning = memorize(() =>
|
||||
require("./CriticalDependencyWarning")
|
||||
);
|
||||
|
||||
/** @typedef {ContextOptions & { request: string }} ContextDependencyOptions */
|
||||
|
||||
const regExpToString = r => (r ? r + "" : "");
|
||||
|
@ -74,11 +78,13 @@ class ContextDependency extends Dependency {
|
|||
|
||||
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."
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Ivan Kopeykin @vankop
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const ModuleDependency = require("./ModuleDependency");
|
||||
const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId");
|
||||
|
||||
class ImportMetaHotAcceptDependency extends ModuleDependency {
|
||||
constructor(request, range) {
|
||||
super(request);
|
||||
this.range = range;
|
||||
this.weak = true;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "import.meta.webpackHot.accept";
|
||||
}
|
||||
|
||||
get category() {
|
||||
return "esm";
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
ImportMetaHotAcceptDependency,
|
||||
"webpack/lib/dependencies/ImportMetaHotAcceptDependency"
|
||||
);
|
||||
|
||||
ImportMetaHotAcceptDependency.Template = ModuleDependencyTemplateAsId;
|
||||
|
||||
module.exports = ImportMetaHotAcceptDependency;
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Ivan Kopeykin @vankop
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const ModuleDependency = require("./ModuleDependency");
|
||||
const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId");
|
||||
|
||||
class ImportMetaHotDeclineDependency extends ModuleDependency {
|
||||
constructor(request, range) {
|
||||
super(request);
|
||||
|
||||
this.range = range;
|
||||
this.weak = true;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "import.meta.webpackHot.decline";
|
||||
}
|
||||
|
||||
get category() {
|
||||
return "esm";
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
ImportMetaHotDeclineDependency,
|
||||
"webpack/lib/dependencies/ImportMetaHotDeclineDependency"
|
||||
);
|
||||
|
||||
ImportMetaHotDeclineDependency.Template = ModuleDependencyTemplateAsId;
|
||||
|
||||
module.exports = ImportMetaHotDeclineDependency;
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Ivan Kopeykin @vankop
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { pathToFileURL } = require("url");
|
||||
const ModuleDependencyWarning = require("../ModuleDependencyWarning");
|
||||
const Template = require("../Template");
|
||||
const BasicEvaluatedExpression = require("../javascript/BasicEvaluatedExpression");
|
||||
const {
|
||||
evaluateToIdentifier,
|
||||
toConstantDependency,
|
||||
evaluateToString,
|
||||
evaluateToNumber
|
||||
} = require("../javascript/JavascriptParserHelpers");
|
||||
const memorize = require("../util/memorize");
|
||||
const propertyAccess = require("../util/propertyAccess");
|
||||
const ConstDependency = require("./ConstDependency");
|
||||
|
||||
/** @typedef {import("estree").MemberExpression} MemberExpression */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("../NormalModule")} NormalModule */
|
||||
/** @typedef {import("../javascript/JavascriptParser")} Parser */
|
||||
|
||||
const getCriticalDependencyWarning = memorize(() =>
|
||||
require("./CriticalDependencyWarning")
|
||||
);
|
||||
|
||||
class ImportMetaPlugin {
|
||||
/**
|
||||
* @param {Compiler} compiler compiler
|
||||
*/
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap(
|
||||
"ImportMetaPlugin",
|
||||
(compilation, { normalModuleFactory }) => {
|
||||
/**
|
||||
* @param {NormalModule} module module
|
||||
* @returns {string} file url
|
||||
*/
|
||||
const getUrl = module => {
|
||||
return pathToFileURL(module.resource).toString();
|
||||
};
|
||||
/**
|
||||
* @param {Parser} parser parser
|
||||
* @param {Object} parserOptions parserOptions
|
||||
* @returns {void}
|
||||
*/
|
||||
const parserHandler = (parser, parserOptions) => {
|
||||
/// import.meta direct ///
|
||||
parser.hooks.typeof
|
||||
.for("import.meta")
|
||||
.tap(
|
||||
"ImportMetaPlugin",
|
||||
toConstantDependency(parser, JSON.stringify("object"))
|
||||
);
|
||||
parser.hooks.metaProperty.tap(
|
||||
"ImportMetaPlugin",
|
||||
toConstantDependency(parser, "Object()")
|
||||
);
|
||||
parser.hooks.metaProperty.tap("ImportMetaPlugin", metaProperty => {
|
||||
const CriticalDependencyWarning = getCriticalDependencyWarning();
|
||||
parser.state.module.addWarning(
|
||||
new ModuleDependencyWarning(
|
||||
parser.state.module,
|
||||
new CriticalDependencyWarning(
|
||||
"Accessing import.meta directly is unsupported (only property access is supported)"
|
||||
),
|
||||
metaProperty.loc
|
||||
)
|
||||
);
|
||||
const dep = new ConstDependency("Object()", metaProperty.range);
|
||||
dep.loc = metaProperty.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("import.meta")
|
||||
.tap("ImportMetaPlugin", evaluateToString("object"));
|
||||
parser.hooks.evaluateIdentifier.for("import.meta").tap(
|
||||
"ImportMetaPlugin",
|
||||
evaluateToIdentifier("import.meta", "import.meta", () => [], true)
|
||||
);
|
||||
|
||||
/// import.meta.url ///
|
||||
parser.hooks.typeof
|
||||
.for("import.meta.url")
|
||||
.tap(
|
||||
"ImportMetaPlugin",
|
||||
toConstantDependency(parser, JSON.stringify("string"))
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("import.meta.url")
|
||||
.tap("ImportMetaPlugin", expr => {
|
||||
const dep = new ConstDependency(
|
||||
JSON.stringify(getUrl(parser.state.module)),
|
||||
expr.range
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("import.meta.url")
|
||||
.tap("ImportMetaPlugin", evaluateToString("string"));
|
||||
parser.hooks.evaluateIdentifier
|
||||
.for("import.meta.url")
|
||||
.tap("ImportMetaPlugin", expr => {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString(getUrl(parser.state.module))
|
||||
.setRange(expr.range);
|
||||
});
|
||||
|
||||
/// import.meta.webpack ///
|
||||
const webpackVersion = parseInt(
|
||||
require("../../package.json").version,
|
||||
10
|
||||
);
|
||||
parser.hooks.typeof
|
||||
.for("import.meta.webpack")
|
||||
.tap(
|
||||
"ImportMetaPlugin",
|
||||
toConstantDependency(parser, JSON.stringify("number"))
|
||||
);
|
||||
parser.hooks.expression
|
||||
.for("import.meta.webpack")
|
||||
.tap(
|
||||
"ImportMetaPlugin",
|
||||
toConstantDependency(parser, JSON.stringify(webpackVersion))
|
||||
);
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("import.meta.webpack")
|
||||
.tap("ImportMetaPlugin", evaluateToString("number"));
|
||||
parser.hooks.evaluateIdentifier
|
||||
.for("import.meta.webpack")
|
||||
.tap("ImportMetaPlugin", evaluateToNumber(webpackVersion));
|
||||
|
||||
/// Unknown properties ///
|
||||
parser.hooks.unhandledExpressionMemberChain
|
||||
.for("import.meta")
|
||||
.tap("ImportMetaPlugin", (expr, members) => {
|
||||
const dep = new ConstDependency(
|
||||
`${Template.toNormalComment(
|
||||
"unsupported import.meta." + members.join(".")
|
||||
)} undefined${propertyAccess(members, 1)}`,
|
||||
expr.range
|
||||
);
|
||||
dep.loc = expr.loc;
|
||||
parser.state.module.addPresentationalDependency(dep);
|
||||
return true;
|
||||
});
|
||||
parser.hooks.evaluate
|
||||
.for("MemberExpression")
|
||||
.tap("ImportMetaPlugin", expression => {
|
||||
const expr = /** @type {MemberExpression} */ (expression);
|
||||
if (
|
||||
expr.object.type === "MetaProperty" &&
|
||||
expr.property.type ===
|
||||
(expr.computed ? "Literal" : "Identifier")
|
||||
) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setUndefined()
|
||||
.setRange(expr.range);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/auto")
|
||||
.tap("ImportMetaPlugin", parserHandler);
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/esm")
|
||||
.tap("ImportMetaPlugin", parserHandler);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ImportMetaPlugin;
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
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 ModuleHotDependency extends NullDependency {
|
||||
constructor(range, apiMethod) {
|
||||
super();
|
||||
|
||||
this.range = range;
|
||||
this.apiMethod = apiMethod;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "module.hot";
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
|
||||
write(this.range);
|
||||
write(this.apiMethod);
|
||||
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
const { read } = context;
|
||||
|
||||
this.range = read();
|
||||
this.apiMethod = read();
|
||||
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
ModuleHotDependency,
|
||||
"webpack/lib/dependencies/ModuleHotDependency"
|
||||
);
|
||||
|
||||
ModuleHotDependency.Template = class ModuleHotDependencyTemplate 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, runtimeRequirements }) {
|
||||
const dep = /** @type {ModuleHotDependency} */ (dependency);
|
||||
runtimeRequirements.add(RuntimeGlobals.module);
|
||||
source.replace(
|
||||
dep.range[0],
|
||||
dep.range[1] - 1,
|
||||
`${module.moduleArgument}.hot${dep.apiMethod ? `.${dep.apiMethod}` : ""}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = ModuleHotDependency;
|
|
@ -6,18 +6,19 @@
|
|||
"use strict";
|
||||
|
||||
const TypeUnknown = 0;
|
||||
const TypeNull = 1;
|
||||
const TypeString = 2;
|
||||
const TypeNumber = 3;
|
||||
const TypeBoolean = 4;
|
||||
const TypeRegExp = 5;
|
||||
const TypeConditional = 6;
|
||||
const TypeArray = 7;
|
||||
const TypeConstArray = 8;
|
||||
const TypeIdentifier = 9;
|
||||
const TypeWrapped = 10;
|
||||
const TypeTemplateString = 11;
|
||||
const TypeBigInt = 12;
|
||||
const TypeUndefined = 1;
|
||||
const TypeNull = 2;
|
||||
const TypeString = 3;
|
||||
const TypeNumber = 4;
|
||||
const TypeBoolean = 5;
|
||||
const TypeRegExp = 6;
|
||||
const TypeConditional = 7;
|
||||
const TypeArray = 8;
|
||||
const TypeConstArray = 9;
|
||||
const TypeIdentifier = 10;
|
||||
const TypeWrapped = 11;
|
||||
const TypeTemplateString = 12;
|
||||
const TypeBigInt = 13;
|
||||
|
||||
class BasicEvaluatedExpression {
|
||||
constructor() {
|
||||
|
@ -48,6 +49,10 @@ class BasicEvaluatedExpression {
|
|||
return this.type === TypeNull;
|
||||
}
|
||||
|
||||
isUndefined() {
|
||||
return this.type === TypeUndefined;
|
||||
}
|
||||
|
||||
isString() {
|
||||
return this.type === TypeString;
|
||||
}
|
||||
|
@ -105,6 +110,7 @@ class BasicEvaluatedExpression {
|
|||
if (this.falsy) return false;
|
||||
if (this.isBoolean()) return this.bool;
|
||||
if (this.isNull()) return false;
|
||||
if (this.isUndefined()) return false;
|
||||
if (this.isString()) return this.string !== "";
|
||||
if (this.isNumber()) return this.number !== 0;
|
||||
if (this.isBigInt()) return this.bigint !== BigInt(0);
|
||||
|
@ -127,6 +133,7 @@ class BasicEvaluatedExpression {
|
|||
asString() {
|
||||
if (this.isBoolean()) return `${this.bool}`;
|
||||
if (this.isNull()) return "null";
|
||||
if (this.isUndefined()) return "undefined";
|
||||
if (this.isString()) return this.string;
|
||||
if (this.isNumber()) return `${this.number}`;
|
||||
if (this.isBigInt()) return `${this.bigint}`;
|
||||
|
@ -159,6 +166,11 @@ class BasicEvaluatedExpression {
|
|||
return this;
|
||||
}
|
||||
|
||||
setUndefined() {
|
||||
this.type = TypeUndefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
setNull() {
|
||||
this.type = TypeNull;
|
||||
return this;
|
||||
|
|
|
@ -30,6 +30,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
|||
/** @typedef {import("estree").Literal} LiteralNode */
|
||||
/** @typedef {import("estree").LogicalExpression} LogicalExpressionNode */
|
||||
/** @typedef {import("estree").MemberExpression} MemberExpressionNode */
|
||||
/** @typedef {import("estree").MetaProperty} MetaPropertyNode */
|
||||
/** @typedef {import("estree").MethodDefinition} MethodDefinitionNode */
|
||||
/** @typedef {import("estree").ModuleDeclaration} ModuleDeclarationNode */
|
||||
/** @typedef {import("estree").Node} AnyNode */
|
||||
|
@ -105,6 +106,8 @@ const getRootName = expression => {
|
|||
return expression.name;
|
||||
case "ThisExpression":
|
||||
return "this";
|
||||
case "MetaProperty":
|
||||
return "import.meta";
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
|
@ -140,7 +143,7 @@ class JavascriptParser extends Parser {
|
|||
evaluateTypeof: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode], BasicEvaluatedExpression | undefined | null>>} */
|
||||
evaluate: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {HookMap<SyncBailHook<[IdentifierNode | ThisExpressionNode | MemberExpressionNode], BasicEvaluatedExpression | undefined | null>>} */
|
||||
/** @type {HookMap<SyncBailHook<[IdentifierNode | ThisExpressionNode | MemberExpressionNode | MetaPropertyNode], BasicEvaluatedExpression | undefined | null>>} */
|
||||
evaluateIdentifier: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {HookMap<SyncBailHook<[IdentifierNode | ThisExpressionNode | MemberExpressionNode], BasicEvaluatedExpression | undefined | null>>} */
|
||||
evaluateDefinedIdentifier: new HookMap(
|
||||
|
@ -257,12 +260,18 @@ class JavascriptParser extends Parser {
|
|||
),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode], boolean | void>>} */
|
||||
new: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {SyncBailHook<[MetaPropertyNode], boolean | void>} */
|
||||
metaProperty: new SyncBailHook(["metaProperty"]),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode], boolean | void>>} */
|
||||
expression: new HookMap(() => new SyncBailHook(["expression"])),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode, string[]], boolean | void>>} */
|
||||
expressionMemberChain: new HookMap(
|
||||
() => new SyncBailHook(["expression", "members"])
|
||||
),
|
||||
/** @type {HookMap<SyncBailHook<[ExpressionNode, string[]], boolean | void>>} */
|
||||
unhandledExpressionMemberChain: new HookMap(
|
||||
() => new SyncBailHook(["expression", "members"])
|
||||
),
|
||||
/** @type {SyncBailHook<[ExpressionNode], boolean | void>} */
|
||||
expressionConditionalOperator: new SyncBailHook(["expression"]),
|
||||
/** @type {SyncBailHook<[ExpressionNode], boolean | void>} */
|
||||
|
@ -347,6 +356,45 @@ class JavascriptParser extends Parser {
|
|||
.tap("JavascriptParser", _expr => {
|
||||
const expr = /** @type {BinaryExpressionNode} */ (_expr);
|
||||
|
||||
const handleNumberOperation = fn => {
|
||||
const left = this.evaluateExpression(expr.left);
|
||||
const right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(fn(left.number, right.number));
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(fn(left.bigint, right.bigint));
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCompare = fn => {
|
||||
const left = this.evaluateExpression(expr.left);
|
||||
const right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBoolean(fn(left.number, right.number));
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isString() && right.isString()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBoolean(fn(left.string, right.string));
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBoolean(fn(left.bigint, right.bigint));
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
let left;
|
||||
let right;
|
||||
let res;
|
||||
|
@ -486,66 +534,13 @@ class JavascriptParser extends Parser {
|
|||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (expr.operator === "-") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number - right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint - right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
return handleNumberOperation((l, r) => l - r);
|
||||
} else if (expr.operator === "*") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number * right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint * right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
return handleNumberOperation((l, r) => l * r);
|
||||
} else if (expr.operator === "/") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number / right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint / right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
return handleNumberOperation((l, r) => l / r);
|
||||
} else if (expr.operator === "**") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number ** right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint ** right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
return handleNumberOperation((l, r) => l ** r);
|
||||
} else if (expr.operator === "==" || expr.operator === "===") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
|
@ -581,53 +576,14 @@ class JavascriptParser extends Parser {
|
|||
return res.setBoolean(false);
|
||||
}
|
||||
} else if (expr.operator === "&") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number & right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint & right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
return handleNumberOperation((l, r) => l & r);
|
||||
} else if (expr.operator === "|") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number | right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint | right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
return handleNumberOperation((l, r) => l | r);
|
||||
} else if (expr.operator === "^") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number ^ right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint ^ right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
return handleNumberOperation((l, r) => l ^ r);
|
||||
} else if (expr.operator === ">>>") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
const left = this.evaluateExpression(expr.left);
|
||||
const right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (!left.isNumber() || !right.isNumber()) return;
|
||||
res = new BasicEvaluatedExpression();
|
||||
|
@ -635,35 +591,17 @@ class JavascriptParser extends Parser {
|
|||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (expr.operator === ">>") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number >> right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint >> right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
return handleNumberOperation((l, r) => l >> r);
|
||||
} else if (expr.operator === "<<") {
|
||||
left = this.evaluateExpression(expr.left);
|
||||
right = this.evaluateExpression(expr.right);
|
||||
if (!left || !right) return;
|
||||
if (left.isNumber() && right.isNumber()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setNumber(left.number << right.number);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
} else if (left.isBigInt() && right.isBigInt()) {
|
||||
res = new BasicEvaluatedExpression();
|
||||
res.setBigInt(left.bigint << right.bigint);
|
||||
res.setRange(expr.range);
|
||||
return res;
|
||||
}
|
||||
return handleNumberOperation((l, r) => l << r);
|
||||
} else if (expr.operator === "<") {
|
||||
return handleCompare((l, r) => l < r);
|
||||
} else if (expr.operator === ">") {
|
||||
return handleCompare((l, r) => l > r);
|
||||
} else if (expr.operator === "<=") {
|
||||
return handleCompare((l, r) => l <= r);
|
||||
} else if (expr.operator === ">=") {
|
||||
return handleCompare((l, r) => l >= r);
|
||||
}
|
||||
});
|
||||
this.hooks.evaluate
|
||||
|
@ -672,26 +610,39 @@ class JavascriptParser extends Parser {
|
|||
const expr = /** @type {UnaryExpressionNode} */ (_expr);
|
||||
|
||||
if (expr.operator === "typeof") {
|
||||
if (expr.argument.type === "Identifier") {
|
||||
const res = this.callHooksForName(
|
||||
this.hooks.evaluateTypeof,
|
||||
expr.argument.name,
|
||||
expr
|
||||
);
|
||||
if (res !== undefined) return res;
|
||||
}
|
||||
if (expr.argument.type === "MemberExpression") {
|
||||
const res = this.callHooksForExpression(
|
||||
this.hooks.evaluateTypeof,
|
||||
expr.argument,
|
||||
expr
|
||||
);
|
||||
if (res !== undefined) return res;
|
||||
}
|
||||
if (expr.argument.type === "FunctionExpression") {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString("function")
|
||||
.setRange(expr.range);
|
||||
switch (expr.argument.type) {
|
||||
case "Identifier": {
|
||||
const res = this.callHooksForName(
|
||||
this.hooks.evaluateTypeof,
|
||||
expr.argument.name,
|
||||
expr
|
||||
);
|
||||
if (res !== undefined) return res;
|
||||
break;
|
||||
}
|
||||
case "MetaProperty": {
|
||||
const res = this.callHooksForName(
|
||||
this.hooks.evaluateTypeof,
|
||||
"import.meta",
|
||||
expr
|
||||
);
|
||||
if (res !== undefined) return res;
|
||||
break;
|
||||
}
|
||||
case "MemberExpression": {
|
||||
const res = this.callHooksForExpression(
|
||||
this.hooks.evaluateTypeof,
|
||||
expr.argument,
|
||||
expr
|
||||
);
|
||||
if (res !== undefined) return res;
|
||||
break;
|
||||
}
|
||||
case "FunctionExpression": {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString("function")
|
||||
.setRange(expr.range);
|
||||
}
|
||||
}
|
||||
const arg = this.evaluateExpression(expr.argument);
|
||||
if (arg.isString() || arg.isWrapped()) {
|
||||
|
@ -704,6 +655,11 @@ class JavascriptParser extends Parser {
|
|||
.setString("object")
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (arg.isUndefined()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString("undefined")
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (arg.isNumber()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setString("number")
|
||||
|
@ -727,36 +683,16 @@ class JavascriptParser extends Parser {
|
|||
} else if (expr.operator === "!") {
|
||||
const argument = this.evaluateExpression(expr.argument);
|
||||
if (!argument) return;
|
||||
if (argument.isBoolean()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setBoolean(!argument.bool)
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (argument.isNull()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setBoolean(true)
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (argument.isTruthy()) {
|
||||
const bool = argument.asBool();
|
||||
if (bool === true) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setBoolean(false)
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (argument.isFalsy()) {
|
||||
} else if (bool === false) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setBoolean(true)
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (argument.isString()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setBoolean(!argument.string)
|
||||
.setRange(expr.range);
|
||||
}
|
||||
if (argument.isNumber()) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setBoolean(!argument.number)
|
||||
.setRange(expr.range);
|
||||
}
|
||||
} else if (expr.operator === "~") {
|
||||
const argument = this.evaluateExpression(expr.argument);
|
||||
if (!argument) return;
|
||||
|
@ -795,65 +731,85 @@ class JavascriptParser extends Parser {
|
|||
.setString("undefined")
|
||||
.setRange(expr.range);
|
||||
});
|
||||
this.hooks.evaluate.for("Identifier").tap("JavascriptParser", _expr => {
|
||||
const expr = /** @type {IdentifierNode} */ (_expr);
|
||||
|
||||
return this.callHooksForNameWithFallback(
|
||||
this.hooks.evaluateIdentifier,
|
||||
expr.name,
|
||||
name =>
|
||||
new BasicEvaluatedExpression()
|
||||
.setIdentifier(name, this.getVariableInfo(expr.name), () => [])
|
||||
.setRange(expr.range),
|
||||
() => {
|
||||
const hook = this.hooks.evaluateDefinedIdentifier.get(expr.name);
|
||||
if (hook !== undefined) {
|
||||
return hook.call(expr);
|
||||
}
|
||||
},
|
||||
expr
|
||||
);
|
||||
});
|
||||
this.hooks.evaluate.for("ThisExpression").tap("JavascriptParser", _expr => {
|
||||
const expr = /** @type {ThisExpressionNode} */ (_expr);
|
||||
|
||||
return this.callHooksForNameWithFallback(
|
||||
this.hooks.evaluateIdentifier,
|
||||
"this",
|
||||
name =>
|
||||
new BasicEvaluatedExpression()
|
||||
.setIdentifier(name, this.getVariableInfo("this"), () => [])
|
||||
.setRange(expr.range),
|
||||
() => {
|
||||
const hook = this.hooks.evaluateDefinedIdentifier.get("this");
|
||||
if (hook !== undefined) {
|
||||
return hook.call(expr);
|
||||
}
|
||||
},
|
||||
expr
|
||||
);
|
||||
});
|
||||
this.hooks.evaluate
|
||||
.for("MemberExpression")
|
||||
.tap("JavascriptParser", expr => {
|
||||
/** @typedef {{ name: string | VariableInfo, rootInfo: string | VariableInfo, getMembers: () => string[] }} GetInfoResult */
|
||||
/**
|
||||
* @param {string} exprType expression type name
|
||||
* @param {function(ExpressionNode): GetInfoResult | undefined} getInfo get info
|
||||
* @returns {void}
|
||||
*/
|
||||
const tapEvaluateWithVariableInfo = (exprType, getInfo) => {
|
||||
/** @type {ExpressionNode | undefined} */
|
||||
let cachedExpression = undefined;
|
||||
/** @type {GetInfoResult | undefined} */
|
||||
let cachedInfo = undefined;
|
||||
this.hooks.evaluate.for(exprType).tap("JavascriptParser", expr => {
|
||||
const expression = /** @type {MemberExpressionNode} */ (expr);
|
||||
|
||||
return this.callHooksForExpressionWithFallback(
|
||||
this.hooks.evaluateIdentifier,
|
||||
expression,
|
||||
(name, rootInfo, getMembers) =>
|
||||
new BasicEvaluatedExpression()
|
||||
.setIdentifier(name, rootInfo, getMembers)
|
||||
.setRange(expression.range),
|
||||
name => {
|
||||
const hook = this.hooks.evaluateDefinedIdentifier.get(name);
|
||||
if (hook !== undefined) {
|
||||
return hook.call(expression);
|
||||
}
|
||||
},
|
||||
expression
|
||||
);
|
||||
const info = getInfo(expr);
|
||||
if (info !== undefined) {
|
||||
return this.callHooksForInfoWithFallback(
|
||||
this.hooks.evaluateIdentifier,
|
||||
info.name,
|
||||
name => {
|
||||
cachedExpression = expression;
|
||||
cachedInfo = info;
|
||||
},
|
||||
name => {
|
||||
const hook = this.hooks.evaluateDefinedIdentifier.get(name);
|
||||
if (hook !== undefined) {
|
||||
return hook.call(expression);
|
||||
}
|
||||
},
|
||||
expression
|
||||
);
|
||||
}
|
||||
});
|
||||
this.hooks.evaluate
|
||||
.for(exprType)
|
||||
.tap({ name: "JavascriptParser", stage: 100 }, expr => {
|
||||
const info = cachedExpression === expr ? cachedInfo : getInfo(expr);
|
||||
if (info !== undefined) {
|
||||
return new BasicEvaluatedExpression()
|
||||
.setIdentifier(info.name, info.rootInfo, info.getMembers)
|
||||
.setRange(expr.range);
|
||||
}
|
||||
});
|
||||
};
|
||||
tapEvaluateWithVariableInfo("Identifier", expr => {
|
||||
const info = this.getVariableInfo(
|
||||
/** @type {IdentifierNode} */ (expr).name
|
||||
);
|
||||
if (
|
||||
typeof info === "string" ||
|
||||
(info instanceof VariableInfo && typeof info.freeName === "string")
|
||||
) {
|
||||
return { name: info, rootInfo: info, getMembers: () => [] };
|
||||
}
|
||||
});
|
||||
tapEvaluateWithVariableInfo("ThisExpression", expr => {
|
||||
const info = this.getVariableInfo("this");
|
||||
if (
|
||||
typeof info === "string" ||
|
||||
(info instanceof VariableInfo && typeof info.freeName === "string")
|
||||
) {
|
||||
return { name: info, rootInfo: info, getMembers: () => [] };
|
||||
}
|
||||
});
|
||||
this.hooks.evaluate.for("MetaProperty").tap("JavascriptParser", expr => {
|
||||
const metaProperty = /** @type {MetaPropertyNode} */ (expr);
|
||||
|
||||
return this.callHooksForName(
|
||||
this.hooks.evaluateIdentifier,
|
||||
"import.meta",
|
||||
metaProperty
|
||||
);
|
||||
});
|
||||
tapEvaluateWithVariableInfo("MemberExpression", expr =>
|
||||
this.getMemberExpressionInfo(/** @type {MemberExpressionNode} */ (expr), [
|
||||
"expression"
|
||||
])
|
||||
);
|
||||
|
||||
this.hooks.evaluate.for("CallExpression").tap("JavascriptParser", _expr => {
|
||||
const expr = /** @type {CallExpressionNode} */ (_expr);
|
||||
if (
|
||||
|
@ -878,6 +834,30 @@ class JavascriptParser extends Parser {
|
|||
return hook.call(expr, param);
|
||||
}
|
||||
});
|
||||
this.hooks.evaluateCallExpressionMember
|
||||
.for("indexOf")
|
||||
.tap("JavascriptParser", (expr, param) => {
|
||||
if (!param.isString()) return;
|
||||
if (expr.arguments.length === 0) return;
|
||||
const [arg1, arg2] = expr.arguments;
|
||||
if (arg1.type === "SpreadElement") return;
|
||||
const arg1Eval = this.evaluateExpression(arg1);
|
||||
if (!arg1Eval.isString()) return;
|
||||
const arg1Value = arg1Eval.string;
|
||||
|
||||
let result;
|
||||
if (arg2) {
|
||||
if (arg2.type === "SpreadElement") return;
|
||||
const arg2Eval = this.evaluateExpression(arg2);
|
||||
if (!arg2Eval.isNumber()) return;
|
||||
result = param.string.indexOf(arg1Value, arg2Eval.number);
|
||||
} else {
|
||||
result = param.string.indexOf(arg1Value);
|
||||
}
|
||||
return new BasicEvaluatedExpression()
|
||||
.setNumber(result)
|
||||
.setRange(expr.range);
|
||||
});
|
||||
this.hooks.evaluateCallExpressionMember
|
||||
.for("replace")
|
||||
.tap("JavascriptParser", (expr, param) => {
|
||||
|
@ -1800,10 +1780,7 @@ class JavascriptParser extends Parser {
|
|||
// renaming with "var a = b;"
|
||||
const hook = this.hooks.rename.get(renameIdentifier);
|
||||
if (hook === undefined || !hook.call(declarator.init)) {
|
||||
this.setVariable(
|
||||
declarator.id.name,
|
||||
this.getVariableInfo(renameIdentifier)
|
||||
);
|
||||
this.setVariable(declarator.id.name, renameIdentifier);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1956,6 +1933,9 @@ class JavascriptParser extends Parser {
|
|||
case "LogicalExpression":
|
||||
this.walkLogicalExpression(expression);
|
||||
break;
|
||||
case "MetaProperty":
|
||||
this.walkMetaProperty(expression);
|
||||
break;
|
||||
case "MemberExpression":
|
||||
this.walkMemberExpression(expression);
|
||||
break;
|
||||
|
@ -2389,7 +2369,14 @@ class JavascriptParser extends Parser {
|
|||
expression,
|
||||
exprInfo.name,
|
||||
exprInfo.rootInfo,
|
||||
members
|
||||
members.slice(),
|
||||
() =>
|
||||
this.callHooksForInfo(
|
||||
this.hooks.unhandledExpressionMemberChain,
|
||||
exprInfo.rootInfo,
|
||||
expression,
|
||||
members
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -2414,7 +2401,13 @@ class JavascriptParser extends Parser {
|
|||
if (expression.computed === true) this.walkExpression(expression.property);
|
||||
}
|
||||
|
||||
walkMemberExpressionWithExpressionName(expression, name, rootInfo, members) {
|
||||
walkMemberExpressionWithExpressionName(
|
||||
expression,
|
||||
name,
|
||||
rootInfo,
|
||||
members,
|
||||
onUnhandled
|
||||
) {
|
||||
const result = this.callHooksForInfo(
|
||||
this.hooks.expression,
|
||||
name,
|
||||
|
@ -2432,9 +2425,10 @@ class JavascriptParser extends Parser {
|
|||
expression.object,
|
||||
name,
|
||||
rootInfo,
|
||||
members
|
||||
members,
|
||||
onUnhandled
|
||||
);
|
||||
} else {
|
||||
} else if (!onUnhandled || !onUnhandled()) {
|
||||
this.walkExpression(expression.object);
|
||||
}
|
||||
if (expression.computed === true) this.walkExpression(expression.property);
|
||||
|
@ -2448,6 +2442,13 @@ class JavascriptParser extends Parser {
|
|||
this.callHooksForName(this.hooks.expression, expression.name, expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MetaPropertyNode} metaProperty meta property
|
||||
*/
|
||||
walkMetaProperty(metaProperty) {
|
||||
this.hooks.metaProperty.call(metaProperty);
|
||||
}
|
||||
|
||||
callHooksForExpression(hookMap, expr, ...args) {
|
||||
const exprName = this.getMemberExpressionInfo(expr, ["expression"]);
|
||||
if (exprName !== undefined) {
|
||||
|
@ -3157,6 +3158,7 @@ class JavascriptParser extends Parser {
|
|||
};
|
||||
}
|
||||
case "Identifier":
|
||||
case "MetaProperty":
|
||||
case "ThisExpression": {
|
||||
if (!possibleTypes.has("expression")) return undefined;
|
||||
const rootName = getRootName(object);
|
||||
|
|
|
@ -9,6 +9,15 @@ const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
|
|||
const ConstDependency = require("../dependencies/ConstDependency");
|
||||
const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
||||
|
||||
/** @typedef {import("estree").Expression} Expression */
|
||||
/** @typedef {import("./JavascriptParser")} JavascriptParser */
|
||||
|
||||
/**
|
||||
* @param {JavascriptParser} parser the parser
|
||||
* @param {string} value the const value
|
||||
* @param {string[]=} runtimeRequirements runtime requirements
|
||||
* @returns {function(Expression): true} plugin function
|
||||
*/
|
||||
exports.toConstantDependency = (parser, value, runtimeRequirements) => {
|
||||
return function constDependency(expr) {
|
||||
const dep = new ConstDependency(value, expr.range, runtimeRequirements);
|
||||
|
@ -18,12 +27,30 @@ exports.toConstantDependency = (parser, value, runtimeRequirements) => {
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} value the string value
|
||||
* @returns {function(Expression): BasicEvaluatedExpression} plugin function
|
||||
*/
|
||||
exports.evaluateToString = value => {
|
||||
return function stringExpression(expr) {
|
||||
return new BasicEvaluatedExpression().setString(value).setRange(expr.range);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} value the number value
|
||||
* @returns {function(Expression): BasicEvaluatedExpression} plugin function
|
||||
*/
|
||||
exports.evaluateToNumber = value => {
|
||||
return function stringExpression(expr) {
|
||||
return new BasicEvaluatedExpression().setNumber(value).setRange(expr.range);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} value the boolean value
|
||||
* @returns {function(Expression): BasicEvaluatedExpression} plugin function
|
||||
*/
|
||||
exports.evaluateToBoolean = value => {
|
||||
return function booleanExpression(expr) {
|
||||
return new BasicEvaluatedExpression()
|
||||
|
|
|
@ -108,8 +108,10 @@ module.exports = {
|
|||
require("../dependencies/ModuleHotAcceptDependency"),
|
||||
"dependencies/ModuleHotDeclineDependency": () =>
|
||||
require("../dependencies/ModuleHotDeclineDependency"),
|
||||
"dependencies/ModuleHotDependency": () =>
|
||||
require("../dependencies/ModuleHotDependency"),
|
||||
"dependencies/ImportMetaHotAcceptDependency": () =>
|
||||
require("../dependencies/ImportMetaHotAcceptDependency"),
|
||||
"dependencies/ImportMetaHotDeclineDependency": () =>
|
||||
require("../dependencies/ImportMetaHotDeclineDependency"),
|
||||
"dependencies/ProvidedDependency": () =>
|
||||
require("../dependencies/ProvidedDependency"),
|
||||
"dependencies/PureExpressionDependency": () =>
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
const { pathToFileURL } = require("url");
|
||||
const url = pathToFileURL(
|
||||
require("path").resolve("./test/cases/esm/import-meta/index.js")
|
||||
).toString();
|
||||
const webpackVersion = parseInt(
|
||||
require("../../../../package.json").version,
|
||||
10
|
||||
);
|
||||
|
||||
it('typeof import.meta === "object"', () => {
|
||||
expect(typeof import.meta).toBe("object");
|
||||
if (typeof import.meta !== "object") require("fail");
|
||||
});
|
||||
|
||||
it('typeof import.meta.url === "string"', () => {
|
||||
expect(typeof import.meta.url).toBe("string");
|
||||
if (typeof import.meta.url !== "string") require("fail");
|
||||
});
|
||||
|
||||
it('typeof import.meta.webpack === "number"', () => {
|
||||
expect(typeof import.meta.webpack).toBe("number");
|
||||
if (typeof import.meta.webpack !== "number") require("fail");
|
||||
});
|
||||
|
||||
it("should return correct import.meta.url", () => {
|
||||
expect(import.meta.url).toBe(url);
|
||||
expect(import.meta["url"]).toBe(url);
|
||||
expect("my" + import.meta.url).toBe("my" + url);
|
||||
if (import.meta.url.indexOf("index.js") === -1) require("fail");
|
||||
});
|
||||
|
||||
it("should return correct import.meta.webpack", () => {
|
||||
expect(import.meta.webpack).toBe(webpackVersion);
|
||||
if (import.meta.webpack < 5) require("fail");
|
||||
if (import.meta.webpack >= 5) {
|
||||
} else {
|
||||
require("fail");
|
||||
}
|
||||
});
|
||||
|
||||
it("should return undefined for unknown property", () => {
|
||||
expect(import.meta.other).toBe(undefined);
|
||||
if (typeof import.meta.other !== "undefined") require("fail");
|
||||
expect(() => import.meta.other.other.other).toThrowError();
|
||||
// if (typeof import.meta.other.other.other !== "undefined") require("fail");
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
export { value } from "./file";
|
|
@ -0,0 +1 @@
|
|||
export { value } from "./file";
|
|
@ -0,0 +1,3 @@
|
|||
export var value = 1;
|
||||
---
|
||||
export var value = 2;
|
|
@ -0,0 +1,18 @@
|
|||
it("should import a changed chunk", (done) => {
|
||||
import("./chunk").then((chunk) => {
|
||||
expect(chunk.value).toBe(1);
|
||||
import("./chunk2").then((chunk2) => {
|
||||
expect(chunk2.value).toBe(1);
|
||||
NEXT(require("../../update")(done));
|
||||
import.meta.webpackHot.accept(["./chunk", "./chunk2"], () => {
|
||||
import("./chunk").then((chunk) => {
|
||||
expect(chunk.value).toBe(2);
|
||||
import("./chunk2").then((chunk2) => {
|
||||
expect(chunk2.value).toBe(2);
|
||||
done();
|
||||
}).catch(done);
|
||||
}).catch(done);
|
||||
});
|
||||
}).catch(done);
|
||||
}).catch(done);
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
import vendor from "vendor";
|
||||
import.meta.webpackHot.accept("vendor");
|
||||
it("should hot update a splitted initial chunk", function (done) {
|
||||
expect(vendor).toBe("1");
|
||||
NEXT(
|
||||
require("../../update")(done, true, () => {
|
||||
expect(vendor).toBe("2");
|
||||
done();
|
||||
})
|
||||
);
|
||||
});
|
3
test/hotCases/chunks/split-chunks-webpackhot/node_modules/vendor.js
generated
vendored
Normal file
3
test/hotCases/chunks/split-chunks-webpackhot/node_modules/vendor.js
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = "1";
|
||||
---
|
||||
module.exports = "2";
|
|
@ -0,0 +1,12 @@
|
|||
module.exports = {
|
||||
output: {
|
||||
filename: "[name].js"
|
||||
},
|
||||
optimization: {
|
||||
chunkIds: "total-size",
|
||||
splitChunks: {
|
||||
chunks: "all",
|
||||
minSize: 0
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,3 +1,3 @@
|
|||
module.exports = "1";
|
||||
---
|
||||
module.exports = "2";
|
||||
module.exports = "2";
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import x from "./module";
|
||||
|
||||
it("should have correct this context", (done) => {
|
||||
expect(x).toEqual("ok1");
|
||||
|
||||
(function() {
|
||||
import.meta.webpackHot.accept("./module", () => {
|
||||
expect(x).toEqual("ok2");
|
||||
expect(this).toEqual({ ok: true });
|
||||
done();
|
||||
});
|
||||
}).call({ ok: true });
|
||||
|
||||
NEXT(require("../../update")(done));
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
export default "ok1";
|
||||
---
|
||||
export default "ok2";
|
|
@ -2,7 +2,7 @@ import x from "./module";
|
|||
|
||||
it("should have correct this context in accept handler", (done) => {
|
||||
expect(x).toEqual("ok1");
|
||||
|
||||
|
||||
(function() {
|
||||
module.hot.accept("./module", () => {
|
||||
expect(x).toEqual("ok2");
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import b from "./b";
|
||||
|
||||
export default b;
|
||||
|
||||
if(import.meta.webpackHot) {
|
||||
import.meta.webpackHot.decline("./b");
|
||||
import.meta.webpackHot.accept();
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export { default } from "./c"
|
|
@ -0,0 +1,3 @@
|
|||
export default 1;
|
||||
---
|
||||
export default 2;
|
|
@ -0,0 +1,14 @@
|
|||
import a from "./a";
|
||||
|
||||
it("should abort when module is declined by parent", (done) => {
|
||||
expect(a).toBe(1);
|
||||
NEXT(require("../../update")((err) => {
|
||||
try {
|
||||
expect(err.message).toMatch(/Aborted because of declined dependency: \.\/b\.js in \.\/a\.js/);
|
||||
expect(err.message).toMatch(/Update propagation: \.\/c\.js -> \.\/b\.js -> \.\/a\.js/);
|
||||
done();
|
||||
} catch(e) {
|
||||
done(e);
|
||||
}
|
||||
}));
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
import {val} from "./module";
|
||||
|
||||
it("should accept changes", (done) => {
|
||||
expect(val).toBe(1);
|
||||
NEXT(require("../../update")(done));
|
||||
done();
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
import {value} from "dep1";
|
||||
|
||||
export const val = value;
|
||||
|
||||
import.meta.webpackHot.accept("dep1");
|
1
test/hotCases/esm-dependency-import/import-meta-webpack-hot/node_modules/dep1/exports.js
generated
vendored
Normal file
1
test/hotCases/esm-dependency-import/import-meta-webpack-hot/node_modules/dep1/exports.js
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export {value} from "./file";
|
3
test/hotCases/esm-dependency-import/import-meta-webpack-hot/node_modules/dep1/file.js
generated
vendored
Normal file
3
test/hotCases/esm-dependency-import/import-meta-webpack-hot/node_modules/dep1/file.js
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
export var value = 1;
|
||||
---
|
||||
export var value = 2;
|
5
test/hotCases/esm-dependency-import/import-meta-webpack-hot/node_modules/dep1/main.js
generated
vendored
Normal file
5
test/hotCases/esm-dependency-import/import-meta-webpack-hot/node_modules/dep1/main.js
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
(() => {
|
||||
throw new Error("should not resolve");
|
||||
})();
|
||||
|
||||
export default 1;
|
6
test/hotCases/esm-dependency-import/import-meta-webpack-hot/node_modules/dep1/package.json
generated
vendored
Normal file
6
test/hotCases/esm-dependency-import/import-meta-webpack-hot/node_modules/dep1/package.json
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"exports": {
|
||||
"import": "./exports.js",
|
||||
"default": "./main.js"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import {val} from "./module";
|
||||
|
||||
it("should fail accept changes", (done) => {
|
||||
expect(val).toBe(1);
|
||||
NEXT(require("../../update")((err) => {
|
||||
try {
|
||||
expect(err.message).toMatch(/Aborted because \.\/node_modules\/dep1\/file.js is not accepted/);
|
||||
expect(err.message).toMatch(/Update propagation: \.\/node_modules\/dep1\/file.js -> \.\/node_modules\/dep1\/exports\.js -> \.\/module\.js -> \.\/index.js/);
|
||||
done();
|
||||
} catch(e) {
|
||||
done(e);
|
||||
}
|
||||
}));
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
import {value} from "dep1";
|
||||
|
||||
export const val = value;
|
||||
|
||||
module.hot.accept("dep1");
|
1
test/hotCases/esm-dependency-import/module-hot/node_modules/dep1/exports.js
generated
vendored
Normal file
1
test/hotCases/esm-dependency-import/module-hot/node_modules/dep1/exports.js
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export {value} from "./file";
|
3
test/hotCases/esm-dependency-import/module-hot/node_modules/dep1/file.js
generated
vendored
Normal file
3
test/hotCases/esm-dependency-import/module-hot/node_modules/dep1/file.js
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
export var value = 1;
|
||||
---
|
||||
export var value = 2;
|
5
test/hotCases/esm-dependency-import/module-hot/node_modules/dep1/main.js
generated
vendored
Normal file
5
test/hotCases/esm-dependency-import/module-hot/node_modules/dep1/main.js
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
(() => {
|
||||
throw new Error("should not resolve");
|
||||
})();
|
||||
|
||||
export default 1;
|
6
test/hotCases/esm-dependency-import/module-hot/node_modules/dep1/package.json
generated
vendored
Normal file
6
test/hotCases/esm-dependency-import/module-hot/node_modules/dep1/package.json
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"exports": {
|
||||
"import": "./exports.js",
|
||||
"default": "./main.js"
|
||||
}
|
||||
}
|
|
@ -333,6 +333,7 @@ declare abstract class BasicEvaluatedExpression {
|
|||
getMembers: any;
|
||||
expression: any;
|
||||
isNull(): boolean;
|
||||
isUndefined(): boolean;
|
||||
isString(): boolean;
|
||||
isNumber(): boolean;
|
||||
isBigInt(): boolean;
|
||||
|
@ -349,6 +350,7 @@ declare abstract class BasicEvaluatedExpression {
|
|||
asBool(): any;
|
||||
asString(): any;
|
||||
setString(string?: any): BasicEvaluatedExpression;
|
||||
setUndefined(): BasicEvaluatedExpression;
|
||||
setNull(): BasicEvaluatedExpression;
|
||||
setNumber(number?: any): BasicEvaluatedExpression;
|
||||
setBigInt(bigint?: any): BasicEvaluatedExpression;
|
||||
|
@ -3020,7 +3022,7 @@ declare abstract class JavascriptParser extends Parser {
|
|||
evaluate: HookMap<SyncBailHook<[Expression], BasicEvaluatedExpression>>;
|
||||
evaluateIdentifier: HookMap<
|
||||
SyncBailHook<
|
||||
[ThisExpression | MemberExpression | Identifier],
|
||||
[ThisExpression | MemberExpression | MetaProperty | Identifier],
|
||||
BasicEvaluatedExpression
|
||||
>
|
||||
>;
|
||||
|
@ -3201,10 +3203,14 @@ declare abstract class JavascriptParser extends Parser {
|
|||
>
|
||||
>;
|
||||
new: HookMap<SyncBailHook<[Expression], boolean | void>>;
|
||||
metaProperty: SyncBailHook<[MetaProperty], boolean | void>;
|
||||
expression: HookMap<SyncBailHook<[Expression], boolean | void>>;
|
||||
expressionMemberChain: HookMap<
|
||||
SyncBailHook<[Expression, string[]], boolean | void>
|
||||
>;
|
||||
unhandledExpressionMemberChain: HookMap<
|
||||
SyncBailHook<[Expression, string[]], boolean | void>
|
||||
>;
|
||||
expressionConditionalOperator: SyncBailHook<[Expression], boolean | void>;
|
||||
expressionLogicalOperator: SyncBailHook<[Expression], boolean | void>;
|
||||
program: SyncBailHook<[Program, Comment[]], boolean | void>;
|
||||
|
@ -3307,10 +3313,12 @@ declare abstract class JavascriptParser extends Parser {
|
|||
expression?: any,
|
||||
name?: any,
|
||||
rootInfo?: any,
|
||||
members?: any
|
||||
members?: any,
|
||||
onUnhandled?: any
|
||||
): void;
|
||||
walkThisExpression(expression?: any): void;
|
||||
walkIdentifier(expression?: any): void;
|
||||
walkMetaProperty(metaProperty: MetaProperty): void;
|
||||
callHooksForExpression(hookMap: any, expr: any, ...args: any[]): any;
|
||||
callHooksForExpressionWithFallback<T, R>(
|
||||
hookMap: HookMap<SyncBailHook<T, R>>,
|
||||
|
|
Loading…
Reference in New Issue