likes
comments
collection
share

对环境变量的思考

作者站长头像
站长
· 阅读数 23

背景

环境变量是很常见的技术的名词,但背后的逻辑你是否清楚,让我们一起review一下。

1. 为什么需要环境变量?

因为在不同的环境,可能会有不同的代码表现

  • 比如:
  • dev环境(本地),那打包出来的静态资源(.js .css)等都是在本地。
  • prd环境:则静态资源的路径大概率在CDN,这里就需要一个环境变量来控制

除了dev环境和prd环境外,还有哪些环境?

  • 比如全球部署时,会有多机房:欧美机房,新加坡机房等,要加载的资源或接口的域名可能都是不一样的,比如 api-sg.com 、api-va.com
  • 比如通过流水线上线的代码,也会有多种环境:测试环境、小流量环境、预发环境等,也可以用环境变量做一些特殊控制

2. 如何控制环境变量?

环境变量是在构建的阶段控制的

比如:

  • 当前是在开发dev环境,可以在启动node的时候增加环境变量,比如npm run dev启动dev服务,则在启动dev node时,添加 NODE_ENV=development
    "dev": "cross-env NODE_ENV=development ...",
    
  • 当打prd包时,则是npm run build,添加 NODE_ENV=production
    "build": "cross-env NODE_ENV=production ...",
    

这种是 最简单的方式,但还是不够灵活,因为要改启动脚本,而且不适合注入过多环境变量,而且多个环境,可能要多个脚本,管理起来也很麻烦。比如 欧美机房、小流量环境 要单独加启动脚本。

"build-va": "cross-env NODE_ENV=production region=va ...",
"build-canary": "cross-env NODE_ENV=production region=canary ...",

很明显我们需要更好的方式管理环境变量:借助上面的方式 + webpack的插件:webpack.docschina.org/plugins/def…

  • 原理是:DefinePlugin 会在 编译时 将你代码中的变量替换为其他值或表达式。

例如:

// webpack.config.js
plugins: [
    new webpack.DefinePlugin({
      PRODUCTION: JSON.stringify(process.env.NODE_ENV) === 'production',
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
    });
]    

// 正常前端代码内的process.env.NODE_ENV是undefined,用了这个插件后,就可以识别process.env.NODE_ENV了

那欧美机房、小流量环境 这种的环境变量怎么加呢?

在打包阶段做对应处理

  • 比如这个包是在欧美机房部署的,那么在打包部署的打包阶段,主动加入环境变量,比如process.env.XXXX = "VA",如果是小流量的机器,那么注入 process.env.XXXX = "xx"
  • 对应业务代码是:
// webpack.config.js
plugins: [
    new webpack.DefinePlugin({
      PRODUCTION: JSON.stringify(process.env.NODE_ENV) === 'production',
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
      'process.env.XXXX': JSON.stringify(process.env.XXXX),
    });
]    

3. 为什么环境变量都是写到 process.env 对象上?

可以看官网介绍,这是node的一个专门让用户可以预留信息的对象:nodejs.cn/api/process…


码字不易,点赞鼓励!