mirror of https://github.com/webpack/webpack.git
Compare commits
3 Commits
7a214cb7d1
...
34737a8a26
| Author | SHA1 | Date |
|---|---|---|
|
|
34737a8a26 | |
|
|
08625a84d7 | |
|
|
9f98d803c0 |
|
|
@ -1128,6 +1128,10 @@ export interface DotenvPluginOptions {
|
||||||
* Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.
|
* Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.
|
||||||
*/
|
*/
|
||||||
prefix?: string[] | string;
|
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.
|
* Multiple entry bundles are created. The key is the entry name. The value can be a string, an array or an entry description object.
|
||||||
|
|
@ -3370,7 +3374,6 @@ export interface JavascriptParserOptions {
|
||||||
* Set the inner regular expression for partial dynamic dependencies.
|
* Set the inner regular expression for partial dynamic dependencies.
|
||||||
*/
|
*/
|
||||||
wrappedContextRegExp?: RegExp;
|
wrappedContextRegExp?: RegExp;
|
||||||
[k: string]: any;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Generator options for json modules.
|
* Generator options for json modules.
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ const { join } = require("./util/fs");
|
||||||
/** @type {DotenvPluginOptions} */
|
/** @type {DotenvPluginOptions} */
|
||||||
const DEFAULT_OPTIONS = {
|
const DEFAULT_OPTIONS = {
|
||||||
prefix: "WEBPACK_",
|
prefix: "WEBPACK_",
|
||||||
dir: true
|
dir: true,
|
||||||
|
template: [".env", ".env.local", ".env.[mode]", ".env.[mode].local"]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Regex for parsing .env files
|
// Regex for parsing .env files
|
||||||
|
|
@ -225,27 +226,6 @@ const resolveEnvPrefix = (rawPrefix) => {
|
||||||
return prefixes;
|
return prefixes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Get list of env files to load based on mode
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
const getEnvFilesForMode = (inputFileSystem, dir, mode) => {
|
|
||||||
if (dir) {
|
|
||||||
return [
|
|
||||||
/** default file */ ".env",
|
|
||||||
/** local file */ ".env.local",
|
|
||||||
/** mode file */ `.env.${mode}`,
|
|
||||||
/** mode local file */ `.env.${mode}.local`
|
|
||||||
].map((file) => join(inputFileSystem, dir, file));
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format environment variables as DefinePlugin definitions
|
* Format environment variables as DefinePlugin definitions
|
||||||
* @param {Record<string, string>} env environment variables
|
* @param {Record<string, string>} env environment variables
|
||||||
|
|
@ -281,7 +261,7 @@ class DotenvPlugin {
|
||||||
/** @type {string[] | undefined} */
|
/** @type {string[] | undefined} */
|
||||||
let fileDependenciesCache;
|
let fileDependenciesCache;
|
||||||
|
|
||||||
compiler.hooks.beforeRun.tapAsync(PLUGIN_NAME, (_params, callback) => {
|
compiler.hooks.beforeCompile.tapAsync(PLUGIN_NAME, (_params, callback) => {
|
||||||
const inputFileSystem = /** @type {InputFileSystem} */ (
|
const inputFileSystem = /** @type {InputFileSystem} */ (
|
||||||
compiler.inputFileSystem
|
compiler.inputFileSystem
|
||||||
);
|
);
|
||||||
|
|
@ -314,6 +294,27 @@ class DotenvPlugin {
|
||||||
definePlugin.apply(compiler);
|
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
|
* Load environment variables from .env files
|
||||||
* Similar to Vite's loadEnv implementation
|
* Similar to Vite's loadEnv implementation
|
||||||
|
|
@ -333,7 +334,6 @@ class DotenvPlugin {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return callback(/** @type {Error} */ (err));
|
return callback(/** @type {Error} */ (err));
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDir = () => {
|
const getDir = () => {
|
||||||
if (typeof rawDir === "string") {
|
if (typeof rawDir === "string") {
|
||||||
return join(fs, context, rawDir);
|
return join(fs, context, rawDir);
|
||||||
|
|
@ -341,16 +341,13 @@ class DotenvPlugin {
|
||||||
if (rawDir === true) {
|
if (rawDir === true) {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
if (rawDir === false) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
const dir = getDir();
|
const dir = getDir();
|
||||||
|
|
||||||
// Get env files to load
|
// Get env files to load
|
||||||
const envFiles = getEnvFilesForMode(fs, dir, mode);
|
const envFiles = this.getEnvFilesForMode(fs, dir, mode);
|
||||||
/** @type {string[]} */
|
/** @type {string[]} */
|
||||||
const fileDependencies = [];
|
const fileDependencies = [];
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -677,6 +677,15 @@
|
||||||
"minLength": 1
|
"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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1837,7 +1846,7 @@
|
||||||
"JavascriptParserOptions": {
|
"JavascriptParserOptions": {
|
||||||
"description": "Parser options for javascript modules.",
|
"description": "Parser options for javascript modules.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": true,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"amd": {
|
"amd": {
|
||||||
"$ref": "#/definitions/Amd"
|
"$ref": "#/definitions/Amd"
|
||||||
|
|
|
||||||
|
|
@ -523,6 +523,32 @@ Object {
|
||||||
"multiple": false,
|
"multiple": false,
|
||||||
"simpleType": "boolean",
|
"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 {
|
"entry": Object {
|
||||||
"configs": Array [
|
"configs": Array [
|
||||||
Object {
|
Object {
|
||||||
|
|
|
||||||
|
|
@ -671,4 +671,4 @@ Before we started using OpenCollective, donations were made anonymously. Now tha
|
||||||
[dependency-review-url]: https://github.com/webpack/webpack/actions/workflows/dependency-review.yml
|
[dependency-review-url]: https://github.com/webpack/webpack/actions/workflows/dependency-review.yml
|
||||||
[dependency-review]: https://github.com/webpack/webpack/actions/workflows/dependency-review.yml/badge.svg
|
[dependency-review]: https://github.com/webpack/webpack/actions/workflows/dependency-review.yml/badge.svg
|
||||||
[cover]: https://codecov.io/gh/webpack/webpack/graph/badge.svg?token=mDP3mQJNnn
|
[cover]: https://codecov.io/gh/webpack/webpack/graph/badge.svg?token=mDP3mQJNnn
|
||||||
[cover-url]: https://codecov.io/gh/webpack/webpack
|
[cover-url]: https://codecov.io/gh/webpack/webpack
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,6 @@ WEBPACK_PORT=${PORT:-3000}
|
||||||
|
|
||||||
# Mode-specific base value
|
# Mode-specific base value
|
||||||
WEBPACK_ENV=development
|
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,2 @@
|
||||||
|
# Custom template test - production.myLocal file
|
||||||
|
WEBPACK_PROD_CUSTOM=from-production-myLocal
|
||||||
|
|
@ -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");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -50,5 +50,14 @@ module.exports = [
|
||||||
dotenv: {
|
dotenv: {
|
||||||
dir: false
|
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"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -4435,9 +4435,23 @@ declare class DotenvPlugin {
|
||||||
* Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.
|
* Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.
|
||||||
*/
|
*/
|
||||||
prefix?: string | string[];
|
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;
|
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
|
* Load environment variables from .env files
|
||||||
* Similar to Vite's loadEnv implementation
|
* Similar to Vite's loadEnv implementation
|
||||||
|
|
@ -4472,6 +4486,11 @@ declare interface DotenvPluginOptions {
|
||||||
* Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.
|
* Only expose environment variables that start with these prefixes. Defaults to 'WEBPACK_'.
|
||||||
*/
|
*/
|
||||||
prefix?: string | string[];
|
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 {
|
declare class DynamicEntryPlugin {
|
||||||
constructor(context: string, entry: () => Promise<EntryStaticNormalized>);
|
constructor(context: string, entry: () => Promise<EntryStaticNormalized>);
|
||||||
|
|
@ -8249,8 +8268,6 @@ declare class JavascriptParser extends ParserClass {
|
||||||
* Parser options for javascript modules.
|
* Parser options for javascript modules.
|
||||||
*/
|
*/
|
||||||
declare interface JavascriptParserOptions {
|
declare interface JavascriptParserOptions {
|
||||||
[index: string]: any;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of `require.amd` and `define.amd`. Or disable AMD support.
|
* Set the value of `require.amd` and `define.amd`. Or disable AMD support.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue