summaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/DefinePlugin.js
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2023-11-05 17:16:09 +0800
committerlittleblack111 <littleblack11111@gmail.com>2023-11-05 17:16:09 +0800
commitd1d9f00b1bd660842addf5e6b1d1b64c852a9eea (patch)
tree60fb37ae73a1109d95301de5ec9b61b5726a4b61 /node_modules/webpack/lib/DefinePlugin.js
parent7c85166c4cbdd862fc4252007d2df5befcbc2a58 (diff)
added hover prefixer
Diffstat (limited to 'node_modules/webpack/lib/DefinePlugin.js')
-rw-r--r--node_modules/webpack/lib/DefinePlugin.js667
1 files changed, 667 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/DefinePlugin.js b/node_modules/webpack/lib/DefinePlugin.js
new file mode 100644
index 00000000..f604523e
--- /dev/null
+++ b/node_modules/webpack/lib/DefinePlugin.js
@@ -0,0 +1,667 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const {
+ JAVASCRIPT_MODULE_TYPE_AUTO,
+ JAVASCRIPT_MODULE_TYPE_ESM,
+ JAVASCRIPT_MODULE_TYPE_DYNAMIC
+} = require("./ModuleTypeConstants");
+const RuntimeGlobals = require("./RuntimeGlobals");
+const WebpackError = require("./WebpackError");
+const ConstDependency = require("./dependencies/ConstDependency");
+const BasicEvaluatedExpression = require("./javascript/BasicEvaluatedExpression");
+
+const {
+ evaluateToString,
+ toConstantDependency
+} = require("./javascript/JavascriptParserHelpers");
+const createHash = require("./util/createHash");
+
+/** @typedef {import("estree").Expression} Expression */
+/** @typedef {import("./Compiler")} Compiler */
+/** @typedef {import("./NormalModule")} NormalModule */
+/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
+/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
+/** @typedef {import("./logging/Logger").Logger} Logger */
+
+/** @typedef {null|undefined|RegExp|Function|string|number|boolean|bigint|undefined} CodeValuePrimitive */
+/** @typedef {RecursiveArrayOrRecord<CodeValuePrimitive|RuntimeValue>} CodeValue */
+
+/**
+ * @typedef {Object} RuntimeValueOptions
+ * @property {string[]=} fileDependencies
+ * @property {string[]=} contextDependencies
+ * @property {string[]=} missingDependencies
+ * @property {string[]=} buildDependencies
+ * @property {string|function(): string=} version
+ */
+
+class RuntimeValue {
+ /**
+ * @param {function({ module: NormalModule, key: string, readonly version: string | undefined }): CodeValuePrimitive} fn generator function
+ * @param {true | string[] | RuntimeValueOptions=} options options
+ */
+ constructor(fn, options) {
+ this.fn = fn;
+ if (Array.isArray(options)) {
+ options = {
+ fileDependencies: options
+ };
+ }
+ this.options = options || {};
+ }
+
+ get fileDependencies() {
+ return this.options === true ? true : this.options.fileDependencies;
+ }
+
+ /**
+ * @param {JavascriptParser} parser the parser
+ * @param {Map<string, string | Set<string>>} valueCacheVersions valueCacheVersions
+ * @param {string} key the defined key
+ * @returns {CodeValuePrimitive} code
+ */
+ exec(parser, valueCacheVersions, key) {
+ const buildInfo = parser.state.module.buildInfo;
+ if (this.options === true) {
+ buildInfo.cacheable = false;
+ } else {
+ if (this.options.fileDependencies) {
+ for (const dep of this.options.fileDependencies) {
+ buildInfo.fileDependencies.add(dep);
+ }
+ }
+ if (this.options.contextDependencies) {
+ for (const dep of this.options.contextDependencies) {
+ buildInfo.contextDependencies.add(dep);
+ }
+ }
+ if (this.options.missingDependencies) {
+ for (const dep of this.options.missingDependencies) {
+ buildInfo.missingDependencies.add(dep);
+ }
+ }
+ if (this.options.buildDependencies) {
+ for (const dep of this.options.buildDependencies) {
+ buildInfo.buildDependencies.add(dep);
+ }
+ }
+ }
+
+ return this.fn({
+ module: parser.state.module,
+ key,
+ get version() {
+ return /** @type {string} */ (
+ valueCacheVersions.get(VALUE_DEP_PREFIX + key)
+ );
+ }
+ });
+ }
+
+ getCacheVersion() {
+ return this.options === true
+ ? undefined
+ : (typeof this.options.version === "function"
+ ? this.options.version()
+ : this.options.version) || "unset";
+ }
+}
+
+/**
+ * @param {any[]|{[k: string]: any}} obj obj
+ * @param {JavascriptParser} parser Parser
+ * @param {Map<string, string | Set<string>>} valueCacheVersions valueCacheVersions
+ * @param {string} key the defined key
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {Logger} logger the logger object
+ * @param {boolean|undefined|null=} asiSafe asi safe (undefined: unknown, null: unneeded)
+ * @param {Set<string>|undefined=} objKeys used keys
+ * @returns {string} code converted to string that evaluates
+ */
+const stringifyObj = (
+ obj,
+ parser,
+ valueCacheVersions,
+ key,
+ runtimeTemplate,
+ logger,
+ asiSafe,
+ objKeys
+) => {
+ let code;
+ let arr = Array.isArray(obj);
+ if (arr) {
+ code = `[${obj
+ .map(code =>
+ toCode(
+ code,
+ parser,
+ valueCacheVersions,
+ key,
+ runtimeTemplate,
+ logger,
+ null
+ )
+ )
+ .join(",")}]`;
+ } else {
+ let keys = Object.keys(obj);
+ if (objKeys) {
+ if (objKeys.size === 0) keys = [];
+ else keys = keys.filter(k => objKeys.has(k));
+ }
+ code = `{${keys
+ .map(key => {
+ const code = obj[key];
+ return (
+ JSON.stringify(key) +
+ ":" +
+ toCode(
+ code,
+ parser,
+ valueCacheVersions,
+ key,
+ runtimeTemplate,
+ logger,
+ null
+ )
+ );
+ })
+ .join(",")}}`;
+ }
+
+ switch (asiSafe) {
+ case null:
+ return code;
+ case true:
+ return arr ? code : `(${code})`;
+ case false:
+ return arr ? `;${code}` : `;(${code})`;
+ default:
+ return `/*#__PURE__*/Object(${code})`;
+ }
+};
+
+/**
+ * Convert code to a string that evaluates
+ * @param {CodeValue} code Code to evaluate
+ * @param {JavascriptParser} parser Parser
+ * @param {Map<string, string | Set<string>>} valueCacheVersions valueCacheVersions
+ * @param {string} key the defined key
+ * @param {RuntimeTemplate} runtimeTemplate the runtime template
+ * @param {Logger} logger the logger object
+ * @param {boolean|undefined|null=} asiSafe asi safe (undefined: unknown, null: unneeded)
+ * @param {Set<string>|undefined=} objKeys used keys
+ * @returns {string} code converted to string that evaluates
+ */
+const toCode = (
+ code,
+ parser,
+ valueCacheVersions,
+ key,
+ runtimeTemplate,
+ logger,
+ asiSafe,
+ objKeys
+) => {
+ const transformToCode = () => {
+ if (code === null) {
+ return "null";
+ }
+ if (code === undefined) {
+ return "undefined";
+ }
+ if (Object.is(code, -0)) {
+ return "-0";
+ }
+ if (code instanceof RuntimeValue) {
+ return toCode(
+ code.exec(parser, valueCacheVersions, key),
+ parser,
+ valueCacheVersions,
+ key,
+ runtimeTemplate,
+ logger,
+ asiSafe
+ );
+ }
+ if (code instanceof RegExp && code.toString) {
+ return code.toString();
+ }
+ if (typeof code === "function" && code.toString) {
+ return "(" + code.toString() + ")";
+ }
+ if (typeof code === "object") {
+ return stringifyObj(
+ code,
+ parser,
+ valueCacheVersions,
+ key,
+ runtimeTemplate,
+ logger,
+ asiSafe,
+ objKeys
+ );
+ }
+ if (typeof code === "bigint") {
+ return runtimeTemplate.supportsBigIntLiteral()
+ ? `${code}n`
+ : `BigInt("${code}")`;
+ }
+ return code + "";
+ };
+
+ const strCode = transformToCode();
+
+ logger.log(`Replaced "${key}" with "${strCode}"`);
+
+ return strCode;
+};
+
+const toCacheVersion = code => {
+ if (code === null) {
+ return "null";
+ }
+ if (code === undefined) {
+ return "undefined";
+ }
+ if (Object.is(code, -0)) {
+ return "-0";
+ }
+ if (code instanceof RuntimeValue) {
+ return code.getCacheVersion();
+ }
+ if (code instanceof RegExp && code.toString) {
+ return code.toString();
+ }
+ if (typeof code === "function" && code.toString) {
+ return "(" + code.toString() + ")";
+ }
+ if (typeof code === "object") {
+ const items = Object.keys(code).map(key => ({
+ key,
+ value: toCacheVersion(code[key])
+ }));
+ if (items.some(({ value }) => value === undefined)) return undefined;
+ return `{${items.map(({ key, value }) => `${key}: ${value}`).join(", ")}}`;
+ }
+ if (typeof code === "bigint") {
+ return `${code}n`;
+ }
+ return code + "";
+};
+
+const PLUGIN_NAME = "DefinePlugin";
+const VALUE_DEP_PREFIX = `webpack/${PLUGIN_NAME} `;
+const VALUE_DEP_MAIN = `webpack/${PLUGIN_NAME}_hash`;
+const TYPEOF_OPERATOR_REGEXP = /^typeof\s+/;
+const WEBPACK_REQUIRE_FUNCTION_REGEXP = /__webpack_require__\s*(!?\.)/;
+const WEBPACK_REQUIRE_IDENTIFIER_REGEXP = /__webpack_require__/;
+
+class DefinePlugin {
+ /**
+ * Create a new define plugin
+ * @param {Record<string, CodeValue>} definitions A map of global object definitions
+ */
+ constructor(definitions) {
+ this.definitions = definitions;
+ }
+
+ /**
+ * @param {function({ module: NormalModule, key: string, readonly version: string | undefined }): CodeValuePrimitive} fn generator function
+ * @param {true | string[] | RuntimeValueOptions=} options options
+ * @returns {RuntimeValue} runtime value
+ */
+ static runtimeValue(fn, options) {
+ return new RuntimeValue(fn, options);
+ }
+
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ const definitions = this.definitions;
+ compiler.hooks.compilation.tap(
+ PLUGIN_NAME,
+ (compilation, { normalModuleFactory }) => {
+ const logger = compilation.getLogger("webpack.DefinePlugin");
+ compilation.dependencyTemplates.set(
+ ConstDependency,
+ new ConstDependency.Template()
+ );
+ const { runtimeTemplate } = compilation;
+
+ const mainHash = createHash(compilation.outputOptions.hashFunction);
+ mainHash.update(
+ /** @type {string} */ (
+ compilation.valueCacheVersions.get(VALUE_DEP_MAIN)
+ ) || ""
+ );
+
+ /**
+ * Handler
+ * @param {JavascriptParser} parser Parser
+ * @returns {void}
+ */
+ const handler = parser => {
+ const mainValue = compilation.valueCacheVersions.get(VALUE_DEP_MAIN);
+ parser.hooks.program.tap(PLUGIN_NAME, () => {
+ const { buildInfo } = parser.state.module;
+ if (!buildInfo.valueDependencies)
+ buildInfo.valueDependencies = new Map();
+ buildInfo.valueDependencies.set(VALUE_DEP_MAIN, mainValue);
+ });
+
+ const addValueDependency = key => {
+ const { buildInfo } = parser.state.module;
+ buildInfo.valueDependencies.set(
+ VALUE_DEP_PREFIX + key,
+ compilation.valueCacheVersions.get(VALUE_DEP_PREFIX + key)
+ );
+ };
+
+ const withValueDependency =
+ (key, fn) =>
+ (...args) => {
+ addValueDependency(key);
+ return fn(...args);
+ };
+
+ /**
+ * Walk definitions
+ * @param {Object} definitions Definitions map
+ * @param {string} prefix Prefix string
+ * @returns {void}
+ */
+ const walkDefinitions = (definitions, prefix) => {
+ Object.keys(definitions).forEach(key => {
+ const code = definitions[key];
+ if (
+ code &&
+ typeof code === "object" &&
+ !(code instanceof RuntimeValue) &&
+ !(code instanceof RegExp)
+ ) {
+ walkDefinitions(code, prefix + key + ".");
+ applyObjectDefine(prefix + key, code);
+ return;
+ }
+ applyDefineKey(prefix, key);
+ applyDefine(prefix + key, code);
+ });
+ };
+
+ /**
+ * Apply define key
+ * @param {string} prefix Prefix
+ * @param {string} key Key
+ * @returns {void}
+ */
+ const applyDefineKey = (prefix, key) => {
+ const splittedKey = key.split(".");
+ splittedKey.slice(1).forEach((_, i) => {
+ const fullKey = prefix + splittedKey.slice(0, i + 1).join(".");
+ parser.hooks.canRename.for(fullKey).tap(PLUGIN_NAME, () => {
+ addValueDependency(key);
+ return true;
+ });
+ });
+ };
+
+ /**
+ * Apply Code
+ * @param {string} key Key
+ * @param {CodeValue} code Code
+ * @returns {void}
+ */
+ const applyDefine = (key, code) => {
+ const originalKey = key;
+ const isTypeof = TYPEOF_OPERATOR_REGEXP.test(key);
+ if (isTypeof) key = key.replace(TYPEOF_OPERATOR_REGEXP, "");
+ let recurse = false;
+ let recurseTypeof = false;
+ if (!isTypeof) {
+ parser.hooks.canRename.for(key).tap(PLUGIN_NAME, () => {
+ addValueDependency(originalKey);
+ return true;
+ });
+ parser.hooks.evaluateIdentifier
+ .for(key)
+ .tap(PLUGIN_NAME, expr => {
+ /**
+ * this is needed in case there is a recursion in the DefinePlugin
+ * to prevent an endless recursion
+ * e.g.: new DefinePlugin({
+ * "a": "b",
+ * "b": "a"
+ * });
+ */
+ if (recurse) return;
+ addValueDependency(originalKey);
+ recurse = true;
+ const res = parser.evaluate(
+ toCode(
+ code,
+ parser,
+ compilation.valueCacheVersions,
+ key,
+ runtimeTemplate,
+ logger,
+ null
+ )
+ );
+ recurse = false;
+ res.setRange(expr.range);
+ return res;
+ });
+ parser.hooks.expression.for(key).tap(PLUGIN_NAME, expr => {
+ addValueDependency(originalKey);
+ let strCode = toCode(
+ code,
+ parser,
+ compilation.valueCacheVersions,
+ originalKey,
+ runtimeTemplate,
+ logger,
+ !parser.isAsiPosition(expr.range[0]),
+ parser.destructuringAssignmentPropertiesFor(expr)
+ );
+
+ if (parser.scope.inShorthand) {
+ strCode = parser.scope.inShorthand + ":" + strCode;
+ }
+
+ if (WEBPACK_REQUIRE_FUNCTION_REGEXP.test(strCode)) {
+ return toConstantDependency(parser, strCode, [
+ RuntimeGlobals.require
+ ])(expr);
+ } else if (WEBPACK_REQUIRE_IDENTIFIER_REGEXP.test(strCode)) {
+ return toConstantDependency(parser, strCode, [
+ RuntimeGlobals.requireScope
+ ])(expr);
+ } else {
+ return toConstantDependency(parser, strCode)(expr);
+ }
+ });
+ }
+ parser.hooks.evaluateTypeof.for(key).tap(PLUGIN_NAME, expr => {
+ /**
+ * this is needed in case there is a recursion in the DefinePlugin
+ * to prevent an endless recursion
+ * e.g.: new DefinePlugin({
+ * "typeof a": "typeof b",
+ * "typeof b": "typeof a"
+ * });
+ */
+ if (recurseTypeof) return;
+ recurseTypeof = true;
+ addValueDependency(originalKey);
+ const codeCode = toCode(
+ code,
+ parser,
+ compilation.valueCacheVersions,
+ originalKey,
+ runtimeTemplate,
+ logger,
+ null
+ );
+ const typeofCode = isTypeof
+ ? codeCode
+ : "typeof (" + codeCode + ")";
+ const res = parser.evaluate(typeofCode);
+ recurseTypeof = false;
+ res.setRange(expr.range);
+ return res;
+ });
+ parser.hooks.typeof.for(key).tap(PLUGIN_NAME, expr => {
+ addValueDependency(originalKey);
+ const codeCode = toCode(
+ code,
+ parser,
+ compilation.valueCacheVersions,
+ originalKey,
+ runtimeTemplate,
+ logger,
+ null
+ );
+ const typeofCode = isTypeof
+ ? codeCode
+ : "typeof (" + codeCode + ")";
+ const res = parser.evaluate(typeofCode);
+ if (!res.isString()) return;
+ return toConstantDependency(
+ parser,
+ JSON.stringify(res.string)
+ ).bind(parser)(expr);
+ });
+ };
+
+ /**
+ * Apply Object
+ * @param {string} key Key
+ * @param {Object} obj Object
+ * @returns {void}
+ */
+ const applyObjectDefine = (key, obj) => {
+ parser.hooks.canRename.for(key).tap(PLUGIN_NAME, () => {
+ addValueDependency(key);
+ return true;
+ });
+ parser.hooks.evaluateIdentifier.for(key).tap(PLUGIN_NAME, expr => {
+ addValueDependency(key);
+ return new BasicEvaluatedExpression()
+ .setTruthy()
+ .setSideEffects(false)
+ .setRange(expr.range);
+ });
+ parser.hooks.evaluateTypeof
+ .for(key)
+ .tap(
+ PLUGIN_NAME,
+ withValueDependency(key, evaluateToString("object"))
+ );
+ parser.hooks.expression.for(key).tap(PLUGIN_NAME, expr => {
+ addValueDependency(key);
+ let strCode = stringifyObj(
+ obj,
+ parser,
+ compilation.valueCacheVersions,
+ key,
+ runtimeTemplate,
+ logger,
+ !parser.isAsiPosition(expr.range[0]),
+ parser.destructuringAssignmentPropertiesFor(expr)
+ );
+
+ if (parser.scope.inShorthand) {
+ strCode = parser.scope.inShorthand + ":" + strCode;
+ }
+
+ if (WEBPACK_REQUIRE_FUNCTION_REGEXP.test(strCode)) {
+ return toConstantDependency(parser, strCode, [
+ RuntimeGlobals.require
+ ])(expr);
+ } else if (WEBPACK_REQUIRE_IDENTIFIER_REGEXP.test(strCode)) {
+ return toConstantDependency(parser, strCode, [
+ RuntimeGlobals.requireScope
+ ])(expr);
+ } else {
+ return toConstantDependency(parser, strCode)(expr);
+ }
+ });
+ parser.hooks.typeof
+ .for(key)
+ .tap(
+ PLUGIN_NAME,
+ withValueDependency(
+ key,
+ toConstantDependency(parser, JSON.stringify("object"))
+ )
+ );
+ };
+
+ walkDefinitions(definitions, "");
+ };
+
+ normalModuleFactory.hooks.parser
+ .for(JAVASCRIPT_MODULE_TYPE_AUTO)
+ .tap(PLUGIN_NAME, handler);
+ normalModuleFactory.hooks.parser
+ .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
+ .tap(PLUGIN_NAME, handler);
+ normalModuleFactory.hooks.parser
+ .for(JAVASCRIPT_MODULE_TYPE_ESM)
+ .tap(PLUGIN_NAME, handler);
+
+ /**
+ * Walk definitions
+ * @param {Object} definitions Definitions map
+ * @param {string} prefix Prefix string
+ * @returns {void}
+ */
+ const walkDefinitionsForValues = (definitions, prefix) => {
+ Object.keys(definitions).forEach(key => {
+ const code = definitions[key];
+ const version = toCacheVersion(code);
+ const name = VALUE_DEP_PREFIX + prefix + key;
+ mainHash.update("|" + prefix + key);
+ const oldVersion = compilation.valueCacheVersions.get(name);
+ if (oldVersion === undefined) {
+ compilation.valueCacheVersions.set(name, version);
+ } else if (oldVersion !== version) {
+ const warning = new WebpackError(
+ `${PLUGIN_NAME}\nConflicting values for '${prefix + key}'`
+ );
+ warning.details = `'${oldVersion}' !== '${version}'`;
+ warning.hideStack = true;
+ compilation.warnings.push(warning);
+ }
+ if (
+ code &&
+ typeof code === "object" &&
+ !(code instanceof RuntimeValue) &&
+ !(code instanceof RegExp)
+ ) {
+ walkDefinitionsForValues(code, prefix + key + ".");
+ }
+ });
+ };
+
+ walkDefinitionsForValues(definitions, "");
+
+ compilation.valueCacheVersions.set(
+ VALUE_DEP_MAIN,
+ /** @type {string} */ (mainHash.digest("hex").slice(0, 8))
+ );
+ }
+ );
+ }
+}
+module.exports = DefinePlugin;