Webpack多城市部署前端差別化配置實現

公司的項目須要多城市部署,不一樣城市接口地址、相關服務地址都會不一樣;同時,還須要實現控制不一樣城市部分功能開啓/關閉。這樣一來,每次不一樣城市發包須要修改的地方就會比較多且分散,這樣就很容易出現疏漏。
因此,咱們將不一樣城市差別化配置單獨使用一個配置文件整合,代碼中再經過讀取配置文件來實現上述需求。
項目使用vue-cli@2.9.6建立;node版本:v8.11.1;。咱們一開始執行不一樣的腳本命令,配置不一樣的環境參數,來實現不一樣城市的區分。以下:javascript

經過運行不一樣命令讀取不一樣配置

第一步,在package.jsonscripts添加腳本設置環境參數

...
"script": {
    ...
    "dev:changsha": "webpack-dev-server --inline --progress --env=changsha --config build/webpack.dev.conf.js",
    "build:changsha": "node build/build.js --env=changsha"
}
...

第二步,使用yargsbuild.jswebpack.dev.conf.js讀取環境參數並添加到process.env

// build/build.js
...
const argv = require('yargs').argv;
process.env.cityName = argv.env
...
// build/webpack.dev.conf.js
...
const argv = require('yargs').argv;
process.env.cityName = argv.env
...

注意: 這裏由於build腳本是使用的node命令,而node命令是可自行添加任意參數的,便可以使用任意變量名作爲環境參數;但webpack-dev-server命令卻只支持使用--env選項配置環境參數。這裏build也使用了env變量來設置環境參數。可是你也能夠這樣添加build腳本:html

"build:changsha": "node build/build.js --cityName=changsha"

而後在build.js使用相應的變量讀取:前端

const argv = require('yargs').argv;
process.env.cityName = argv.cityName
...

第三步,經過webpack讀取不一樣城市的配置文件

./config文件夾下添加changsha,chengdu兩個文件夾,分別在兩個文件夾中添加dev.conf.jsprod.conf.js。例如:vue

// ./config/changsha/dev.conf.js
module.exports = {
    apisIp:'"http://192.200.115.1:8080"',
    videoIp:'"http://192.200.115.2:8080"',
    openFun1: true,
    openFun2: true
    ...
}
// ./config/changsha/prod.conf.js
module.exports = {
    apisIp:'"http://192.200.141.1:8080"',
    videoIp:'"http://192.200.141.2:8080"',
    openFun1: true,
    openFun2: false
    ...
}

而後./config下的prod.env.jsdev.env.js分別讀取prod.conf.jsdev.conf.js配置java

// 修改./config/dev.env.js爲
'use strict'
const prodEnv = require('./prod.env')
const cityConf = require(`./${process.env.cityName||'chengdu'}/dev.conf.js`)
module.exports = Object.assign(prodEnv, {NODE_ENV: '"development"'}, cityConf)
// 修改./config/dev.env.js爲
'use strict'
const cityConf = require(`./${process.env.cityName||'chengdu'}/prod.conf.js`)
module.exports = {
  NODE_ENV: '"production"',
  ...cityConf
}

注意:node

  • prod.env.jsdev.env.js都默認加載chengdu文件下相應的配置;
  • 之因此在prod.env.jsdev.env.js中加載相應配置就會生效,是由於在webpack.prod.conf.jswebpack.dev.conf.js兩個文件中分別讀取前兩個文件;webpack.dev.conf.js就是開發環境的入口文件;打包的入口文件build.js讀取了webpack.prod.conf.js
  • webpack.dev.conf.jswebpack.prod.conf.js都是使用DefinePlugin插件將環境配置寫入process.dev的。因此,你也可使用其它變量名保存配置;同時,你也能夠不經過prod.env.jsdev.env.js讀取配置,能夠直接在webpack.dev.conf.jswebpack.prod.conf.js中讀取;
  • Node.js有一個process全局變量,webpack也會生成一個process,這兩個只是名稱相同,但並非同一個對象;前一個process只能webpack讀取,咱們在具體的前端代碼中是沒法讀取的;後一個爲webpack供給前端代碼讀取的全局變量,打包後webpack會將全部調用prcess的代碼直接替換爲具體的值;

最後,在具體前端代碼中讀取使用

// 例如,在./src/components/HelloWorld.vue中,咱們能夠這樣使用:
<template>
  <div class="hello">
    <video><source :src="videoIp +'/a.mp4'"/></video>
    <div v-if="openFun1">放開功能1入口</div>
    <div v-if="openFun2">放開功能2入口</div>
  </div>
</template>

<script>
const apisIp = process.env.apisIp
export default {
  name: 'HelloWorld',
  data () {
    return {
      videoIp: process.env.videoIp,
      openFun1: process.env.openFun1,
      openFun2: process.env.openFun2
    }
  },
  methods: {
    getData () {
      this.$axios.get(apisIp + '/apis/daga')
        .then((data) => { console.log(data) })
    }
  }
}
</script>
...

總結

最後,總結梳理一下思路,大概是如下幾步:webpack

  1. 經過命令行參數寫入環境參數;
  2. 將環境參數保存全node全局變量process的env對象上;
  3. webpack根據環境參數讀取相應配置並寫入一個全局變量供代碼讀取;
  4. 具體代碼中,經過讀取上一步定義的全局變量,實現相關功能;
相關文章
相關標籤/搜索