旧的做法

在开发项目我们使用的是局域网的 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