Webpack 5构建时与运行时环境变量配置问题
实现Webpack区分构建时与运行时环境变量的方案
一、明确两类变量的差异
- 构建时变量:打包阶段确定,直接嵌入最终代码,比如你现有脚本里的
ENV=qa/prod这类环境标识,适合用Webpack原生能力注入。 - 运行时变量:部署或启动应用时才确定,不能打包进代码,需要通过动态加载、全局注入这类方式获取。
二、具体实现步骤
1. 配置构建时变量(Webpack层面)
在webpack.config.js中使用DefinePlugin注入构建时变量,专门处理打包阶段就能确定的参数,同时给运行时变量留好占位:
const webpack = require('webpack'); // 读取构建脚本传入的ENV参数,默认prod const buildEnv = process.env.ENV || 'prod'; module.exports = { // 其他Webpack配置... plugins: [ new webpack.DefinePlugin({ // 用BUILD_前缀区分构建时变量 'process.env.BUILD_ENV': JSON.stringify(buildEnv), // 运行时变量先设为null,后续动态赋值 'process.env.RUNTIME_VARS': 'null' }) ] };
2. 处理运行时变量
方式一:动态加载配置文件
- 打包前在项目
public目录下创建模板文件runtime-config.template.js:
window.runtimeConfig = { API_BASE_URL: '{{API_BASE_URL}}', CDN_DOMAIN: '{{CDN_DOMAIN}}' };
- 部署时用脚本替换模板里的占位符,生成实际的运行时配置文件,比如Linux环境下的启动脚本:
# 替换API地址占位符 sed -i "s/{{API_BASE_URL}}/${API_BASE_URL}/g" public/runtime-config.js # 替换CDN地址占位符 sed -i "s/{{CDN_DOMAIN}}/${CDN_DOMAIN}/g" public/runtime-config.js
- 在应用入口文件(如
index.js)中加载该配置并赋值:
// 加载运行时配置 import '../public/runtime-config.js'; // 将全局配置挂载到process.env process.env.RUNTIME_VARS = window.runtimeConfig; // 使用示例 console.log('当前构建环境:', process.env.BUILD_ENV); console.log('接口请求地址:', process.env.RUNTIME_VARS.API_BASE_URL);
方式二:容器化部署下的全局注入
如果用Docker等容器部署,可以在启动服务时将运行时变量注入到index.html的全局变量中:
- 修改
index.html的<head>部分:
<script> window.runtimeConfig = { API_BASE_URL: '%API_BASE_URL%', CDN_DOMAIN: '%CDN_DOMAIN%' }; </script>
- 容器启动脚本中替换占位符(以Nginx为例):
envsubst '\$API_BASE_URL \$CDN_DOMAIN' < /usr/share/nginx/html/index.html > /usr/share/nginx/html/index.tmp && mv /usr/share/nginx/html/index.tmp /usr/share/nginx/html/index.html
- 应用内同样从
window.runtimeConfig读取变量并挂载到process.env使用。
3. 保留现有构建脚本
你的现有构建脚本无需修改,因为ENV属于构建时变量,打包时会通过process.env.ENV被Webpack读取:
"scripts": { "build": "webpack --mode=production", "build:qa": "ENV=qa webpack --mode=production", "build:prod": "ENV=prod webpack --mode=production" }
三、关键注意事项
- 构建时变量必须是打包阶段就能确定的值,这类变量会被Webpack直接替换为具体内容,运行时无法修改。
- 运行时变量绝对不能用
DefinePlugin注入,否则会被固化到代码中,失去动态配置的意义。 - 建议用前缀(如
BUILD_、RUNTIME_)区分两类变量,避免代码中混淆使用。
内容的提问来源于stack exchange,提问作者MrVoland
相关产品推荐
相关产品推荐

