You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
6.7 KiB
253 lines
6.7 KiB
/* |
|
MIT License http://www.opensource.org/licenses/mit-license.php |
|
Author Tobias Koppers @sokra |
|
*/ |
|
|
|
"use strict"; |
|
|
|
const RuntimeGlobals = require("./RuntimeGlobals"); |
|
const WebpackError = require("./WebpackError"); |
|
const ConstDependency = require("./dependencies/ConstDependency"); |
|
const BasicEvaluatedExpression = require("./javascript/BasicEvaluatedExpression"); |
|
const { |
|
toConstantDependency, |
|
evaluateToString |
|
} = require("./javascript/JavascriptParserHelpers"); |
|
const ChunkNameRuntimeModule = require("./runtime/ChunkNameRuntimeModule"); |
|
const GetFullHashRuntimeModule = require("./runtime/GetFullHashRuntimeModule"); |
|
|
|
/** @typedef {import("./Compiler")} Compiler */ |
|
/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */ |
|
|
|
/* eslint-disable camelcase */ |
|
const REPLACEMENTS = { |
|
__webpack_require__: { |
|
expr: RuntimeGlobals.require, |
|
req: [RuntimeGlobals.require], |
|
type: "function", |
|
assign: false |
|
}, |
|
__webpack_public_path__: { |
|
expr: RuntimeGlobals.publicPath, |
|
req: [RuntimeGlobals.publicPath], |
|
type: "string", |
|
assign: true |
|
}, |
|
__webpack_base_uri__: { |
|
expr: RuntimeGlobals.baseURI, |
|
req: [RuntimeGlobals.baseURI], |
|
type: "string", |
|
assign: true |
|
}, |
|
__webpack_modules__: { |
|
expr: RuntimeGlobals.moduleFactories, |
|
req: [RuntimeGlobals.moduleFactories], |
|
type: "object", |
|
assign: false |
|
}, |
|
__webpack_chunk_load__: { |
|
expr: RuntimeGlobals.ensureChunk, |
|
req: [RuntimeGlobals.ensureChunk], |
|
type: "function", |
|
assign: true |
|
}, |
|
__non_webpack_require__: { |
|
expr: "require", |
|
req: null, |
|
type: undefined, // type is not known, depends on environment |
|
assign: true |
|
}, |
|
__webpack_nonce__: { |
|
expr: RuntimeGlobals.scriptNonce, |
|
req: [RuntimeGlobals.scriptNonce], |
|
type: "string", |
|
assign: true |
|
}, |
|
__webpack_hash__: { |
|
expr: `${RuntimeGlobals.getFullHash}()`, |
|
req: [RuntimeGlobals.getFullHash], |
|
type: "string", |
|
assign: false |
|
}, |
|
__webpack_chunkname__: { |
|
expr: RuntimeGlobals.chunkName, |
|
req: [RuntimeGlobals.chunkName], |
|
type: "string", |
|
assign: false |
|
}, |
|
__webpack_get_script_filename__: { |
|
expr: RuntimeGlobals.getChunkScriptFilename, |
|
req: [RuntimeGlobals.getChunkScriptFilename], |
|
type: "function", |
|
assign: true |
|
}, |
|
__webpack_runtime_id__: { |
|
expr: RuntimeGlobals.runtimeId, |
|
req: [RuntimeGlobals.runtimeId], |
|
assign: false |
|
}, |
|
"require.onError": { |
|
expr: RuntimeGlobals.uncaughtErrorHandler, |
|
req: [RuntimeGlobals.uncaughtErrorHandler], |
|
type: undefined, // type is not known, could be function or undefined |
|
assign: true // is never a pattern |
|
}, |
|
__system_context__: { |
|
expr: RuntimeGlobals.systemContext, |
|
req: [RuntimeGlobals.systemContext], |
|
type: "object", |
|
assign: false |
|
}, |
|
__webpack_share_scopes__: { |
|
expr: RuntimeGlobals.shareScopeMap, |
|
req: [RuntimeGlobals.shareScopeMap], |
|
type: "object", |
|
assign: false |
|
}, |
|
__webpack_init_sharing__: { |
|
expr: RuntimeGlobals.initializeSharing, |
|
req: [RuntimeGlobals.initializeSharing], |
|
type: "function", |
|
assign: true |
|
} |
|
}; |
|
/* eslint-enable camelcase */ |
|
|
|
class APIPlugin { |
|
/** |
|
* Apply the plugin |
|
* @param {Compiler} compiler the compiler instance |
|
* @returns {void} |
|
*/ |
|
apply(compiler) { |
|
compiler.hooks.compilation.tap( |
|
"APIPlugin", |
|
(compilation, { normalModuleFactory }) => { |
|
compilation.dependencyTemplates.set( |
|
ConstDependency, |
|
new ConstDependency.Template() |
|
); |
|
|
|
compilation.hooks.runtimeRequirementInTree |
|
.for(RuntimeGlobals.chunkName) |
|
.tap("APIPlugin", chunk => { |
|
compilation.addRuntimeModule( |
|
chunk, |
|
new ChunkNameRuntimeModule(chunk.name) |
|
); |
|
return true; |
|
}); |
|
|
|
compilation.hooks.runtimeRequirementInTree |
|
.for(RuntimeGlobals.getFullHash) |
|
.tap("APIPlugin", (chunk, set) => { |
|
compilation.addRuntimeModule(chunk, new GetFullHashRuntimeModule()); |
|
return true; |
|
}); |
|
|
|
/** |
|
* @param {JavascriptParser} parser the parser |
|
*/ |
|
const handler = parser => { |
|
Object.keys(REPLACEMENTS).forEach(key => { |
|
const info = REPLACEMENTS[key]; |
|
parser.hooks.expression |
|
.for(key) |
|
.tap( |
|
"APIPlugin", |
|
toConstantDependency(parser, info.expr, info.req) |
|
); |
|
if (info.assign === false) { |
|
parser.hooks.assign.for(key).tap("APIPlugin", expr => { |
|
const err = new WebpackError(`${key} must not be assigned`); |
|
err.loc = expr.loc; |
|
throw err; |
|
}); |
|
} |
|
if (info.type) { |
|
parser.hooks.evaluateTypeof |
|
.for(key) |
|
.tap("APIPlugin", evaluateToString(info.type)); |
|
} |
|
}); |
|
|
|
parser.hooks.expression |
|
.for("__webpack_layer__") |
|
.tap("APIPlugin", expr => { |
|
const dep = new ConstDependency( |
|
JSON.stringify(parser.state.module.layer), |
|
expr.range |
|
); |
|
dep.loc = expr.loc; |
|
parser.state.module.addPresentationalDependency(dep); |
|
return true; |
|
}); |
|
parser.hooks.evaluateIdentifier |
|
.for("__webpack_layer__") |
|
.tap("APIPlugin", expr => |
|
(parser.state.module.layer === null |
|
? new BasicEvaluatedExpression().setNull() |
|
: new BasicEvaluatedExpression().setString( |
|
parser.state.module.layer |
|
) |
|
).setRange(expr.range) |
|
); |
|
parser.hooks.evaluateTypeof |
|
.for("__webpack_layer__") |
|
.tap("APIPlugin", expr => |
|
new BasicEvaluatedExpression() |
|
.setString( |
|
parser.state.module.layer === null ? "object" : "string" |
|
) |
|
.setRange(expr.range) |
|
); |
|
|
|
parser.hooks.expression |
|
.for("__webpack_module__.id") |
|
.tap("APIPlugin", expr => { |
|
parser.state.module.buildInfo.moduleConcatenationBailout = |
|
"__webpack_module__.id"; |
|
const dep = new ConstDependency( |
|
parser.state.module.moduleArgument + ".id", |
|
expr.range, |
|
[RuntimeGlobals.moduleId] |
|
); |
|
dep.loc = expr.loc; |
|
parser.state.module.addPresentationalDependency(dep); |
|
return true; |
|
}); |
|
|
|
parser.hooks.expression |
|
.for("__webpack_module__") |
|
.tap("APIPlugin", expr => { |
|
parser.state.module.buildInfo.moduleConcatenationBailout = |
|
"__webpack_module__"; |
|
const dep = new ConstDependency( |
|
parser.state.module.moduleArgument, |
|
expr.range, |
|
[RuntimeGlobals.module] |
|
); |
|
dep.loc = expr.loc; |
|
parser.state.module.addPresentationalDependency(dep); |
|
return true; |
|
}); |
|
parser.hooks.evaluateTypeof |
|
.for("__webpack_module__") |
|
.tap("APIPlugin", evaluateToString("object")); |
|
}; |
|
|
|
normalModuleFactory.hooks.parser |
|
.for("javascript/auto") |
|
.tap("APIPlugin", handler); |
|
normalModuleFactory.hooks.parser |
|
.for("javascript/dynamic") |
|
.tap("APIPlugin", handler); |
|
normalModuleFactory.hooks.parser |
|
.for("javascript/esm") |
|
.tap("APIPlugin", handler); |
|
} |
|
); |
|
} |
|
} |
|
|
|
module.exports = APIPlugin;
|
|
|