Webpack構(gòu)建優(yōu)化——區(qū)分環(huán)境

為什么需要區(qū)分環(huán)境

在開發(fā)網(wǎng)頁的時候,一般都會有多套運行環(huán)境苫耸,例如:

  1. 在開發(fā)過程中方便開發(fā)調(diào)試的環(huán)境敢会。
  2. 發(fā)布到線上給用戶使用的運行環(huán)境。

這兩套不同的環(huán)境雖然都是由同一套源代碼編譯而來忠寻,但是代碼內(nèi)容卻不一樣,差異包括:

  • 線上代碼被特殊壓縮過存和。
  • 開發(fā)用的代碼包含一些用于提示開發(fā)者的提示日志奕剃,這些日志普通用戶不可能去看它。
  • 開發(fā)用的代碼所連接的后端數(shù)據(jù)接口地址也可能和線上環(huán)境不同捐腿,因為要避免開發(fā)過程中造成對線上數(shù)據(jù)的影響纵朋。

為了盡可能的復(fù)用代碼,在構(gòu)建的過程中需要根據(jù)目標(biāo)代碼要運行的環(huán)境而輸出不同的代碼茄袖,我們需要一套機制在源碼中去區(qū)分環(huán)境倡蝙。 幸運的是Webpack已經(jīng)為我們實現(xiàn)了這點。

如何區(qū)分環(huán)境

具體區(qū)分方法很簡單绞佩,在源碼中通過如下方式:

if (process.env.NODE_ENV === 'production') {
  console.log('你正在線上環(huán)境');
} else {
  console.log('你正在使用開發(fā)環(huán)境');
}

其大概原理是借助于環(huán)境變量的值去判斷執(zhí)行哪個分支。
當(dāng)你的代碼中出現(xiàn)了使用process模塊的語句時猪钮,Webpack就自動打包進process模塊的代碼以支持非Node.js的運行環(huán)境品山。 當(dāng)你的代碼中沒有使用process時就不會打包進process模塊的代碼。這個注入的process模塊作用是為了模擬Node.js中的process烤低,以支持上面使用的process.env.NODE_ENV === 'production'語句肘交。
在構(gòu)建線上環(huán)境代碼時,需要給當(dāng)前運行環(huán)境設(shè)置環(huán)境變量NODE_ENV = 'production'扑馁,Webpack相關(guān)配置如下:

const DefinePlugin = require('webpack/lib/DefinePlugin');
module.exports = {
  plugins: [
    new DefinePlugin({
      // 定義 NODE_ENV 環(huán)境變量為 production
      'process.env': {
        NODE_ENV: JSON.stringify('production')
      }
    }),
  ],
};

注意在定義環(huán)境變量的值時用JSON.stringify包裹字符串的原因是環(huán)境變量的值需要是一個由雙引號包裹的字符串涯呻,而JSON.stringify('production')的值正好等于'"production"'
執(zhí)行構(gòu)建后腻要,你會在輸出的文件中發(fā)現(xiàn)如下代碼:

if (true) {
  console.log('你正在使用線上環(huán)境');
} else {
  console.log('你正在使用開發(fā)環(huán)境');
}

定義的環(huán)境變量的值被代入到了源碼中复罐,process.env.NODE_ENV === 'production'被直接替換成了true。并且由于此時訪問process的語句被替換了而沒有了雄家,Webpack也不會打包進process模塊了效诅。
DefinePlugin定義的環(huán)境變量只對Webpack需要處理的代碼有效,而不會影響Node.js運行時的環(huán)境變量的值。
通過Shell腳本的方式去定義的環(huán)境變量乱投,例如NODE_ENV=production webpack咽笼,Webpack是不認識的,對Webpack需要處理的代碼中的環(huán)境區(qū)分語句是沒有作用的戚炫。
也就是說只需要通過DefinePlugin定義環(huán)境變量就能使上面介紹的環(huán)境區(qū)分語句正常工作剑刑,沒必要又通過Shell腳本的方式去定義一遍。
如果想讓W(xué)ebpack使用通過Shell腳本的方式去定義的環(huán)境變量双肤,可以使用EnvironmentPlugin施掏,代碼如下:

new webpack.EnvironmentPlugin(['NODE_ENV'])

以上這句代碼實際上等價于:

new webpack.DefinePlugin({
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
})

結(jié)合UglifyJS

其實以上輸出的代碼還可以進一步優(yōu)化,因為if(true)語句永遠只會執(zhí)行前一個分支中的代碼杨伙,也就是說最佳的輸出其實應(yīng)該直接是:

console.log('你正在線上環(huán)境');

Webpack沒有實現(xiàn)去除死代碼功能其监,但是UglifyJS可以做這個事情。

第三方庫中的環(huán)境區(qū)分

除了在自己寫的源碼中可以有環(huán)境區(qū)分的代碼外限匣,很多第三方庫也做了環(huán)境區(qū)分的優(yōu)化抖苦。 以React為例,它做了兩套環(huán)境區(qū)分米死,分別是:

  1. 開發(fā)環(huán)境:包含類型檢查锌历、HTML元素檢查等等針對開發(fā)者的警告日志代碼。
  2. 線上環(huán)境:去掉了所有針對開發(fā)者的代碼峦筒,只保留讓React能正常運行的部分究西,以優(yōu)化大小和性能。

例如React源碼中有大量類似下面這樣的代碼:

if (process.env.NODE_ENV !== 'production') {
  warning(false, '%s(...): Can only update a mounted or mounting component.... ')
}

如果你不定義NODE_ENV=production那么這些警告日志就會被包含到輸出的代碼中物喷,輸出的文件將會非常大卤材。
process.env.NODE_ENV !== 'production'中的NODE_ENV'production'兩個值是社區(qū)的約定,通常使用這條判斷語句區(qū)分開發(fā)環(huán)境和線上環(huán)境峦失。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扇丛,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子尉辑,更是在濱河造成了極大的恐慌帆精,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隧魄,死亡現(xiàn)場離奇詭異卓练,居然都是意外死亡,警方通過查閱死者的電腦和手機购啄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門襟企,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人狮含,你說我怎么就攤上這事整吆」澳欤” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵表蝙,是天一觀的道長拴测。 經(jīng)常有香客問我,道長府蛇,這世上最難降的妖魔是什么集索? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮汇跨,結(jié)果婚禮上务荆,老公的妹妹穿的比我還像新娘。我一直安慰自己穷遂,他們只是感情好函匕,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蚪黑,像睡著了一般盅惜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上忌穿,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天抒寂,我揣著相機與錄音,去河邊找鬼掠剑。 笑死屈芜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的朴译。 我是一名探鬼主播井佑,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼眠寿!你這毒婦竟也來了毅糟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤澜公,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后喇肋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坟乾,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年蝶防,在試婚紗的時候發(fā)現(xiàn)自己被綠了甚侣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡间学,死狀恐怖殷费,靈堂內(nèi)的尸體忽然破棺而出印荔,到底是詐尸還是另有隱情,我是刑警寧澤详羡,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布仍律,位于F島的核電站,受9級特大地震影響实柠,放射性物質(zhì)發(fā)生泄漏水泉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一窒盐、第九天 我趴在偏房一處隱蔽的房頂上張望草则。 院中可真熱鬧,春花似錦蟹漓、人聲如沸炕横。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至梅桩,卻和暖如春塔鳍,著一層夾襖步出監(jiān)牢的瞬間伯铣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工轮纫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留腔寡,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓掌唾,卻偏偏與公主長得像放前,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子糯彬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

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

  • GitChat技術(shù)雜談 前言 本文較長凭语,為了節(jié)省你的閱讀時間,在文前列寫作思路如下: 什么是 webpack撩扒,它要...
    蕭玄辭閱讀 12,679評論 7 110
  • 1 Webpack 1.1 概念簡介 1.1.1 WebPack是什么 1似扔、一個打包工具 2、一個模塊加載工具 3...
    Kevin_Junbaozi閱讀 6,642評論 0 16
  • 寫在前面的話 閱讀本文之前搓谆,先看下面這個webpack的配置文件炒辉,如果每一項你都懂,那本文能帶給你的收獲也許就比較...
    不忘初心_9a16閱讀 3,232評論 0 17
  • 少年貪玩泉手,青年迷戀愛情黔寇,壯年汲汲于成名成家,暮年自安于自欺欺人斩萌。人壽幾何缝裤,頑鐵能練成精金屏轰,又能有多少? 不問前途憋飞,...
    貳貳貳爺閱讀 159評論 0 0
  • 天蒙蒙亮聽到卷簾門自動打開的聲音霎苗,接著便是叔叔和爺爺?shù)膶υ挕W蛲砣タ礌敔斶€好搀崭,見我就問怎么兩個孩子都沒來叨粘。今天估計...
    顧鳴芬閱讀 114評論 0 0