mirror of https://github.com/webpack/webpack.git
Compare commits
3 Commits
7a214cb7d1
...
34737a8a26
Author | SHA1 | Date |
---|---|---|
|
34737a8a26 | |
|
08625a84d7 | |
|
9f98d803c0 |
|
@ -47,6 +47,10 @@ export type DevServer =
|
|||
* A developer tool to enhance debugging (false | eval | [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map).
|
||||
*/
|
||||
export type DevTool = (false | "eval") | string;
|
||||
/**
|
||||
* Enable and configure the Dotenv plugin to load environment variables from .env files.
|
||||
*/
|
||||
export type Dotenv = boolean | DotenvPluginOptions;
|
||||
/**
|
||||
* The entry point(s) of the compilation.
|
||||
*/
|
||||
|
@ -884,6 +888,10 @@ export interface WebpackOptions {
|
|||
* A developer tool to enhance debugging (false | eval | [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map).
|
||||
*/
|
||||
devtool?: DevTool;
|
||||
/**
|
||||
* Enable and configure the Dotenv plugin to load environment variables from .env files.
|
||||
*/
|
||||
dotenv?: Dotenv;
|
||||
/**
|
||||
* The entry point(s) of the compilation.
|
||||
*/
|
||||
|
@ -1108,6 +1116,23 @@ export interface FileCacheOptions {
|
|||
*/
|
||||
version?: string;
|
||||
}
|
||||
/**
|
||||
* Options for Dotenv plugin.
|
||||
*/
|
||||
export interface DotenvPluginOptions {
|
||||
/**
|
||||
* The directory from which .env files are loaded. Can be an absolute path, or a path relative to the project root. false will disable the .env file loading.
|
||||
*/
|
||||
dir?: boolean | string;
|
||||
/**
|
||||
* Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.
|
||||
*/
|
||||
prefix?: string[] | string;
|
||||
/**
|
||||
* Template patterns for .env file names. Use [mode] as placeholder for the webpack mode. Defaults to ['.env', '.env.local', '.env.[mode]', '.env.[mode].local'].
|
||||
*/
|
||||
template?: string[];
|
||||
}
|
||||
/**
|
||||
* Multiple entry bundles are created. The key is the entry name. The value can be a string, an array or an entry description object.
|
||||
*/
|
||||
|
@ -3349,7 +3374,6 @@ export interface JavascriptParserOptions {
|
|||
* Set the inner regular expression for partial dynamic dependencies.
|
||||
*/
|
||||
wrappedContextRegExp?: RegExp;
|
||||
[k: string]: any;
|
||||
}
|
||||
/**
|
||||
* Generator options for json modules.
|
||||
|
@ -3798,6 +3822,10 @@ export interface WebpackOptionsNormalized {
|
|||
* A developer tool to enhance debugging (false | eval | [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map).
|
||||
*/
|
||||
devtool?: DevTool;
|
||||
/**
|
||||
* Enable and configure the Dotenv plugin to load environment variables from .env files.
|
||||
*/
|
||||
dotenv?: Dotenv;
|
||||
/**
|
||||
* The entry point(s) of the compilation.
|
||||
*/
|
||||
|
|
|
@ -354,20 +354,20 @@ class DefinePlugin {
|
|||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
const definitions = this.definitions;
|
||||
|
||||
/**
|
||||
* @type {Map<string, Set<string>>}
|
||||
*/
|
||||
const finalByNestedKey = new Map();
|
||||
/**
|
||||
* @type {Map<string, Set<string>>}
|
||||
*/
|
||||
const nestedByFinalKey = new Map();
|
||||
|
||||
compiler.hooks.compilation.tap(
|
||||
PLUGIN_NAME,
|
||||
(compilation, { normalModuleFactory }) => {
|
||||
const definitions = this.definitions;
|
||||
|
||||
/**
|
||||
* @type {Map<string, Set<string>>}
|
||||
*/
|
||||
const finalByNestedKey = new Map();
|
||||
/**
|
||||
* @type {Map<string, Set<string>>}
|
||||
*/
|
||||
const nestedByFinalKey = new Map();
|
||||
|
||||
const logger = compilation.getLogger("webpack.DefinePlugin");
|
||||
compilation.dependencyTemplates.set(
|
||||
ConstDependency,
|
||||
|
|
|
@ -0,0 +1,426 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Natsu @xiaoxiaojx
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const createSchemaValidation = require("./util/create-schema-validation");
|
||||
const { join } = require("./util/fs");
|
||||
|
||||
/** @typedef {import("../declarations/WebpackOptions").DotenvPluginOptions} DotenvPluginOptions */
|
||||
/** @typedef {import("./Compiler")} Compiler */
|
||||
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
|
||||
|
||||
/** @type {DotenvPluginOptions} */
|
||||
const DEFAULT_OPTIONS = {
|
||||
prefix: "WEBPACK_",
|
||||
dir: true,
|
||||
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
|
||||
const LINE =
|
||||
/(?:^|^)\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
|
||||
* ported from https://github.com/motdotla/dotenv/blob/master/lib/main.js#L49
|
||||
* @param {string|Buffer} src the source content to parse
|
||||
* @returns {Record<string, string>} parsed environment variables object
|
||||
*/
|
||||
function parse(src) {
|
||||
const obj = /** @type {Record<string, string>} */ ({});
|
||||
|
||||
// Convert buffer to string
|
||||
let lines = src.toString();
|
||||
|
||||
// Convert line breaks to same format
|
||||
lines = lines.replace(/\r\n?/gm, "\n");
|
||||
|
||||
let match;
|
||||
while ((match = LINE.exec(lines)) !== null) {
|
||||
const key = match[1];
|
||||
|
||||
// Default undefined or null to empty string
|
||||
let value = match[2] || "";
|
||||
|
||||
// Remove whitespace
|
||||
value = value.trim();
|
||||
|
||||
// Check if double quoted
|
||||
const maybeQuote = value[0];
|
||||
|
||||
// Remove surrounding quotes
|
||||
value = value.replace(/^(['"`])([\s\S]*)\1$/gm, "$2");
|
||||
|
||||
// Expand newlines if double quoted
|
||||
if (maybeQuote === '"') {
|
||||
value = value.replace(/\\n/g, "\n");
|
||||
value = value.replace(/\\r/g, "\r");
|
||||
}
|
||||
|
||||
// Add to object
|
||||
obj[key] = value;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve escape sequences
|
||||
* ported from https://github.com/motdotla/dotenv-expand
|
||||
* @param {string} value value to resolve
|
||||
* @returns {string} resolved value
|
||||
*/
|
||||
function _resolveEscapeSequences(value) {
|
||||
return value.replace(/\\\$/g, "$");
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand environment variable value
|
||||
* ported from https://github.com/motdotla/dotenv-expand
|
||||
* @param {string} value value to expand
|
||||
* @param {Record<string, string | undefined>} processEnv process.env object
|
||||
* @param {Record<string, string>} runningParsed running parsed object
|
||||
* @returns {string} expanded value
|
||||
*/
|
||||
function expandValue(value, processEnv, runningParsed) {
|
||||
const env = { ...runningParsed, ...processEnv }; // process.env wins
|
||||
|
||||
const regex = /(?<!\\)\$\{([^{}]+)\}|(?<!\\)\$([A-Za-z_][A-Za-z0-9_]*)/g;
|
||||
|
||||
let result = value;
|
||||
let match;
|
||||
const seen = new Set(); // self-referential checker
|
||||
|
||||
while ((match = regex.exec(result)) !== null) {
|
||||
seen.add(result);
|
||||
|
||||
const [template, bracedExpression, unbracedExpression] = match;
|
||||
const expression = bracedExpression || unbracedExpression;
|
||||
|
||||
// match the operators `:+`, `+`, `:-`, and `-`
|
||||
const opRegex = /(:\+|\+|:-|-)/;
|
||||
// find first match
|
||||
const opMatch = expression.match(opRegex);
|
||||
const splitter = opMatch ? opMatch[0] : null;
|
||||
|
||||
const r = expression.split(/** @type {string} */ (splitter));
|
||||
// const r = splitter ? expression.split(splitter) : [expression];
|
||||
|
||||
let defaultValue;
|
||||
let value;
|
||||
|
||||
const key = r.shift();
|
||||
|
||||
if ([":+", "+"].includes(splitter || "")) {
|
||||
defaultValue = env[key || ""] ? r.join(splitter || "") : "";
|
||||
value = null;
|
||||
} else {
|
||||
defaultValue = r.join(splitter || "");
|
||||
value = env[key || ""];
|
||||
}
|
||||
|
||||
if (value) {
|
||||
// self-referential check
|
||||
result = seen.has(value)
|
||||
? result.replace(template, defaultValue)
|
||||
: result.replace(template, value);
|
||||
} else {
|
||||
result = result.replace(template, defaultValue);
|
||||
}
|
||||
|
||||
// if the result equaled what was in process.env and runningParsed then stop expanding
|
||||
if (result === runningParsed[key || ""]) {
|
||||
break;
|
||||
}
|
||||
|
||||
regex.lastIndex = 0; // reset regex search position to re-evaluate after each replacement
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand environment variables in parsed object
|
||||
* ported from https://github.com/motdotla/dotenv-expand
|
||||
* @param {{ parsed: Record<string, string>, processEnv?: Record<string, string | undefined> }} options expand options
|
||||
* @returns {{ parsed: Record<string, string> }} expanded options
|
||||
*/
|
||||
function expand(options) {
|
||||
// for use with progressive expansion
|
||||
const runningParsed = /** @type {Record<string, string>} */ ({});
|
||||
|
||||
let processEnv = process.env;
|
||||
if (
|
||||
options &&
|
||||
options.processEnv !== null &&
|
||||
options.processEnv !== undefined
|
||||
) {
|
||||
processEnv = options.processEnv;
|
||||
}
|
||||
|
||||
// dotenv.config() ran before this so the assumption is process.env has already been set
|
||||
for (const key in options.parsed) {
|
||||
let value = options.parsed[key];
|
||||
|
||||
// short-circuit scenario: process.env was already set prior to the file value
|
||||
value =
|
||||
processEnv[key] && processEnv[key] !== value
|
||||
? /** @type {string} */ (processEnv[key])
|
||||
: expandValue(value, processEnv, runningParsed);
|
||||
|
||||
options.parsed[key] = _resolveEscapeSequences(value);
|
||||
|
||||
// for use with progressive expansion
|
||||
runningParsed[key] = _resolveEscapeSequences(value);
|
||||
}
|
||||
|
||||
for (const processKey in options.parsed) {
|
||||
if (processEnv) {
|
||||
processEnv[processKey] = options.parsed[processKey];
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve and validate env prefixes
|
||||
* Similar to Vite's resolveEnvPrefix
|
||||
* @param {string | string[] | undefined} rawPrefix raw prefix option
|
||||
* @returns {string[]} normalized prefixes array
|
||||
*/
|
||||
const resolveEnvPrefix = (rawPrefix) => {
|
||||
const prefixes = Array.isArray(rawPrefix)
|
||||
? rawPrefix
|
||||
: [rawPrefix || "WEBPACK_"];
|
||||
|
||||
// Check for empty prefix (security issue like Vite does)
|
||||
if (prefixes.includes("")) {
|
||||
throw new Error(
|
||||
"prefix option contains value '', which could lead to unexpected exposure of sensitive information."
|
||||
);
|
||||
}
|
||||
|
||||
return prefixes;
|
||||
};
|
||||
|
||||
/**
|
||||
* Format environment variables as DefinePlugin definitions
|
||||
* @param {Record<string, string>} env environment variables
|
||||
* @returns {Record<string, string>} formatted definitions
|
||||
*/
|
||||
const envToDefinitions = (env) => {
|
||||
const definitions = /** @type {Record<string, string>} */ ({});
|
||||
|
||||
for (const [key, value] of Object.entries(env)) {
|
||||
// Always use process.env. prefix for DefinePlugin
|
||||
definitions[`process.env.${key}`] = JSON.stringify(value);
|
||||
}
|
||||
|
||||
return definitions;
|
||||
};
|
||||
|
||||
class DotenvPlugin {
|
||||
/**
|
||||
* @param {DotenvPluginOptions=} options options object
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
validate(options);
|
||||
this.config = { ...DEFAULT_OPTIONS, ...options };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
const definePlugin = new compiler.webpack.DefinePlugin({});
|
||||
|
||||
/** @type {string[] | undefined} */
|
||||
let fileDependenciesCache;
|
||||
|
||||
compiler.hooks.beforeCompile.tapAsync(PLUGIN_NAME, (_params, callback) => {
|
||||
const inputFileSystem = /** @type {InputFileSystem} */ (
|
||||
compiler.inputFileSystem
|
||||
);
|
||||
const context = compiler.context;
|
||||
const mode = compiler.options.mode || "development";
|
||||
|
||||
this.loadEnv(
|
||||
inputFileSystem,
|
||||
mode,
|
||||
context,
|
||||
(err, env, fileDependencies) => {
|
||||
if (err) return callback(err);
|
||||
|
||||
const definitions = envToDefinitions(env || {});
|
||||
|
||||
// update the definitions
|
||||
definePlugin.definitions = definitions;
|
||||
// update the file dependencies
|
||||
fileDependenciesCache = fileDependencies;
|
||||
|
||||
callback();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
|
||||
compilation.fileDependencies.addAll(fileDependenciesCache || []);
|
||||
});
|
||||
|
||||
definePlugin.apply(compiler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of env files to load based on mode and template
|
||||
* Similar to Vite's getEnvFilesForMode
|
||||
* @param {InputFileSystem} inputFileSystem the input file system
|
||||
* @param {string} dir the directory containing .env files
|
||||
* @param {string | undefined} mode the mode (e.g., 'production', 'development')
|
||||
* @returns {string[]} array of file paths to load
|
||||
*/
|
||||
getEnvFilesForMode(inputFileSystem, dir, mode) {
|
||||
if (!dir) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { template } = /** @type {DotenvPluginOptions} */ (this.config);
|
||||
const templates = template || [];
|
||||
|
||||
return templates
|
||||
.map((pattern) => pattern.replace(/\[mode\]/g, mode || "development"))
|
||||
.map((file) => join(inputFileSystem, dir, file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load environment variables from .env files
|
||||
* Similar to Vite's loadEnv implementation
|
||||
* @param {InputFileSystem} fs the input file system
|
||||
* @param {string | undefined} mode the mode
|
||||
* @param {string} context the compiler context
|
||||
* @param {(err: Error | null, env?: Record<string, string>, fileDependencies?: string[]) => void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
loadEnv(fs, mode, context, callback) {
|
||||
const { dir: rawDir, prefix: rawPrefix } =
|
||||
/** @type {DotenvPluginOptions} */ (this.config);
|
||||
|
||||
let prefixes;
|
||||
try {
|
||||
prefixes = resolveEnvPrefix(rawPrefix);
|
||||
} catch (err) {
|
||||
return callback(/** @type {Error} */ (err));
|
||||
}
|
||||
const getDir = () => {
|
||||
if (typeof rawDir === "string") {
|
||||
return join(fs, context, rawDir);
|
||||
}
|
||||
if (rawDir === true) {
|
||||
return context;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
/** @type {string} */
|
||||
const dir = getDir();
|
||||
// Get env files to load
|
||||
const envFiles = this.getEnvFilesForMode(fs, dir, mode);
|
||||
/** @type {string[]} */
|
||||
const fileDependencies = [];
|
||||
|
||||
// Read all files
|
||||
const readPromises = envFiles.map((filePath) =>
|
||||
this.loadFile(fs, filePath).then(
|
||||
(content) => {
|
||||
fileDependencies.push(filePath);
|
||||
return { content, filePath };
|
||||
},
|
||||
() =>
|
||||
// File doesn't exist, skip it (this is normal)
|
||||
({ content: "", filePath })
|
||||
)
|
||||
);
|
||||
|
||||
Promise.all(readPromises)
|
||||
.then((results) => {
|
||||
// Parse all files and merge (later files override earlier ones)
|
||||
// Similar to Vite's implementation
|
||||
const parsed = /** @type {Record<string, string>} */ ({});
|
||||
for (const { content } of results) {
|
||||
if (!content) continue;
|
||||
const entries = parse(content);
|
||||
for (const key in entries) {
|
||||
parsed[key] = entries[key];
|
||||
}
|
||||
}
|
||||
|
||||
// Always expand environment variables (like Vite does)
|
||||
// Make a copy of process.env so that dotenv-expand doesn't modify global process.env
|
||||
const processEnv = { ...process.env };
|
||||
expand({ parsed, processEnv });
|
||||
|
||||
// Filter by prefixes and prioritize process.env (like Vite)
|
||||
const env = /** @type {Record<string, string>} */ ({});
|
||||
|
||||
// First, add filtered vars from parsed .env files
|
||||
for (const [key, value] of Object.entries(parsed)) {
|
||||
if (prefixes.some((prefix) => key.startsWith(prefix))) {
|
||||
env[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Then, prioritize actual env variables starting with prefixes
|
||||
// These are typically provided inline and should be prioritized (like Vite)
|
||||
for (const key in process.env) {
|
||||
if (prefixes.some((prefix) => key.startsWith(prefix))) {
|
||||
env[key] = /** @type {string} */ (process.env[key]);
|
||||
}
|
||||
}
|
||||
|
||||
callback(null, env, fileDependencies);
|
||||
})
|
||||
.catch((err) => {
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a file with proper path resolution
|
||||
* @param {InputFileSystem} fs the input file system
|
||||
* @param {string} file the file to load
|
||||
* @returns {Promise<string>} the content of the file
|
||||
*/
|
||||
loadFile(fs, file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.readFile(file, "utf8", (err, content) => {
|
||||
if (err) reject(err);
|
||||
else resolve(content || "");
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DotenvPlugin;
|
|
@ -294,6 +294,14 @@ class WebpackOptionsApply extends OptionsApply {
|
|||
).apply(compiler);
|
||||
}
|
||||
|
||||
if (options.dotenv) {
|
||||
const DotenvPlugin = require("./DotenvPlugin");
|
||||
|
||||
new DotenvPlugin(
|
||||
typeof options.dotenv === "boolean" ? {} : options.dotenv
|
||||
).apply(compiler);
|
||||
}
|
||||
|
||||
if (options.devtool) {
|
||||
if (options.devtool.includes("source-map")) {
|
||||
const hidden = options.devtool.includes("hidden");
|
||||
|
|
|
@ -202,6 +202,7 @@ const {
|
|||
* & { performance: NonNullable<WebpackOptionsNormalized["performance"]> }
|
||||
* & { recordsInputPath: NonNullable<WebpackOptionsNormalized["recordsInputPath"]> }
|
||||
* & { recordsOutputPath: NonNullable<WebpackOptionsNormalized["recordsOutputPath"]>
|
||||
* & { dotenv: NonNullable<WebpackOptionsNormalized["dotenv"]> }
|
||||
* }} WebpackOptionsNormalizedWithDefaults
|
||||
*/
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ const getNormalizedWebpackOptions = (config) => ({
|
|||
return { ...devServer };
|
||||
}),
|
||||
devtool: config.devtool,
|
||||
dotenv: config.dotenv,
|
||||
entry:
|
||||
config.entry === undefined
|
||||
? { main: {} }
|
||||
|
|
|
@ -232,6 +232,9 @@ module.exports = mergeExports(fn, {
|
|||
get DynamicEntryPlugin() {
|
||||
return require("./DynamicEntryPlugin");
|
||||
},
|
||||
get DotenvPlugin() {
|
||||
return require("./DotenvPlugin");
|
||||
},
|
||||
get EntryOptionPlugin() {
|
||||
return require("./EntryOptionPlugin");
|
||||
},
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -629,6 +629,66 @@
|
|||
"description": "Module namespace to use when interpolating filename template string for the sources array in a generated SourceMap. Defaults to `output.library` if not set. It's useful for avoiding runtime collisions in sourcemaps from multiple webpack projects built as libraries.",
|
||||
"type": "string"
|
||||
},
|
||||
"Dotenv": {
|
||||
"description": "Enable and configure the Dotenv plugin to load environment variables from .env files.",
|
||||
"cli": {
|
||||
"exclude": false
|
||||
},
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Enable Dotenv plugin with default options.",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/DotenvPluginOptions"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DotenvPluginOptions": {
|
||||
"description": "Options for Dotenv plugin.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"dir": {
|
||||
"description": "The directory from which .env files are loaded. Can be an absolute path, or a path relative to the project root. false will disable the .env file loading.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"prefix": {
|
||||
"description": "Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "A prefix that environment variables must start with to be exposed.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"template": {
|
||||
"description": "Template patterns for .env file names. Use [mode] as placeholder for the webpack mode. Defaults to ['.env', '.env.local', '.env.[mode]', '.env.[mode].local'].",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "A template pattern for .env file names.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"EmptyGeneratorOptions": {
|
||||
"description": "No generator options are supported for this module type.",
|
||||
"type": "object",
|
||||
|
@ -1786,7 +1846,7 @@
|
|||
"JavascriptParserOptions": {
|
||||
"description": "Parser options for javascript modules.",
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"amd": {
|
||||
"$ref": "#/definitions/Amd"
|
||||
|
@ -5800,6 +5860,9 @@
|
|||
"devtool": {
|
||||
"$ref": "#/definitions/DevTool"
|
||||
},
|
||||
"dotenv": {
|
||||
"$ref": "#/definitions/Dotenv"
|
||||
},
|
||||
"entry": {
|
||||
"$ref": "#/definitions/EntryNormalized"
|
||||
},
|
||||
|
@ -5950,6 +6013,9 @@
|
|||
"devtool": {
|
||||
"$ref": "#/definitions/DevTool"
|
||||
},
|
||||
"dotenv": {
|
||||
"$ref": "#/definitions/Dotenv"
|
||||
},
|
||||
"entry": {
|
||||
"$ref": "#/definitions/Entry"
|
||||
},
|
||||
|
|
|
@ -84,6 +84,7 @@ describe("snapshots", () => {
|
|||
"dependencies": undefined,
|
||||
"devServer": undefined,
|
||||
"devtool": false,
|
||||
"dotenv": undefined,
|
||||
"entry": Object {
|
||||
"main": Object {
|
||||
"import": Array [
|
||||
|
|
|
@ -79,7 +79,7 @@ describe("Validation", () => {
|
|||
expect(msg).toMatchInlineSnapshot(`
|
||||
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
|
||||
- configuration should be an object:
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, dotenv?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
-> Options object as provided by the user."
|
||||
`)
|
||||
);
|
||||
|
@ -88,7 +88,7 @@ describe("Validation", () => {
|
|||
expect(msg).toMatchInlineSnapshot(`
|
||||
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
|
||||
- configuration should be an object:
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, dotenv?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
-> Options object as provided by the user."
|
||||
`)
|
||||
);
|
||||
|
@ -251,7 +251,7 @@ describe("Validation", () => {
|
|||
expect(msg).toMatchInlineSnapshot(`
|
||||
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
|
||||
- configuration has an unknown property 'postcss'. These properties are valid:
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, dotenv?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
-> Options object as provided by the user.
|
||||
For typos: please correct them.
|
||||
For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.
|
||||
|
@ -494,7 +494,7 @@ describe("Validation", () => {
|
|||
expect(msg).toMatchInlineSnapshot(`
|
||||
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
|
||||
- configuration has an unknown property 'debug'. These properties are valid:
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, dotenv?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
-> Options object as provided by the user.
|
||||
The 'debug' property was removed in webpack 2.0.0.
|
||||
Loaders should be updated to allow passing this option via loader options in module.rules.
|
||||
|
@ -542,7 +542,7 @@ describe("Validation", () => {
|
|||
expect(msg).toMatchInlineSnapshot(`
|
||||
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
|
||||
- configuration[1] should be an object:
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, dotenv?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
-> Options object as provided by the user."
|
||||
`)
|
||||
);
|
||||
|
@ -664,7 +664,7 @@ describe("Validation", () => {
|
|||
expect(msg).toMatchInlineSnapshot(`
|
||||
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
|
||||
- configuration has an unknown property 'rules'. These properties are valid:
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, dotenv?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
-> Options object as provided by the user.
|
||||
Did you mean module.rules?"
|
||||
`)
|
||||
|
@ -679,7 +679,7 @@ describe("Validation", () => {
|
|||
expect(msg).toMatchInlineSnapshot(`
|
||||
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
|
||||
- configuration has an unknown property 'splitChunks'. These properties are valid:
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, dotenv?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
-> Options object as provided by the user.
|
||||
Did you mean optimization.splitChunks?"
|
||||
`)
|
||||
|
@ -694,7 +694,7 @@ describe("Validation", () => {
|
|||
expect(msg).toMatchInlineSnapshot(`
|
||||
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
|
||||
- configuration has an unknown property 'noParse'. These properties are valid:
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, dotenv?, entry?, experiments?, extends?, externals?, externalsPresets?, externalsType?, ignoreWarnings?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
|
||||
-> Options object as provided by the user.
|
||||
Did you mean module.noParse?"
|
||||
`)
|
||||
|
|
|
@ -465,6 +465,90 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"dotenv": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Enable Dotenv plugin with default options.",
|
||||
"multiple": false,
|
||||
"path": "dotenv",
|
||||
"type": "boolean",
|
||||
},
|
||||
],
|
||||
"description": "Enable Dotenv plugin with default options.",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"dotenv-dir": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "The directory from which .env files are loaded. Can be an absolute path, or a path relative to the project root. false will disable the .env file loading.",
|
||||
"multiple": false,
|
||||
"path": "dotenv.dir",
|
||||
"type": "boolean",
|
||||
},
|
||||
Object {
|
||||
"description": "The directory from which .env files are loaded. Can be an absolute path, or a path relative to the project root. false will disable the .env file loading.",
|
||||
"multiple": false,
|
||||
"path": "dotenv.dir",
|
||||
"type": "string",
|
||||
},
|
||||
],
|
||||
"description": "The directory from which .env files are loaded. Can be an absolute path, or a path relative to the project root. false will disable the .env file loading.",
|
||||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"dotenv-prefix": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "A prefix that environment variables must start with to be exposed.",
|
||||
"multiple": true,
|
||||
"path": "dotenv.prefix[]",
|
||||
"type": "string",
|
||||
},
|
||||
],
|
||||
"description": "A prefix that environment variables must start with to be exposed.",
|
||||
"multiple": true,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"dotenv-prefix-reset": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Clear all items provided in 'dotenv.prefix' configuration. Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.",
|
||||
"multiple": false,
|
||||
"path": "dotenv.prefix",
|
||||
"type": "reset",
|
||||
},
|
||||
],
|
||||
"description": "Clear all items provided in 'dotenv.prefix' configuration. Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"dotenv-template": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "A template pattern for .env file names.",
|
||||
"multiple": true,
|
||||
"path": "dotenv.template[]",
|
||||
"type": "string",
|
||||
},
|
||||
],
|
||||
"description": "A template pattern for .env file names.",
|
||||
"multiple": true,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"dotenv-template-reset": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Clear all items provided in 'dotenv.template' configuration. Template patterns for .env file names. Use [mode] as placeholder for the webpack mode. Defaults to ['.env', '.env.local', '.env.[mode]', '.env.[mode].local'].",
|
||||
"multiple": false,
|
||||
"path": "dotenv.template",
|
||||
"type": "reset",
|
||||
},
|
||||
],
|
||||
"description": "Clear all items provided in 'dotenv.template' configuration. Template patterns for .env file names. Use [mode] as placeholder for the webpack mode. Defaults to ['.env', '.env.local', '.env.[mode]', '.env.[mode].local'].",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"entry": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# Basic test
|
||||
WEBPACK_API_URL=https://api.example.com
|
||||
WEBPACK_MODE=test
|
||||
SECRET_KEY=should-not-be-exposed
|
||||
PRIVATE_VAR=also-hidden
|
||||
|
||||
# Expand test
|
||||
WEBPACK_BASE=example.com
|
||||
WEBPACK_FULL_URL=${WEBPACK_API_URL}/v1
|
||||
WEBPACK_PORT=${PORT:-3000}
|
||||
|
||||
# Mode-specific base value
|
||||
WEBPACK_ENV=development
|
||||
|
||||
# Custom template test - base value
|
||||
WEBPACK_OVERRIDE_VAR=base-value
|
|
@ -0,0 +1,3 @@
|
|||
# Custom template test - myLocal file
|
||||
WEBPACK_CUSTOM_VAR=from-myLocal
|
||||
WEBPACK_OVERRIDE_VAR=myLocal-value
|
|
@ -0,0 +1,3 @@
|
|||
# Production overrides
|
||||
WEBPACK_API_URL=https://prod-api.example.com
|
||||
WEBPACK_ENV=production
|
|
@ -0,0 +1,2 @@
|
|||
# Custom template test - production.myLocal file
|
||||
WEBPACK_PROD_CUSTOM=from-production-myLocal
|
|
@ -0,0 +1,10 @@
|
|||
"use strict";
|
||||
|
||||
it("should expose only WEBPACK_ prefixed env vars", () => {
|
||||
expect(process.env.WEBPACK_API_URL).toBe("https://api.example.com");
|
||||
expect(process.env.WEBPACK_MODE).toBe("test");
|
||||
|
||||
// Non-prefixed vars should not be exposed
|
||||
expect(typeof process.env.SECRET_KEY).toBe("undefined");
|
||||
expect(typeof process.env.PRIVATE_VAR).toBe("undefined");
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
it("should load from custom dir", () => {
|
||||
expect(process.env.WEBPACK_FROM_ENVS).toBe("loaded-from-envs-dir");
|
||||
expect(process.env.WEBPACK_API_URL).toBe("https://custom.example.com");
|
||||
});
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
|
||||
it("should expose only APP_ and CONFIG_ prefixed vars", () => {
|
||||
expect(process.env.APP_NAME).toBe("MyApp");
|
||||
expect(process.env.CONFIG_TIMEOUT).toBe("5000");
|
||||
|
||||
// WEBPACK_ prefixed should not be exposed
|
||||
expect(typeof process.env.WEBPACK_API_URL).toBe("undefined");
|
||||
|
||||
// Non-prefixed should not be exposed
|
||||
expect(typeof process.env.SECRET_KEY).toBe("undefined");
|
||||
});
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
"use strict";
|
||||
|
||||
it("should load env files based on custom template", () => {
|
||||
// Should load from .env.myLocal (custom template)
|
||||
expect(process.env.WEBPACK_CUSTOM_VAR).toBe("from-myLocal");
|
||||
|
||||
// Should load from .env.production.myLocal (custom mode-specific template)
|
||||
expect(process.env.WEBPACK_PROD_CUSTOM).toBe("from-production-myLocal");
|
||||
|
||||
// Should also load from standard .env
|
||||
expect(process.env.WEBPACK_API_URL).toBe("https://prod-api.example.com");
|
||||
|
||||
// Custom template files should override .env values
|
||||
expect(process.env.WEBPACK_OVERRIDE_VAR).toBe("myLocal-value");
|
||||
});
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
"use strict";
|
||||
|
||||
it("should not load any .env files when dir is false", () => {
|
||||
// When dir: false, no .env files should be loaded
|
||||
// Only environment variables that were already set in process.env should be available
|
||||
// and only those with WEBPACK_ prefix should be exposed
|
||||
|
||||
// These should be undefined since no .env files are loaded
|
||||
expect(typeof process.env.WEBPACK_API_URL).toBe("undefined");
|
||||
expect(typeof process.env.WEBPACK_MODE).toBe("undefined");
|
||||
expect(typeof process.env.SECRET_KEY).toBe("undefined");
|
||||
expect(typeof process.env.PRIVATE_VAR).toBe("undefined");
|
||||
|
||||
// Only pre-existing process.env variables with WEBPACK_ prefix should be available
|
||||
// (if any were set before webpack runs)
|
||||
});
|
|
@ -0,0 +1,2 @@
|
|||
WEBPACK_FROM_ENVS=loaded-from-envs-dir
|
||||
WEBPACK_API_URL=https://custom.example.com
|
|
@ -0,0 +1,10 @@
|
|||
"use strict";
|
||||
|
||||
it("should expand variables by default", () => {
|
||||
expect(process.env.WEBPACK_BASE).toBe("example.com");
|
||||
expect(process.env.WEBPACK_API_URL).toBe("https://api.example.com");
|
||||
expect(process.env.WEBPACK_FULL_URL).toBe("https://api.example.com/v1");
|
||||
|
||||
// Test default value operator
|
||||
expect(process.env.WEBPACK_PORT).toBe("3000");
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
"use strict";
|
||||
|
||||
it("should load .env.production and override .env values", () => {
|
||||
// Value from .env.production should override .env
|
||||
expect(process.env.WEBPACK_API_URL).toBe("https://prod-api.example.com");
|
||||
expect(process.env.WEBPACK_ENV).toBe("production");
|
||||
|
||||
// Value only in .env
|
||||
expect(process.env.WEBPACK_MODE).toBe("test");
|
||||
});
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
APP_NAME=MyApp
|
||||
CONFIG_TIMEOUT=5000
|
||||
WEBPACK_API_URL=should-not-be-exposed
|
||||
SECRET_KEY=also-hidden
|
|
@ -0,0 +1,63 @@
|
|||
"use strict";
|
||||
|
||||
/** @type {import("../../../../").Configuration[]} */
|
||||
module.exports = [
|
||||
// Test 1: Basic - default behavior with WEBPACK_ prefix
|
||||
{
|
||||
name: "basic",
|
||||
mode: "development",
|
||||
entry: "./basic.js",
|
||||
dotenv: true
|
||||
},
|
||||
// Test 2: Expand - variables are always expanded
|
||||
{
|
||||
name: "expand",
|
||||
mode: "development",
|
||||
entry: "./expand.js",
|
||||
dotenv: true
|
||||
},
|
||||
// Test 3: Custom dir - load from different directory
|
||||
{
|
||||
name: "custom-dir",
|
||||
mode: "development",
|
||||
entry: "./custom-envdir.js",
|
||||
dotenv: {
|
||||
dir: "./envs"
|
||||
}
|
||||
},
|
||||
// Test 4: Custom prefixes - multiple prefixes
|
||||
{
|
||||
name: "custom-prefixes",
|
||||
mode: "development",
|
||||
entry: "./custom-prefixes.js",
|
||||
dotenv: {
|
||||
dir: "./prefixes-env",
|
||||
prefix: ["APP_", "CONFIG_"]
|
||||
}
|
||||
},
|
||||
// Test 5: Mode-specific - .env.[mode] overrides
|
||||
{
|
||||
name: "mode-specific",
|
||||
mode: "production",
|
||||
entry: "./mode-specific.js",
|
||||
dotenv: true
|
||||
},
|
||||
// Test 6: Disabled dir - dir: false disables .env file loading
|
||||
{
|
||||
name: "disabled-dir",
|
||||
mode: "development",
|
||||
entry: "./disabled-dir.js",
|
||||
dotenv: {
|
||||
dir: false
|
||||
}
|
||||
},
|
||||
// Test 7: Custom template - load files based on custom template patterns
|
||||
{
|
||||
name: "custom-template",
|
||||
mode: "production",
|
||||
entry: "./custom-template.js",
|
||||
dotenv: {
|
||||
template: [".env", ".env.myLocal", ".env.[mode]", ".env.[mode].myLocal"]
|
||||
}
|
||||
}
|
||||
];
|
|
@ -3000,6 +3000,11 @@ declare interface Configuration {
|
|||
*/
|
||||
devtool?: string | false;
|
||||
|
||||
/**
|
||||
* Enable and configure the Dotenv plugin to load environment variables from .env files.
|
||||
*/
|
||||
dotenv?: boolean | DotenvPluginOptions;
|
||||
|
||||
/**
|
||||
* The entry point(s) of the compilation.
|
||||
*/
|
||||
|
@ -4419,6 +4424,74 @@ declare interface DllReferencePluginOptionsManifest {
|
|||
| "jsonp"
|
||||
| "system";
|
||||
}
|
||||
declare class DotenvPlugin {
|
||||
constructor(options?: DotenvPluginOptions);
|
||||
config: {
|
||||
/**
|
||||
* The directory from which .env files are loaded. Can be an absolute path, or a path relative to the project root. false will disable the .env file loading.
|
||||
*/
|
||||
dir?: string | boolean;
|
||||
/**
|
||||
* Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.
|
||||
*/
|
||||
prefix?: string | string[];
|
||||
/**
|
||||
* Template patterns for .env file names. Use [mode] as placeholder for the webpack mode. Defaults to ['.env', '.env.local', '.env.[mode]', '.env.[mode].local'].
|
||||
*/
|
||||
template?: string[];
|
||||
};
|
||||
apply(compiler: Compiler): void;
|
||||
|
||||
/**
|
||||
* Get list of env files to load based on mode and template
|
||||
* Similar to Vite's getEnvFilesForMode
|
||||
*/
|
||||
getEnvFilesForMode(
|
||||
inputFileSystem: InputFileSystem,
|
||||
dir: string,
|
||||
mode?: string
|
||||
): string[];
|
||||
|
||||
/**
|
||||
* Load environment variables from .env files
|
||||
* Similar to Vite's loadEnv implementation
|
||||
*/
|
||||
loadEnv(
|
||||
fs: InputFileSystem,
|
||||
mode: undefined | string,
|
||||
context: string,
|
||||
callback: (
|
||||
err: null | Error,
|
||||
env?: Record<string, string>,
|
||||
fileDependencies?: string[]
|
||||
) => void
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Load a file with proper path resolution
|
||||
*/
|
||||
loadFile(fs: InputFileSystem, file: string): Promise<string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for Dotenv plugin.
|
||||
*/
|
||||
declare interface DotenvPluginOptions {
|
||||
/**
|
||||
* The directory from which .env files are loaded. Can be an absolute path, or a path relative to the project root. false will disable the .env file loading.
|
||||
*/
|
||||
dir?: string | boolean;
|
||||
|
||||
/**
|
||||
* Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.
|
||||
*/
|
||||
prefix?: string | string[];
|
||||
|
||||
/**
|
||||
* Template patterns for .env file names. Use [mode] as placeholder for the webpack mode. Defaults to ['.env', '.env.local', '.env.[mode]', '.env.[mode].local'].
|
||||
*/
|
||||
template?: string[];
|
||||
}
|
||||
declare class DynamicEntryPlugin {
|
||||
constructor(context: string, entry: () => Promise<EntryStaticNormalized>);
|
||||
context: string;
|
||||
|
@ -8195,8 +8268,6 @@ declare class JavascriptParser extends ParserClass {
|
|||
* Parser options for javascript modules.
|
||||
*/
|
||||
declare interface JavascriptParserOptions {
|
||||
[index: string]: any;
|
||||
|
||||
/**
|
||||
* Set the value of `require.amd` and `define.amd`. Or disable AMD support.
|
||||
*/
|
||||
|
@ -18313,6 +18384,11 @@ declare interface WebpackOptionsNormalized {
|
|||
*/
|
||||
devtool?: string | false;
|
||||
|
||||
/**
|
||||
* Enable and configure the Dotenv plugin to load environment variables from .env files.
|
||||
*/
|
||||
dotenv?: boolean | DotenvPluginOptions;
|
||||
|
||||
/**
|
||||
* The entry point(s) of the compilation.
|
||||
*/
|
||||
|
@ -18514,7 +18590,13 @@ type WebpackOptionsNormalizedWithDefaults = WebpackOptionsNormalized & {
|
|||
} & { watch: NonNullable<undefined | boolean> } & {
|
||||
performance: NonNullable<undefined | false | PerformanceOptions>;
|
||||
} & { recordsInputPath: NonNullable<undefined | string | false> } & {
|
||||
recordsOutputPath: NonNullable<undefined | string | false>;
|
||||
recordsOutputPath:
|
||||
| (string & {
|
||||
dotenv: NonNullable<undefined | boolean | DotenvPluginOptions>;
|
||||
})
|
||||
| (false & {
|
||||
dotenv: NonNullable<undefined | boolean | DotenvPluginOptions>;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -19237,6 +19319,7 @@ declare namespace exports {
|
|||
DllPlugin,
|
||||
DllReferencePlugin,
|
||||
DynamicEntryPlugin,
|
||||
DotenvPlugin,
|
||||
EntryOptionPlugin,
|
||||
EntryPlugin,
|
||||
EnvironmentPlugin,
|
||||
|
|
Loading…
Reference in New Issue