From 3bd962a6d7f61239c020e2dbbeb7341e5b842dd1 Mon Sep 17 00:00:00 2001
From: WXL <wl_5969728@163.com>
Date: 星期二, 21 四月 2026 11:46:41 +0800
Subject: [PATCH] 推送

---
 node_modules/webpack/lib/DotenvPlugin.js |   92 +++++++++++++++++++++++++++-------------------
 1 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/node_modules/webpack/lib/DotenvPlugin.js b/node_modules/webpack/lib/DotenvPlugin.js
index e623a9f..f5fa52a 100644
--- a/node_modules/webpack/lib/DotenvPlugin.js
+++ b/node_modules/webpack/lib/DotenvPlugin.js
@@ -6,7 +6,6 @@
 "use strict";
 
 const FileSystemInfo = require("./FileSystemInfo");
-const createSchemaValidation = require("./util/create-schema-validation");
 const { join } = require("./util/fs");
 
 /** @typedef {import("../declarations/WebpackOptions").DotenvPluginOptions} DotenvPluginOptions */
@@ -18,34 +17,19 @@
 /** @typedef {Exclude<DotenvPluginOptions["prefix"], string | undefined>} Prefix */
 /** @typedef {Record<string, string>} Env */
 
-/** @type {DotenvPluginOptions} */
-const DEFAULT_OPTIONS = {
-	prefix: "WEBPACK_",
-	template: [".env", ".env.local", ".env.[mode]", ".env.[mode].local"]
-};
+const DEFAULT_TEMPLATE = [
+	".env",
+	".env.local",
+	".env.[mode]",
+	".env.[mode].local"
+];
 
 // Regex for parsing .env files
-// ported from https://github.com/motdotla/dotenv/blob/master/lib/main.js#L32
+// ported from https://github.com/motdotla/dotenv/blob/master/lib/main.js#L49
 const LINE =
-	/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/gm;
+	/^\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?$/gm;
 
 const PLUGIN_NAME = "DotenvPlugin";
-
-const validate = createSchemaValidation(
-	undefined,
-	() => {
-		const { definitions } = require("../schemas/WebpackOptions.json");
-
-		return {
-			definitions,
-			oneOf: [{ $ref: "#/definitions/DotenvPluginOptions" }]
-		};
-	},
-	{
-		name: "Dotenv Plugin",
-		baseDataPath: "options"
-	}
-);
 
 /**
  * Parse .env file content
@@ -54,15 +38,17 @@
  * @returns {Env} parsed environment variables object
  */
 function parse(src) {
-	const obj = /** @type {Env} */ ({});
+	const obj = /** @type {Env} */ (Object.create(null));
 
 	// Convert buffer to string
 	let lines = src.toString();
 
 	// Convert line breaks to same format
-	lines = lines.replace(/\r\n?/gm, "\n");
+	lines = lines.replace(/\r\n?/g, "\n");
 
+	/** @type {null | RegExpExecArray} */
 	let match;
+
 	while ((match = LINE.exec(lines)) !== null) {
 		const key = match[1];
 
@@ -112,10 +98,12 @@
 function expandValue(value, processEnv, runningParsed) {
 	const env = { ...runningParsed, ...processEnv }; // process.env wins
 
-	const regex = /(?<!\\)\$\{([^{}]+)\}|(?<!\\)\$([A-Za-z_][A-Za-z0-9_]*)/g;
+	const regex = /(?<!\\)\$\{([^{}]+)\}|(?<!\\)\$([a-z_]\w*)/gi;
 
 	let result = value;
+	/** @type {null | RegExpExecArray} */
 	let match;
+	/** @type {Set<string>} */
 	const seen = new Set(); // self-referential checker
 
 	while ((match = regex.exec(result)) !== null) {
@@ -133,7 +121,9 @@
 		const r = expression.split(/** @type {string} */ (splitter));
 		// const r = splitter ? expression.split(splitter) : [expression];
 
+		/** @type {string} */
 		let defaultValue;
+		/** @type {undefined | null | string} */
 		let value;
 
 		const key = r.shift();
@@ -174,7 +164,7 @@
  */
 function expand(options) {
 	// for use with progressive expansion
-	const runningParsed = /** @type {Env} */ ({});
+	const runningParsed = /** @type {Env} */ (Object.create(null));
 	const processEnv = options.processEnv;
 
 	// dotenv.config() ran before this so the assumption is process.env has already been set
@@ -183,7 +173,8 @@
 
 		// short-circuit scenario: process.env was already set prior to the file value
 		value =
-			processEnv[key] && processEnv[key] !== value
+			Object.prototype.hasOwnProperty.call(processEnv, key) &&
+			processEnv[key] !== value
 				? /** @type {string} */ (processEnv[key])
 				: expandValue(value, processEnv, runningParsed);
 
@@ -223,18 +214,37 @@
 
 class DotenvPlugin {
 	/**
+	 * Creates an instance of DotenvPlugin.
 	 * @param {DotenvPluginOptions=} options options object
 	 */
 	constructor(options = {}) {
-		validate(options);
-		this.options = { ...DEFAULT_OPTIONS, ...options };
+		/** @type {DotenvPluginOptions} */
+		this.options = options;
 	}
 
 	/**
+	 * Applies the plugin by registering its hooks on the compiler.
 	 * @param {Compiler} compiler the compiler instance
 	 * @returns {void}
 	 */
 	apply(compiler) {
+		compiler.hooks.validate.tap(PLUGIN_NAME, () => {
+			compiler.validate(
+				() => {
+					const { definitions } = require("../schemas/WebpackOptions.json");
+
+					return {
+						definitions,
+						oneOf: [{ $ref: "#/definitions/DotenvPluginOptions" }]
+					};
+				},
+				this.options,
+				{
+					name: "Dotenv Plugin",
+					baseDataPath: "options"
+				}
+			);
+		});
 		const definePlugin = new compiler.webpack.DefinePlugin({});
 		const prefixes = Array.isArray(this.options.prefix)
 			? this.options.prefix
@@ -251,7 +261,9 @@
 		let snapshot;
 
 		const cache = compiler.getCache(PLUGIN_NAME);
-		const identifier = JSON.stringify(this.options.template);
+		const identifier = JSON.stringify(
+			this.options.template || DEFAULT_TEMPLATE
+		);
 		const itemCache = cache.getItemCache(identifier, null);
 
 		compiler.hooks.beforeCompile.tapPromise(PLUGIN_NAME, async () => {
@@ -288,8 +300,7 @@
 			return [];
 		}
 
-		const { template } = /** @type {DotenvPluginOptions} */ (this.options);
-		const templates = template || [];
+		const templates = this.options.template || DEFAULT_TEMPLATE;
 
 		return templates
 			.map((pattern) => pattern.replace(/\[mode\]/g, mode || "development"))
@@ -302,7 +313,7 @@
 	 * @param {InputFileSystem} fs input file system
 	 * @param {string} dir dir to load `.env` files
 	 * @param {string} mode mode
-	 * @returns {Promise<{parsed: Env, fileDependencies: string[], missingDependencies: string[]}>} parsed env variables and dependencies
+	 * @returns {Promise<{ parsed: Env, fileDependencies: string[], missingDependencies: string[] }>} parsed env variables and dependencies
 	 */
 	async _getParsed(fs, dir, mode) {
 		/** @type {string[]} */
@@ -332,7 +343,7 @@
 
 		// Parse all files and merge (later files override earlier ones)
 		// Similar to Vite's implementation
-		const parsed = /** @type {Env} */ ({});
+		const parsed = /** @type {Env} */ (Object.create(null));
 
 		for (const content of contents) {
 			if (!content) continue;
@@ -346,6 +357,7 @@
 	}
 
 	/**
+	 * Loads the provided compiler.
 	 * @private
 	 * @param {Compiler} compiler compiler
 	 * @param {ItemCacheFacade} itemCache item cache facade
@@ -422,7 +434,7 @@
 		// Make a copy of process.env so that dotenv-expand doesn't modify global process.env
 		const processEnv = { ...process.env };
 		expand({ parsed, processEnv });
-		const env = /** @type {Env} */ ({});
+		const env = /** @type {Env} */ (Object.create(null));
 
 		// Get all keys from parser and process.env
 		const keys = [...Object.keys(parsed), ...Object.keys(process.env)];
@@ -430,7 +442,11 @@
 		// Prioritize actual env variables from `process.env`, fallback to parsed
 		for (const key of keys) {
 			if (prefixes.some((prefix) => key.startsWith(prefix))) {
-				env[key] = process.env[key] ? process.env[key] : parsed[key];
+				env[key] =
+					Object.prototype.hasOwnProperty.call(process.env, key) &&
+					process.env[key]
+						? process.env[key]
+						: parsed[key];
 			}
 		}
 

--
Gitblit v1.9.3