create-react-app 里 .env 文件的應(yīng)用

.env 文件在由 creact-react-app 生成的項目里是一個關(guān)于當(dāng)環(huán)境的配置文件(先不去管這個文件的起源),我們可以在這個文件里寫一些配置纪隙,然后通過某種手段在代碼里讀取中鼠、應(yīng)用這些配置窗怒,比如我們會有開發(fā)姨丈、staging岸蜗、生產(chǎn)等環(huán)境九昧,每個環(huán)境的配置都不盡相同绊袋,最基本地,每個環(huán)境請求的后端服務(wù)器的 url 就不相同铸鹰,自己 mock 的時候的本機地址癌别、與后端聯(lián)調(diào)時候的局域網(wǎng)的地址,staging 的域名和正式上線環(huán)境的域名蹋笼,之前的做法是一般會在 api 請求相關(guān)的目錄下有 config.js 這樣一個文件展姐,那些配置就當(dāng)成一個常量寫到這個文件里躁垛,然后導(dǎo)出供其他需要的模塊引用,那么問題就來了圾笨,每次切換環(huán)境時都需要去更改這些配置變量為對應(yīng)環(huán)境的值教馆,這是一件很繁瑣的事情,一般我是

const HOST = 'xxx.xxx.xxx'
// const HOST = 'yyy.yyy.yyy'

在用哪個環(huán)境的時候就把另一個環(huán)境的賦值語句給注釋掉擂达,然后后面如果在需要 build 的時候把多余的注釋掉的刪掉土铺,當(dāng)然,刪除注釋的工作可以由工具來做谍婉,但是開發(fā)時一堆無關(guān)代碼的注釋躺在那里看起來很惡心舒憾,然后我就想能不能不管怎么切換環(huán)境,需要放到瀏覽器上去跑的那段代碼永遠不用變穗熬,而只通過啟動時輸入不同的命令就可以應(yīng)用對應(yīng)的配置镀迂,比如 npm run start:mock 表示使用本地的 mock 環(huán)境,同時開啟本地的 mock 服務(wù)唤蔗;npm run start 表示使用默認的開發(fā)環(huán)境探遵,使用后端提供的環(huán)境,然后 npm run build 表示正式上線環(huán)境的編譯妓柜;npm run build:staging 表示 staging 環(huán)境的編譯箱季。然后我就找到了 .env 文件。

要實現(xiàn)上面說的那些棍掐,我們需要用到 dotenvdotenv-webpack 這兩個 npm 包(前提是在通過 create-react-app 創(chuàng)建的項目里藏雏,同時還要 run eject,當(dāng)然其他腳手架生成的項目肯定也可以做到這樣作煌,因為憑自己目前的功力還沒有辦法自己搗鼓出一個完成的項目骨架掘殴,所以就先把 create-react-app 研究透)。關(guān)于 .env 文件的用法粟誓,就不多說了 https://github.com/motdotla/dotenv 里有奏寨,然后我看到里面:

Should I have multiple .env files?
No. We strongly recommend against having a "main" .env file and an "environment" .env file like .env.test. Your config should vary between deploys, and you should not be sharing values between environments.

里面是不提倡用多個 .env.*.* 這樣的文件的,可是 create-react-app 里則提倡用多個這樣的文件鹰服,比如 .env.development.local病瞳、.env.development.env.local……這樣的悲酷,然后讀取這些配置的時候有個優(yōu)先級套菜,這些代碼都寫在項目根目錄下的 config/env.js 里的,然后在切換環(huán)境的時候都會執(zhí)行一遍這個文件设易,讀取對應(yīng)的配置逗柴,我暫時還沒弄懂它讀取所有 .env.*.* 文件的用意。但是我目前也沒想到如何單憑一個 .env 文件而能實現(xiàn)我想要的東西亡嫌,所以我也用的多個 .env 文件嚎于,但是我稍微改寫了env.js掘而、start.jswebpcakDevServer.js于购、webpack.config.dev.jswebpack.config.prod.js 袍睡,使得一個環(huán)境對應(yīng)特定的 .env 文件,每個環(huán)境里的通用配置的字段都一樣肋僧,然后正式代碼里只用讀取這些字段就可以了斑胜,這些字段會根據(jù)不同的環(huán)境提供不同的值。其起作用的原理 https://github.com/mrsteele/dotenv-webpack 里有寫:

The plugin can be installed with little-to-no configuration needed. Once installed, you can access the variables within your code using process.env as you would with dotenv.

就是說嫌吠,在編譯時止潘,將正式代碼里引用了 .env 文件配置的變量直接替換成對應(yīng)的值,比如 .env 里有 HOST = xxx.xxx.xxx辫诅,然后正式的 js 代碼里有 const host = process.env.HOST凭戴,然后在編譯過程中 HOST 這個變量會被替換成 xxx.xxx.xxx,所以編譯后的代碼就會是 const host = 'xxx.xxx.xxx'炕矮,相當(dāng)于對正式 js 代碼提供了一個全局變量 process.env.HOST么夫,但是這個變量只在編譯時有效。dotenv-webpack 這個插件的用法:

const Dotenv = require('dotenv-webpack');

module.exports = {
  ...
  plugins: [
    new Dotenv()
  ]
  ...
}

用了這個插件后 new webpack.definePlugin({...}) 這條語句實現(xiàn)的功能可一并由 dotenv-webpack 來實現(xiàn)了肤视,只需要在對應(yīng) .env 文件里寫上 NODE_ENV = developmentNODE_ENV = production 就可以了档痪。此外,new DotEnv() 接受一個配置對象邢滑,里面有個 path 字段腐螟,值是加載的 .env 文件的路徑,這就允許我們根據(jù)不同的條件加載不同的 .env.*.* 文件困后,這是實現(xiàn)我想要的功能的關(guān)鍵(不過這也應(yīng)該是一個插件必然會提供的)乐纸。

下面我以默認開發(fā)環(huán)境和 mock 環(huán)境為例,簡單說下大致細節(jié)操灿。這二者都算開發(fā)環(huán)境锯仪,但還是可能會在某些時候需要區(qū)分”枚剑現(xiàn)在我為 mock 環(huán)境配一個 .env.development.local 文件趾盐,然后當(dāng)我執(zhí)行 npm run start:mock 時讓 new DotEnv(option) 加載這個文件,而在 npm run start 時加載 .env.develpment 文件小腊。 npm run start 真正執(zhí)行的是 node ./scripts/start.js救鲤,然后這個 start.js 文件里有對 webpcak.config.dev.js 這個文件的引用,需要用到它導(dǎo)出的 webpack 的配置秩冈,這是一個靜態(tài)的對象本缠,所以如果我們在 webpcak.config.dev.js 里將 new DotEnv(option) 里的 option 寫死的話,那么我們對于多個 option 就需要導(dǎo)出多個 webpack 配置入问,所以可以將 webpcak.config.dev.js 的導(dǎo)出做成一個接受一個 option 的函數(shù)丹锹,函數(shù)的返回值是應(yīng)用了這個 option 而生成的配置對象稀颁。然后我們需要一個變量來決定 option 的取值,這個變量需要在 start.js 里出現(xiàn)楣黍,然后這個變量顯然不能是通過在 start.js 文件里通過 const arg = 'xxx' 來生成而只能通過外部傳入匾灶,怎么傳入呢?很自然想到在命令行里傳入租漂,然后再對應(yīng)的腳本文件里讀取 process.argv 來獲取阶女。于是:

// package.json

{
  ...
  "start:mock": "node ./scrips/start.js mock"
  ...
}

將 mock 這個字符串傳到 start.js 里,然后 start.js 通過判斷 process.argv[2] === ‘mock’ 來決定加載哪個 .env 文件哩治。加載其他 .env 的原理一致秃踩。

此外,當(dāng)我們切換到 mock 環(huán)境時候业筏,還有一件事情要做憔杨,就是開啟本地的 mock 服務(wù),當(dāng)然我們可以在輸入 npm run start:mock 之后再又去手動開啟 mock 服務(wù)蒜胖,但步也可以放到 npm run start:mock 命令去完成芍秆,通過 npm-run-all 這個 npm 模塊。
然后翠勉,通常 mock 服務(wù)是不是也會有個類似的 config.js 文件妖啥,但是這里我們既然已經(jīng)有了 env.development.lcoal 那便不必再費事去多維護一些多余的數(shù)據(jù)了。通過

const config = require('dotenv').config({
    path: dotEnvFile
  }).parsed

就可以讀取一個由 .env 里的配置轉(zhuǎn)換而成的配置對象对碌,然后這就保持正式 js 代碼里的配置值和實際 mock 服務(wù)的配置永遠一致了荆虱。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市朽们,隨后出現(xiàn)的幾起案子怀读,更是在濱河造成了極大的恐慌,老刑警劉巖骑脱,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菜枷,死亡現(xiàn)場離奇詭異,居然都是意外死亡叁丧,警方通過查閱死者的電腦和手機啤誊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拥娄,“玉大人蚊锹,你說我怎么就攤上這事≈神” “怎么了牡昆?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摊欠。 經(jīng)常有香客問我丢烘,道長柱宦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任播瞳,我火速辦了婚禮忍宋,結(jié)果婚禮上偏陪,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好鸡典,可當(dāng)我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布俩滥。 她就那樣靜靜地躺著眠副,像睡著了一般肪康。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上姜贡,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天试吁,我揣著相機與錄音,去河邊找鬼楼咳。 笑死熄捍,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的母怜。 我是一名探鬼主播余耽,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼苹熏!你這毒婦竟也來了碟贾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤轨域,失蹤者是張志新(化名)和其女友劉穎袱耽,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體干发,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡朱巨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了枉长。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冀续。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖搀暑,靈堂內(nèi)的尸體忽然破棺而出沥阳,到底是詐尸還是另有隱情跨琳,我是刑警寧澤自点,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站脉让,受9級特大地震影響桂敛,放射性物質(zhì)發(fā)生泄漏功炮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一术唬、第九天 我趴在偏房一處隱蔽的房頂上張望薪伏。 院中可真熱鬧,春花似錦粗仓、人聲如沸嫁怀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽塘淑。三九已至,卻和暖如春蚂斤,著一層夾襖步出監(jiān)牢的瞬間存捺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工曙蒸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留捌治,地道東北人。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓纽窟,卻偏偏與公主長得像肖油,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子臂港,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,047評論 2 355

推薦閱讀更多精彩內(nèi)容