1. 程式人生 > >在基於vue-cli的專案自定義打包環境

在基於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.DefinePluginwebpack自帶的一個外掛,它的作用是在編譯的時候生成一些全域性變數的,這裡說的全域性變數指的是客戶端的全域性變數,相當於掛載在window物件上的變數,我們可以利用它的這個功能在不同的環境(開發,測試,或者生產)當中定義不同的行為。

    官方介紹與使用

介紹完兩個外掛了,是時候說一下兩者結合在實際當中如何使用了。
下面將展示如何解決本文開頭一開始所提到的根據測試和生產環境配置不同的使用者許可權的問題。

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


如上圖所示,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