前两篇文章我们分别介绍了vue-cli3的动态路由和axios封装,今天我们来说说vue-cli3的多环境配置和项目配置文件抽离。


多环境配置

大多数项目在正式上线的时候都会分为多个环境,其中最常见的就是开发环境和生产环境,有时候我们还需要一个测试环境,但是当我们利用@vue/cli生成脚手架时,在脚手架中却没有测试环境的打包命令

1
2
3
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint --fix"

在vue-cli2打包时可以通过修改 “build” 和 “config”中的文件来区分不同的线上环境,但是vue-cli3号称0配置,不能够直接修改打包的配置文件。这个时候vue-cli3提供的定制环境变量的作用就体现出来了。
vue-cli3总共提供了四种方式来制定环境变量:

  1. 在根目录添加.env文件,配置所有情况下都会用到的配置(不知道这个存在的意义,所有的都需要的也就不需要配置了吧)。
  2. 在根目录添加.env.local 文件,配置所有情况下都会用到的配置,与.env的区别是只会在本地,该文件不会被git跟踪。
  3. 在根目录添加.env.[mode] 文件,配置对应某个模式下的配置,比如:.env.development来配置开发环境的配置。
  4. 在根目录添加.env.[mode].local文件,配置对应某个模式下的配置,与.env.[mode]的区别也只是会在本地生效,该文件不会被git跟踪。
    在文件中,我们只需要以key=value的方式就可以设置变量了。
    好了,废话不多说,我们直接来看怎么实现。
  5. package.json添加 “test”: “vue-cli-service build –mode test”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
···
"scripts": {
"serve": "vue-cli-service serve", //本地运行,会把process.env.NODE_ENV设置为‘development’
// 打包,会把process.env.NODE_ENV设置为步骤2中‘.env.test’文件设置的值。
// 注意,这里 “--mode 名字“ 要和步骤2中文件名“.env.xx”保持一致
"test": "vue-cli-service build --mode test",
"build": "vue-cli-service build" //打包, 会把process.env.NODE_ENV设置为‘production’
},
"dependencies": {
···
},
···
}
  1. 在项目根目录添加.env.test文件
  2. 在.env.test中添加需要的配置信息
1
2
3
4
5
6
// 表示加载不同的配置
NODE_ENV = 'production'
// 用于区分生产环境和测试环境
VUE_APP_TITLE = 'test'
// 可通过process.env.VUE_APP_URL引用
VUE_APP_URL = '//at.alicdn.com/t/font_1069352_iol3svrd7cd.js'

完成了以上步骤,我们就配置完了测试环境。接下来就可以直接运行yarn test开始打包了。

项目配置文件抽离

在项目完成之后,我们需要将前端项目打包发布到不同的服务器。项目部署到不同的服务器,后端的地址也有可能会发生变化,那么我们就不得不修改项目配置文件,然后重新打包发布。听着就觉得麻烦,有没有什么办法可以直接修改配置文件而不用重新打包发布呢?当我们需要更改后端接口地址的时候,只需要在配置文件中修改对应的地址,然后刷新页面,马上就能生效,这样是不是简单多了呢?下面我们就来说说怎么实现。
其实原理很简单,利用process对象,获取启动Node.js进程时的命令行参数(process.env),匹配当前开发或生产的环境常量挂载到process.env。

  1. 在public文件夹下面新建一个配置文件buildConfig.js

    看过vue-cli3源码的小伙伴想必都知道,public文件夹下面的文件在打包时不会被压缩,而是被复制到dist文件夹
1
2
3
4
5
6
7
8
9
10
11
12
// copy static assets in public/
const publicDir = api.resolve('public')
if (!isLegacyBundle && fs.existsSync(publicDir)) {
webpackConfig
.plugin('copy')
.use(require('copy-webpack-plugin'), [[{
from: publicDir,
to: outputDir,
toType: 'dir',
ignore: publicCopyIgnore
}]])
}

打包后:

2. 在index.html文件中引入配置文件,引入的方法很简单

3. 在项目中需要使用的地方直接使用process.env引用

当只有一个环境时这种方案就很好了,
但是如果需要经常性的打包,比如说频繁切换测试环境和生产环境,那我们每次打完包之后又需要去修改一次配置文件中的后端地址,工作量并没有减轻多少。
不会偷懒的程序员不是好的程序员–鲁迅

看吧,鲁迅先生都有有理。
好了,继续接上面的说,得益于配置多页面时的灵感,我们可以使用webpack插件htmlwebpackplugin来解决这个问题。
这里举个测试环境的例子,首先我们在上面的基础上在新建一个文件testConfig.js

然后在vue.config.js中利用htmlwebpackplugin插件动态加载不同的配置文件,比如说打包生产环境时,加载buildConfig.js文件,打包测试环境时加载testConfig.js文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const IsFormalProduction = process.env.VUE_APP_TITLE === 'production';
const IsDevelopment = process.env.VUE_APP_TITLE === 'development';
const IsTest = process.env.VUE_APP_TITLE === 'test';

const envConfig = {
dev: {},
test: {
config: ['/testConfig.js']
},
build: {
config: ['/buildConfig.js']
}
};
...
chainWebpack: config => {
config.resolve.alias.set('@', resolve('src')).set('_c', resolve('src/components'));
config.plugin('html').tap(args => {
if (IsFormalProduction) {
args[0].config = envConfig.build.config;
} else if (IsTest) {
args[0].config = envConfig.test.config;
}
return args;
});
}
...

这样我们就完成了动态加载外部配置文件的目的了,最后我们只需要在html中加载对应的js即可。

完成了以上步骤,我们来测试一下
运行yarn test打包测试环境,在nginx上部署


运行yarn build打包生产环境,在nginx上部署

完美测试通过,perfect。


本文完