使用process.env.NODE_ENV的正确姿势
什么是process.env.NODE_ENV
process.env.NODE_ENV
应该是我们最熟悉的环境变量了,它经常出现在使用框架或者类库的时候,被用来区分不同的环境(开发,测试,生产等),以便我们进行相对应的项目配置,比如是否开启sourceMap,api地址切换等。那为什么process.env.NODE_ENV
能用来区分环境呢?它是如何来的?
先来看一下process
和process.env
的官方解释:
- process
process
对象是一个 global
(全局变量),提供有关信息,控制当前 Node.js 进程。作为一个对象,它对于 Node.js 应用程序始终是可用的,故无需使用 require()
。
- process.env
process.env
属性返回一个包含用户环境信息的对象。
在node环境中,当我们打印process.env
时,发现它并没有NODE_ENV
这一个属性。实际上,process.env.NODE_ENV
是在package.json的scripts
命令中注入的,也就是NODE_ENV
并不是node自带的,而是由用户定义的,至于为什么叫NODE_ENV
,应该是约定成俗的吧。
{ "scripts": { "dev": "NODE_ENV=development webpack --config webpack.dev.config.js" } }
可以看到NODE_ENV
被赋值为development
,当执行npm run dev
时,我们就可以在 webpack.dev.config.js
脚本中以及它所引入的脚本中访问到process.env.NODE_ENV
,而无法在其它脚本中访问。
如何在其他脚本中访问
前面提到,在scripts
命令中注入的NODE_ENV
只能被webpack的构建脚本访问,而被webpack打包的源码中是无法访问到的,此时可以借助webpack的DefinePlugin插件,创建全局变量。
const webpack = require('webpack'); module.exports = { plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"development"' }) ] }
当然DefinePlugin
不仅仅可以定义process.env.NODE_ENV
,你也可以根据自己的需要定义其他的全局变量。定义完成之后,就可以在项目代码中直接使用了。
跨平台的cross-env
在window平台下直接设置NODE_ENV =XXX
是会报错的,cross-env
能够提供一个设置环境变量的scripts
,这样我们就能够以unix方式设置环境变量,然后在windows上也能够兼容。
- 安装
cross-env
npm install cross-env --save
- 在
NODE_ENV=XXX
前面添加cross-env
。"scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server" }
使用.env文件
如果需要配置的环境变量太多,全部设置在scripts
命令中既不美观也不容易维护,此时将环境变量配置在.env
文件中,然后使用dotenv
插件来加载.env
配置文件。
- 安装
dotenv
npm install dotenv --save
- 创建
.env
文件
NODE_ENV = development # 这是注释 API_URL = https://abc.com
- 尽早的在程序中引入和配置
dotenv
。在config函数中可以配置.env文件的路径。具体参考dotenv文档
require('dotenv').config()
这样就可以在程序中使用环境变量了。
在实际项目中,我们一般还是在scripts
命令中设置NODE_ENV
,然后通过不同的NODE_ENV
来加载不同的.env
文件。
举个例子:
有一个项目,简单的项目结构如下:
├── env
├── .env.dev
├── .env.test
├── .env.pre
└── .env.prd
├── webpack.config.js
.env.***
文件中配置了每个环境对应的变量,例如:
# .env.test 文件 API_URL = https://abc-test.com # .env.pre 文件 API_URL = https://abc-pre.com # .env.prd 文件 API_URL = https://abc.com
在webpack.config.js
加载env
配置:
require('dotenv').config({ path: path.resolve(__dirname, './env/.env.' + process.env.NODE_ENV) })
最后别忘了还要在scripts
命令中设置NODE_ENV
:
# dev cross-env NODE_ENV=dev # test cross-env NODE_ENV=test # pre cross-env NODE_ENV=pre # prd cross-env NODE_ENV=prd
Vue cli
也可以加载.env
文件,详情可查看:Vue cli-环境变量和模式