配置文件

鄙人已付費購買,粘貼出來給更多前端愛好者學(xué)習(xí)招刨。若掘金小冊禁止此類操作哀军,請聯(lián)系

在實際項目的開發(fā)中,我們一般會經(jīng)歷項目的開發(fā)階段谎倔、測試階段和最終上線階段猿推,每一個階段對于項目代碼的要求可能都不盡相同,那么我們?nèi)绾文軌蛴稳杏杏嗟脑诓煌A段下使我們的項目呈現(xiàn)不同的效果蹬叭,使用不同的功能呢?這里就需要引入環(huán)境的概念孽查。

一般一個項目都會有以下 3 種環(huán)境:

開發(fā)環(huán)境(開發(fā)階段坦喘,本地開發(fā)版本,一般會使用一些調(diào)試工具或額外的輔助功能)

測試環(huán)境(測試階段洲胖,上線前版本坯沪,除了一些 bug 的修復(fù)擒滑,基本不會和上線版本有很大差別)

生產(chǎn)環(huán)境(上線階段,正式對外發(fā)布的版本藻糖,一般會進(jìn)行優(yōu)化库车,關(guān)掉錯誤報告)

作為一名開發(fā)人員,我們可能需要針對每一種環(huán)境編寫一些不同的代碼并且保證這些代碼運行在正確的環(huán)境中洋满,那么我們應(yīng)該如何在代碼中判斷項目所處的環(huán)境同時執(zhí)行不同的代碼呢?這就需要我們進(jìn)行正確的環(huán)境配置和管理正罢。

介紹

1. 配置文件

正確的配置環(huán)境首先需要我們認(rèn)識不同環(huán)境配置之間的關(guān)系驻民,如圖所示:




我們從上圖中可以了解到每一個環(huán)境其實有其不同的配置,同時它們也存在著交集部分回还,交集便是它們都共有的配置項柠硕,那么在 Vue 中我們應(yīng)該如何處理呢?

我們可以在根目錄下創(chuàng)建以下形式的文件進(jìn)行不同環(huán)境下變量的配置:

.env# 在所有的環(huán)境中被載入

.env.local# 在所有的環(huán)境中被載入仅叫,但會被git忽略

.env.[mode]# 只在指定的模式中被載入

.env.[mode].local# 只在指定的模式中被載入诫咱,但會被git忽略

比如我們創(chuàng)建一個名為 .env.stage 的文件,該文件表明其只在 stage 環(huán)境下被加載坎缭,在這個文件中掏呼,我們可以配置如下鍵值對的變量:

NODE_ENV=stage

VUE_APP_TITLE=stage mode

這時候我們怎么在 vue.config.js 中訪問這些變量呢?很簡單憎夷,使用process.env.[name]進(jìn)行訪問就可以了,比如:

// vue.config.js

console.log(process.env.NODE_ENV);// development(在終端輸出)

當(dāng)你運行yarn serve命令后會發(fā)現(xiàn)輸出的是 development祥得,因為vue-cli-service serve命令默認(rèn)設(shè)置的環(huán)境是 development蒋得,你需要修改 package.json 中的 serve 腳本的命令為:

"scripts": {

"serve":"vue-cli-service serve --mode stage",

}

--mode stage其實就是修改了 webpack 4 中的 mode 配置項為 stage,同時其會讀取對應(yīng) .env.[model] 文件下的配置饮焦,如果沒找到對應(yīng)配置文件,其會使用默認(rèn)環(huán)境 development械哟,同樣vue-cli-service build會使用默認(rèn)環(huán)境 production殿雪。

這時候如果你再創(chuàng)建一個 .env 的文件,再次配置重復(fù)的變量爸业,但是值不同亏镰,如:

NODE_ENV=staging

VUE_APP_TITLE=staging mode

VUE_APP_NAME=project

因為 .env 文件會被所有環(huán)境加載,即公共配置索抓,那么最終我們運行vue-cli-service serve打印出來的是哪個呢逼肯?答案是stage,但是如果是 .env.stage.local 文件中配置成上方這樣篮幢,答案便是staging三椿,所以 .env.[mode].local 會覆蓋 .env.[mode] 下的相同配置。同理 .env.local 會覆蓋 .env 下的相同配置搜锰。

由此可以得出結(jié)論,相同配置項的權(quán)重:

.env.[mode].local>.env.[mode]>.env.local>.env

但是需要注意的是焊傅,除了相同配置項權(quán)重大的覆蓋小的鸦列,不同配置項它們會進(jìn)行合并操作,類似于 Javascript 中的 Object.assign 的用法。

2. 環(huán)境注入

通過上述配置文件的創(chuàng)建骆姐,我們成功使用命令行的形式對項目環(huán)境進(jìn)行了設(shè)置并可以自由切換,但是需要注意的是我們在 Vue 的前端代碼中打印出的process.env與 vue.config.js 中輸出的可能是不一樣的玻褪,這需要普及一個知識點:webpack 通過 DefinePlugin 內(nèi)置插件將 process.env 注入到客戶端代碼中带射。

// webpack 配置

{

? ? ...


? ? plugins: [

newwebpack.DefinePlugin({

'process.env': {

NODE_ENV:JSON.stringify(process.env.NODE_ENV)

? ? ? ? ? ? }

? ? ? ? }),

? ? ],


? ? ...

}

由于 vue-cli 3.x 封裝的 webpack 配置中已經(jīng)幫我們完成了這個功能,所以我們可以直接在客戶端代碼中打印出 process.env 的值窟社,該對象可以包含多個鍵值對灿里,也就是說可以注入多個值,但是經(jīng)過 CLI 封裝后僅支持注入環(huán)境配置文件中以VUE_APP_開頭的變量匣吊,而NODE_ENV和BASE_URL這兩個特殊變量除外色鸳。比如我們在權(quán)重最高的 .env.stage.local 文件中寫入:

NODE_ENV=stage2

VUE_APP_TITLE=stage mode2

NAME=vue

然后我們嘗試在 vue.config.js 中打印process.env,終端輸出:

{

? ? ...


npm_config_ignore_scripts:'',

npm_config_version_git_sign:'',

npm_config_ignore_optional:'',

npm_config_init_version:'1.0.0',

npm_package_dependencies_vue_router:'^3.0.1',

npm_config_version_tag_prefix:'v',

npm_node_execpath:'/usr/local/bin/node',

NODE_ENV:'stage2',

VUE_APP_TITLE:'stage mode2',

NAME:'vue',

BABEL_ENV:'development',


? ? ...

}

可以看到輸出內(nèi)容除了我們環(huán)境配置中的變量外還包含了很多 npm 的信息褥影,但是我們在入口文件 main.js 中打印會發(fā)現(xiàn)輸出:

{

"BASE_URL":"/vue/",

"NODE_ENV":"stage2",

"VUE_APP_TITLE":"stage mode2"

}

可見注入時過濾調(diào)了非VUE_APP_開頭的變量咏雌,其中多出的BASE_URL為你在 vue.config.js 設(shè)置的值,默認(rèn)為 /统倒,其在環(huán)境配置文件中設(shè)置無效氛雪。




3. 額外配置

以上我們通過新建配置文件的方式為項目不同環(huán)境配置不同的變量值,能夠?qū)崿F(xiàn)項目基本的環(huán)境管理浴鸿,但是 .env 這樣的配置文件中的參數(shù)目前只支持靜態(tài)值弦追,無法使用動態(tài)參數(shù),在某些情況下無法實現(xiàn)特定需求掸哑,這時候我們可以在根目錄下新建 config 文件夾用于存放一些額外的配置文件。

/* 配置文件 index.js */

// 公共變量

constcom = {

IP:JSON.stringify('xxx')

};

module.exports = {

// 開發(fā)環(huán)境變量

? ? dev: {

env: {

TYPE:JSON.stringify('dev'),

? ? ? ? ? ? ...com

? ? }

? ? },


// 生產(chǎn)環(huán)境變量

? ? build: {

env: {

TYPE:JSON.stringify('prod'),

? ? ? ? ? ? ...com

? ? }

? ? }

}

上方代碼我們把環(huán)境變量分為了公共變量厌蔽、開發(fā)環(huán)境變量和生產(chǎn)環(huán)境變量摔癣,當(dāng)然這些變量可能是動態(tài)的,比如用戶的 ip 等≡褡牵現(xiàn)在我們要在 vue.config.js 里注入這些變量近她,我們可以使用 chainWebpack 修改 DefinePlugin 中的值:

/* vue.config.js */

constconfigs =require('./config');

// 用于做相應(yīng)的 merge 處理

constmerge =require('webpack-merge');

// 根據(jù)環(huán)境判斷使用哪份配置

constcfg = process.env.NODE_ENV ==='production'? configs.build.env : configs.dev.env;

module.exports = {

? ? ...


chainWebpack:config=>{

config.plugin('define')

.tap(args=>{

letname ='process.env';


// 使用 merge 保證原始值不變

args[0][name] = merge(args[0][name], cfg);


returnargs

? ? ? ? ? ? })

? ? },

? ? ...

}

最后我們可以在客戶端成功打印出包含動態(tài)配置的對象:

{

"NODE_ENV":"stage2",

"VUE_APP_TITLE":"stage mode2",

"BASE_URL":"/vue/",

"TYPE":"dev",

"IP":"xxx"

}

4. 實際場景

結(jié)合以上環(huán)境變量的配置,我們項目中一般會遇到一些實際場景: 比如在非線上環(huán)境我們可以給自己的移動端項目開啟vConsole調(diào)試薇缅,但是在線上環(huán)境肯定不需要開啟這一功能攒磨,我們可以在入口文件中進(jìn)行設(shè)置,代碼如下:

/* main.js */

importVuefrom'vue'

importAppfrom'./App.vue'

importrouterfrom'./router'

importstorefrom'./store'

Vue.config.productionTip =false

// 如果是非線上環(huán)境灸撰,加載 VConsole

if(process.env.NODE_ENV !=='production') {

varVConsole =require('vconsole/dist/vconsole.min.js');

varvConsole =newVConsole();

}

newVue({

? router,

? store,

render:h=>h(App)

}).$mount('#app')

vConsole 是一款用于移動網(wǎng)頁的輕量級拼坎,可擴(kuò)展的前端開發(fā)工具,可以看作是移動端瀏覽器的控制臺债蓝,如圖:




另外我們還可以使用配置中的 BASE_URL 來設(shè)置路由的 base 參數(shù):

/* router.js */

importVuefrom'vue'

importRouterfrom'vue-router'

importHomefrom'./views/Home.vue'

importAboutfrom'./views/About.vue'

Vue.use(Router)

letbase =`${process.env.BASE_URL}`;// 獲取二級目錄

exportdefaultnewRouter({

mode:'history',

base: base,// 設(shè)置 base 值

? ? routes: [

? ? ? ? {

path:'/',

name:'home',

component: Home

? ? ? ? },

? ? ? ? {

path:'/about',

name:'about',

component: About

? ? ? ? }

? ? ]

})

每一個環(huán)境變量你都可以用于項目的一些地方饰迹,它提供給了我們一種全局的可訪問形式余舶,也是基于 Node 開發(fā)的特性所在。

結(jié)語

環(huán)境的配置和管理對于項目的構(gòu)建起到了至關(guān)重要的作用匿值,通過給項目配置不同的環(huán)境不僅可以增加開發(fā)的靈活性千扔、提高程序的拓展性库正,同時也有助于幫助我們?nèi)チ私獠⒎治鲰椖吭诓煌h(huán)境下的運行機(jī)制厘唾,建立全局觀念龙誊。

思考 & 作業(yè)

webpack 通過 DefinePlugin 內(nèi)置插件將 process.env 注入到客戶端代碼中時,process.env.NODE_ENV為什么要進(jìn)行 JSON.stringify 處理鹤树?

process.env中如何獲取 package.json 中 name 的值逊朽?

如何在 package.json 中的 scripts 字段中定義一些自定義腳本來切換不同的環(huán)境?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末追他,一起剝皮案震驚了整個濱河市岛蚤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌单雾,老刑警劉巖她紫,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贿讹,死亡現(xiàn)場離奇詭異,居然都是意外死亡围详,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雹食,“玉大人,你說我怎么就攤上這事吃挑。” “怎么了舶衬?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵逛犹,是天一觀的道長。 經(jīng)常有香客問我舞蔽,道長码撰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任朵栖,我火速辦了婚禮鸡岗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘轩性。我一直安慰自己揣苏,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布脯厨。 她就那樣靜靜地躺著坑质,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稼跳。 梳的紋絲不亂的頭發(fā)上吃沪,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機(jī)與錄音红淡,去河邊找鬼。 笑死在旱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的遂黍。 我是一名探鬼主播俊嗽,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼绍豁,長吁一口氣:“原來是場噩夢啊……” “哼牙捉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起邪铲,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤带到,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后被饿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搪搏,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了囱嫩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡澡谭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出潘酗,到底是詐尸還是另有隱情雁仲,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布缸兔,位于F島的核電站吹艇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抛猖。R本人自食惡果不足惜鼻听,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撑教。 院中可真熱鬧醉拓,春花似錦、人聲如沸廉嚼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矫夷。三九已至憋槐,卻和暖如春双藕,著一層夾襖步出監(jiān)牢的瞬間阳仔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工嘶摊, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阱飘。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓虱颗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親高帖。 傳聞我的和親對象是個殘疾皇子辨萍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359