Modern.js 提供了对环境变量的支持,包含内置的环境变量和自定义的环境变量。
表示当前资源文件的路径前缀,是只读的的环境变量。
表示当前的执行环境,是只读的的环境变量,其值在不同的执行命令下具有不同的值:
production
:执行 modern build
、modern serve
命令时的默认值。test
:执行 modern test
命令时的默认值。development
:执行 modern dev
命令时的默认值,同时也是其他所有情况下的默认值。手动设置当前的执行环境。除了上述 NODE_ENV 对应的值之外,这里支持自定义环境名称,例如 staging
、boe
等。
TIP
MODERN_ENV 的优先级高于 NODE_ENV。
使用 @modern-js/runtime
时会自动注入,用于区分 SSR 与 CSR 环境。开发者可以自行在代码中判断,构建时会默认移除 dead code。
function App() {
if (process.env.MODERN_TARGET === 'browser') {
console.log(window.innerHeight);
}
}
开发环境打包后,可以看到 SSR 产物和 CSR 产物如下:
function App() {
if (false) {
}
}
function App() {
if (true) {
console.log(window.innerHeight);
}
}
NOTE
在生产环境,会将 dead code 移除,例如上述 if
语句。
这种方式可以针对不同客户端提供不同的产物,保证代码体积最小化。也能方便处理不同环境下,代码中的一些副作用,
环境变量支持通过 shell
和 .env
文件两种方式指定。
shell
指定在命令前添加自定义环境变量:
REACT_APP_FOO=123 BAR=456 pnpm run dev
.env
文件指定在项目根目录创建 .env
文件,并添加自定义环境变量,这些环境变量会默认添加到启动项目的 Node.js 进程中,例如:
REACT_APP_FOO=123
BAR=456
.env
文件遵循以下规则加载规则:
.env
:默认加载。.env.{ MODERN_ENV | NODE_ENV }
:针对具体环境设置环境变量,会覆盖 .env
中的设置。当需要根据环境使用不同的配置时,可以把环境变量定义到对应环境名称的 .env
文件中,并在启动项目时手动设置执行环境。例如使用以下命令启动项目时,将会加载 .env
和 .env.staging
:
MODERN_ENV=staging pnpm run dev
在前端代码中可以直接使用 NODE_ENV
环境变量。另外,以 MODERN_
开头的自定义环境变量,也可以在代码中直接使用。
例如:
if (process.env.NODE_ENV === 'development') {
// do something
}
执行 pnpm run dev
命令之后可以看到如下构建产物:
if (true) {
// do something
}
同样在自定义的 HTML 模板中,也可以直接使用这类环境变量。如 config/html/head.html
:
<meta name="test" content="<process.env.NODE_ENV>">
如果需要在代码中使用任意名称的环境变量,可以在 source.globalVars
配置指定, 例如:
export default defineConfig({
source: {
globalVars: {
'process.env.VERSION': process.env.VERSION,
}.
},
});
此时,在代码中的 process.env.VERSION
,将会被替换为环境变量中 VERSION
的值。
NOTE
source.globalVars
也支持将其他表达式或字符串替换为指定的值,不仅限于环境变量。
除了环境变量,Modern.js 也支持将代码中的变量替换成其它值或者表达式,可以用于在代码逻辑中区分开发环境与生产环境等场景。
例如将代码中的 TWO
转换为 1 + 1
的表达式:
export default {
source: {
define: {
TWO: '1 + 1',
},
},
};
const foo = TWO;
// ⬇️ Turn into being...
const foo = 1 + 1;
在大多数情况下,source.globalVars
已经能满足替换变量的需求。但 source.globalVars
传入的值都会默认被 JSON 序列化,因此无法做出像上面例子中 1 + 1
的替换,此时就需要使用 source.define
。