webpack打包Vue后生成一个可修改的配置文件

1,071 阅读3分钟

问题背景

工作中两个场景都需要将stg和prod环境的前端代码中不同的接口url 以及各种外部引用的url等提取到静态变量中,并且更改静态变量的配置url就可以改变网站的访问接口

场景一:做docker自动部署平台的时候,当服务器的地址发生变化,后端接口迁移了,然后前端需要在平台上可以自动部署而不是手动部署的时候,就需要有一个配置文件可以在线上编辑更改。

场景二:前端是用工程化生成的,但是整体没有前后端分离部署。后端通过自动化部署的时候需要经过 获取代码---普通编译---stg部署----prd部署 步骤,后端部署stg的时候用的是前端生成的stg代码。prod的时候是prod的代码,为了在上平台上部署,需要后端编写shell脚本,区分stg和prod环境,然后将前端不同的包在不同的阶段放到服务器的根目录下。因为是整个项目的静态资源包,可能比较大,需要先zip压缩然后再解压。后端就提出,可不可以只是把不同的环境的不同的部分提取出来,然后只是移动这一个文件,就可以大大提升部署速度。

解决方案

综上:寻找出两种方法来解决

  1. 方法一:前端将不同环境的配置放到一个config.js中,然后通过用户访问的不同的url来区分是线上还是测试环境。每次服务器发生变化,只需要改变这个配置文件区分不同环境访问的url
  • 首先在vue-cli静态文件夹 vuecli2是static文件下 vueCli3是public文件夹下新建config.js配置文件,包括不同环境的key对应的不同的接口地址等
// 在public目录下新建一个config.js文件
export consst config=[
  // 接口地址
  targetAddress: {
    local:"http://xxx.xxx.local.com",
    stg: "http://xxx.xxx.stg.com",
    prod:'http://xxx.xxx.prod.com',
  },
  urlMap: {
	local: ['10.118.120.41:8080','localhost:8080', '10.118.120.43:8089'],
	stg: ['XXX.XXX.stg.com'],
	prod: ['XXX.XX.prod.com'],
	cas: {
      local:"http://XXX.XXX.local/cas/#/",
      stg: "http://XXX.XXX.stg/cas/#/",
      prod:'http://XXX.XXX.prod/cas/#/',		
	}
  },
  developerUrl: {
    local:"http://XXX.XXX.local/subiectallmanage/",
    stg: "http://XXX.XXX.stg/subiectallmanage",
    prod:'http://XXX.XXX.prod/subiectallmanage',	 
  }
 ]
  • 然后在项目的api接口文件中引入config配置文件,并且根据用户输入的地址判断是哪一个环境(是local还是stg还是prod),然后根据环境取出对应config中的url地址即可
 // 在接口文件中 api/api.js下面写上如下代码
 import { config } from '../../public/js/config.js'
 let targetUrl = ''; // 后端接口Url
 const curUrl = window.location.href; // 用户输入的url
 const map = config.urlMap;
 for (let env in map) {
	if ( env != 'cas') {
		let hasUrl = map[env].some(e => {
			return curUrl.includes(e);
		})
		if (hasUrl) { targetUrl = config.targetAddress[env]; }
	}
 }
  1. 方法二:利用插件generate-asset-webpack-plugin在打包的时候生成json文件,然后通过axios请求获取json中的配置。因为后端可以区分是生产还是测试环境,所以只需要有一个默认的json文件和一个生产的json 测试的json。然后后端通过shell脚本判断当前环境替换生产json到默认json目录下面。
  • 安装插件 generate-asset-webpack-plugin
npm i generate-asset-webpack-plugin -D
  • vue.config.js中添加插件,使用插件生成json文件
var GenerateAssetPlugin = require('generate-asset-webpack-plugin');
var createServerConfig = function(compilation) {
    // 配置需要的api接口
    let cfgJson = {
        VUE_APP_SERVE_URL: process.env.VUE_APP_PULIC_PATH,
        VUE_APP_PULIC_ACTIVE: process.env.VUE_APP_PULIC_ACTIVE
    }
    return JSON.stringify(cfgJson);
}
    module.exports = {
        configureWebpack: {
            plugins: [
                new GenerateAssetPlugin({
                    // 不同的环境生成不同的json文件 stgConfig.json prdConfig.json
                    filename: `${process.env.VUE_APP_STATUS}Config.json`,
                    fn: function(compilation, cb) {
                        cb(null, createConfig(compilation))
                    }
                })
            ]
        }
    }
  • 配置完成后,运行npm run test打测试包,生成stgConfig.json文件在测试目录下,如下图

0001.png

  • 然后将生成的stgConfig.json改名为serverconfig.json复制一份到public下面,在src目录下面新建一个getConfigUrl.js文件
import axios from 'axios';
Vue.prototype.getConfigJson = function() {
        axios.get("serverconfig.json").then((result) => {
            //挂载到vue原型上面,这样就可以在项目中调用了
            Vue.prototype.$configApiUrl = result.data;
            console.log(result.data);
        }).catch((error) => {
            console.log('getConfigJson Error!', error)
        })
    }
  • 最后将项目中用到
process.env.VUE_APP_SERVE_URL替换成 this.$configApiUrl.VUE_APP_SERVE_URL 
process.env.VUE_APP_PULIC_ACTIVE替换this.$configApiUrl.VUE_APP_PULIC_ACTIVE

然后执行npm run build打包生成prdConfig.json将两个配置文件都给到后端即可。