旧的做法

在开发项目我们使用的是局域网的ip,部署的时候可能要改为外网的ip,每次打包都需要在代码修改指定的ip,拿 vue-cli 创建的项目来说,对于API接口的ip我们可以这样动态来修改

window.axios = axios.create({
  baseURL: process.env.NODE_ENV === 'production' ? 'https://service/api/': 'https://1.2.3.4/api/',
  timeout: 60000,
  withCredentials: true
});

这样虽然可行,但是如果复杂的场景下就比较麻烦,比如我们在本地开发的时候想指定外网的ip来测试,又如打包的时候有不同的版本(开发版本,测试版本,线上版本),指向不同的ip地址,这样配置起来就会很麻烦,后来想到下面这种解决方法

当执行 npm run build 的时候,webpack可以通过 webpack.DefinePlugin 插件来实现的全局变量,vue-cli是在 build/webpack.prod.config.js 里面定义 process.env 变量

new webpack.DefinePlugin({
    'process.env': require('../config/prod.env')
})

我们可以在 config 目录下新建一个 build.env.js 文件来针对不同环境进行配置全局变量

'use strict'
const lifeCycleEvnet = process.env.npm_lifecycle_event        // 返回当前运行脚本的名称
let buildEnv = {};

if (lifeCycleEvnet === 'build:dev' || lifeCycleEvnet === 'start:dev') {
  buildEnv = {
    NODE_ENV: '"development"',
    UPLOAD_IP: '"127.0.0.1:8080"',
    AJAX_IP: '"http://localhost:8989"'
  }
} else if (lifeCycleEvnet === 'build:pro' || lifeCycleEvnet === 'start:pro') {
  buildEnv = {
    NODE_ENV: '"production"',
    UPLOAD_IP: '"https://upload.service.com"',
    AJAX_IP: '"https://service.com/api/"'
  }
}

module.exports = buildEnv;

然后在 bulid/webpack.prod.config.jsbuild/webpack.dev.config.js 两个文件修改 process.env 变量指向

new webpack.DefinePlugin({
  'process.env': require('../config/build.env')
})

webpack就可以在模块里面通过 process.env 获取该全局变量相关的配置,上面的ajax请求ip配置可以改为

window.axios = axios.create({
  baseURL: process.env.AJAX_IP,
  timeout: 60000,
  withCredentials: true
});

为了方便开发和打包,我们可以在 package.json 新增以下命令

"scripts": {
  "start:pro": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "start:dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "build:dev": "node build/build.js",
  "build:pro": "node build/build.js"
}

这样就可以实现不同命令来配置不同的变量值

更友好的选择

由于文章写得比较老,现在有一个库可以直接用,非常简洁,贡献上地址 env-cmd