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

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

測試環境與生產環境中的用戶權限不同,所以,就須要根據測試環境打一個包,生產環境又打一個包。
但是,若是每次打包都須要更改權限的配置文件的話,會很麻煩,並且,體現不出一個coder該有的逼格。
爲了更有逼格地解決這個問題,因而我百度了一番,上天不負有心人,讓我找到了解決方案。vue

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

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

process是一個控制node.js的進程,它是一個global對象,包含進程相關的一些信息,而process.env則是包含用戶環境信息的一個對象,例以下面這樣的對象:webpack

{
  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來判斷是哪一種環境,而後再做相應的配置。ios

官方解釋web

  • 如何使用cross-envnpm

    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去轉成字符串。json

  • webpack.DefinePlugin又是什麼呢?
    webpack.DefinePluginwebpack自帶的一個插件,它的做用是在編譯的時候生成一些全局變量的,這裏說的全局變量指的是客戶端的全局變量,至關於掛載在window對象上的變量,咱們能夠利用它的這個功能在不一樣的環境(開發,測試,或者生產)當中定義不一樣的行爲。

    官方介紹與使用axios

介紹完兩個插件了,是時候說一下二者結合在實際當中如何使用了。
下面將展現如何解決本文開頭一開始所提到的根據測試和生產環境配置不一樣的用戶權限的問題。vim

在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. 用戶登陸以後根據獲取的用戶權限文件中的方法獲取登陸用戶的權限,並把當前登陸用戶的權限保存起來以便以後使用。
相關文章
相關標籤/搜索