天天看點

在基于vue-cli的項目自定義打包環境

在工作當中,遇到了下面這個問題:

測試環境與生産環境中的使用者權限不一樣,是以,就需要根據測試環境打一個包,生産環境又打一個包。

可是,如果每次打包都需要更改權限的配置檔案的話,會很麻煩,而且,展現不出一個coder該有的逼格。

為了更有逼格地解決這個問題,于是我百度了一番,上天不負有心人,讓我找到了解決方案。

在詳叙解決方案之前,先簡單介紹下解決方案當中使用到的工具:cross-env,webpack.DefinePlugin

  • cross-env是給process.env當中添加變量的,那process.env又是什麼呢?

process是一個控制node.js的程序,它是一個global對象,包含程序相關的一些資訊,而process.env則是包含使用者環境資訊的一個對象,例如下面這樣的對象:

{
  TERM: 'xterm-256color',
  SHELL: '/usr/local/bin/bash',
  USER: 'maciej',
  PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
  PWD: '/Users/maciej',
  EDITOR: 'vim',
  SHLVL: '1',
  HOME: '/Users/maciej',
  LOGNAME: 'maciej',
  _: '/usr/local/bin/node'
}
           

使用cross-env可以往這個process.env對象當中添加自定義的資料,然後可以在任何node.js的執行環境當中擷取,一般是在打包配置當中擷取process.env.NODE_ENV來判斷是哪種環境,然後再作相應的配置。

官方解釋
  • 如何使用cross-env
    1. 安裝:npm i cross-env -D
    2. 在npm自定義指令當中使用;
"script":{
    "build:testing":"cross-env NODE_ENV=‘testing’ webpack"
}
           

然後,我們執行npm run build:testing的時候,就好執行以上的指令,cross-env就會在process.env當中添加一個NODE_ENV的屬性,屬性的值就是‘testing’字元串,注意這裡是加了單引号的,因為這樣才是一個字元串,如果不加的話,就相當于一個代碼片段,還要在擷取完之後通過JSON.stringify去轉成字元串。

  • webpack.DefinePlugin又是什麼呢?

    webpack.DefinePlugin是webpack自帶的一個插件,它的作用是在編譯的時候生成一些全局變量的,這裡說的全局變量指的是用戶端的全局變量,相當于挂載在window對象上的變量,我們可以利用它的這個功能在不同的環境(開發,測試,或者生産)當中定義不同的行為。

    官方介紹與使用

介紹完兩個插件了,是時候說一下兩者結合在實際當中如何使用了。

下面将展示如何解決本文開頭一開始所提到的根據測試和生産環境配置不同的使用者權限的問題。

在config目錄下,根據不同的環境建立不同的配置檔案

在基于vue-cli的項目自定義打包環境

如上圖所示,test.env.js是測試環境的配置檔案,prod.env.js則是生産環境的配置檔案

  • test.env.js的配置
const merge = require('webpack-merge')
const devEnv = require('./dev.env')

module.exports = merge(devEnv, {
  NODE_ENV: '"testing"'
})

           
  • prod.env.js的配置
module.exports = {
    NODE_ENV:"production"
}
           

分别建立測試與生産的權限配置檔案

  • test.authority.js 測試環境權限
function getAuthority(userAuthority){
    const menus = [];
    switch(userAuthority){
        case 'zhangsan':
            menus = ["a","b","c","d"];    //這裡的a,b,c,d相當與路由配置當中頁面的name
            break;
            case 'lishi':
                menus = ["a","b","c"];    
                break;
            case 'wangwu':
                menus = ["b","c","d"];    
                break;
            default:
                menus = ["a","b"];
            
    }
    return menus;
}
export default getAuthority;
           
  • prod.authority.js 生産環境的配置方法頁和上面一樣,隻不過是menus裡的配置不同

使用cross-env配置對應的NODE_ENV

  • package.json
"scripts":{
    "build:testing": "cross-env NODE_ENV='testing' node build/build.js",
    "build": "cross-env NODE_ENV='production' node build/build.js"
}
           

npm run build:testing執行的是測試環境的打包,npm run build則是生産環境的打包。

将目前環境的配置添加到用戶端全局

  • build/webpack.prod.conf.js
const env = process.env.NODE_ENV === 'testing' ? require("../config/test.env.js") : require("../config/prod.env.js");

//配置webpack.DefinePlugin将env添加到全局變量當中
plugins:[
new webpack.DefinePlugin({
    "ENV":env
})
]

           

根據環境資訊配置使用者權限

要對使用者權限進行控制是要先知道目前登入的是哪個使用者,是以使用者權限配置的操作是在登入頁面完成的。

  • login.vue
//擷取環境資訊,然後根據環境資訊讀取對應的權限配置檔案
const env = ENV.NODE_ENV === "testing" ? "test" : "prod";

import getAuthority from `${env}.authority.js`;

export default {
    methods:{
        login(){
            axios({...}).then(res => {    //調用登入接口擷取目前使用者資訊
                let userAuthority = getAuthority(res.userName);    //擷取目前登入使用者的頁面權限
                sessionStorage.setItem("authorityPages",JSON.stringify(userAuthority))    //将使用者的頁面權限儲存起來,在生成側邊欄的時候通過v-if指令判斷是否渲染
            })
        }
    }
}

           

來到這裡,就能夠解決本文一開始所提的問題了,下面總結一下。

總結

  1. 根據不同的環境編寫對應的打包環境資訊配置檔案;
  2. 根據不同環境編寫對應使用者權限配置檔案;
  3. 根據不同環境編寫對應的npm打包指令,使用cross-env設定對應的運作時環境;
  4. 在打包配置檔案當中根據運作時環境擷取對應的環境配置資訊,然後使用webpack.DefinePulgin添加到用戶端全局變量當中;
  5. 登入頁根據全局變量中的環境資訊擷取對應的使用者權限配置檔案;
  6. 使用者登入之後根據擷取的使用者權限檔案中的方法擷取登入使用者的權限,并把目前登入使用者的權限儲存起來以便之後使用。

原文位址:

https://segmentfault.com/a/1190000016962001

繼續閱讀