徹底解決 webpack 打包文件體積過大

webpack 把我們所有的文件都打包成一個(gè) JS 文件,這樣即使你是小項(xiàng)目茫叭,打包后的文件也會(huì)非常大酬屉。下面就來講下如何從多個(gè)方面進(jìn)行優(yōu)化。

去除不必要的插件

剛開始用 webpack 的時(shí)候揍愁,開發(fā)環(huán)境和生產(chǎn)環(huán)境用的是同一個(gè) webpack 配置文件呐萨,導(dǎo)致生產(chǎn)環(huán)境打包的 JS 文件包含了一大堆沒必要的插件,比如 HotModuleReplacementPlugin, NoErrorsPlugin... 這時(shí)候不管用什么優(yōu)化方式莽囤,都沒多大效果浩聋。所以储矩,如果你打包后的文件非常大的話,先檢查下是不是包含了這些插件。

提取第三方庫

像 react 這個(gè)庫的核心代碼就有 627 KB衫冻,這樣和我們的源代碼放在一起打包卖宠,體積肯定會(huì)很大孩灯。所以可以在 webpack 中設(shè)置

{
  entry: {
   bundle: 'app'
    vendor: ['react']
  }

  plugins: {
    new webpack.optimize.CommonsChunkPlugin('vendor',  'vendor.js')
  }
}

這樣打包之后就會(huì)多出一個(gè) vendor.js 文件潦俺,之后在引入我們自己的代碼之前,都要先引入這個(gè)文件狼牺。比如在 index.html

 <script src="/build/vendor.js"></script>
 <script src="/build/bundle.js"></script>

除了這種方式之外羡儿,還可以通過引用外部文件的方式引入第三方庫,比如像下面的配置

{
  externals: {
     'react': 'React'
  }
}

externals 對(duì)象的 key 是給 require 時(shí)用的是钥,比如 require('react')掠归,對(duì)象的 value 表示的是如何在 global 中訪問到該對(duì)象,這里是 window.React悄泥。這時(shí)候 index.html 就變成下面這樣

<script src="http://cdn.bootcss.com/react/0.14.7/react.min.js"></script>
<script src="/build/bundle.js"></script>

當(dāng)然虏冻,個(gè)人更推薦第一種方式

目前推薦用 DLL 的方式提取第三方庫弹囚。

代碼壓縮

webpack 自帶了一個(gè)壓縮插件 UglifyJsPlugin厨相,只需要在配置文件中引入即可。

{
  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
}

加入了這個(gè)插件之后鸥鹉,編譯的速度會(huì)明顯變慢蛮穿,所以一般只在生產(chǎn)環(huán)境啟用。

另外毁渗,服務(wù)器端還可以開啟 gzip 壓縮践磅,優(yōu)化的效果更明顯。

代碼分割

什么是代碼分割呢灸异?我們知道府适,一般加載一個(gè)網(wǎng)頁都會(huì)把全部的 js 代碼都加載下來幻碱。但是對(duì)于 web app 來說,我們更想要的是只加載當(dāng)前 UI 的代碼细溅,沒有點(diǎn)擊的部分不加載。

看起來好像挺麻煩儡嘶,但是通過 webpack 的 code split 以及配合 react router 就可以方便實(shí)現(xiàn)喇聊。具體的例子可以看下 react router 的官方示例 huge apps。不過這里還是講下之前配置踩過的坑蹦狂。

code split不支持 ES6 的模塊系統(tǒng)的誓篱,所以在導(dǎo)入和導(dǎo)出的時(shí)候千萬要注意,特別是導(dǎo)出凯楔。如果你導(dǎo)出組件的時(shí)候用 ES6 的方式窜骄,這時(shí)候不管導(dǎo)入是用 CommomJs 還是 AMD,都會(huì)失敗摆屯,而且還不會(huì)報(bào)錯(cuò)邻遏!

當(dāng)然會(huì)踩到這個(gè)坑也是因?yàn)槲覄倓偛庞?NodeJS,而且一入門就是用 ES6 的風(fēng)格虐骑。除了這個(gè)之外准验,還有一點(diǎn)也要注意,在生產(chǎn)環(huán)境的 webpack 配置文件中廷没,要加上 publicPath

output: {
    path: xxx,
    publicPath: yyy,
    filename: 'bundle.js'
}

不然的話糊饱,webpack 在加載 chunk 的時(shí)候,路徑會(huì)出錯(cuò)颠黎。

設(shè)置緩存

開始這個(gè)小節(jié)之前另锋,可以先看下大神的一篇文章:大公司里怎樣開發(fā)和部署前端代碼

對(duì)于靜態(tài)文件狭归,第一次獲取之后夭坪,文件內(nèi)容沒改變的話,瀏覽器直接讀取緩存文件即可过椎。那如果緩存設(shè)置過長台舱,文件要更新怎么辦呢?嗯潭流,以文件內(nèi)容的 MD5 作為文件名就是一個(gè)不錯(cuò)的解決方案竞惋。來看下用 webpack 應(yīng)該怎樣實(shí)現(xiàn)

output: {
    path: xxx,
    publicPath: yyy,
    filename: '[name]-[chunkhash:6].js'
}

打包后的文件名加入了 hash 值

const bundler = webpack(config)

bundler.run((err, stats) => {
  let assets = stats.toJson().assets
  let name

  for (let i = 0; i < assets.length; i++) {
    if (assets[i].name.startsWith('main')) {
      name = assets[i].name
      break
    }
  }

  fs.stat(config.buildTemplatePath, (err, stats) => {
    if (err) {
      fs.mkdirSync(config.buildTemplatePath)
    }

    writeTemplate(name)
  })
})

手動(dòng)調(diào)用 webpack 的 API,獲取打包后的文件名灰嫉,通過 writeTemplate 更新 html 代碼拆宛。完整代碼猛戳 gitst

這樣子讼撒,我們就可以把文件的緩存設(shè)置得很長浑厚,而不用擔(dān)心更新問題股耽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市钳幅,隨后出現(xiàn)的幾起案子物蝙,更是在濱河造成了極大的恐慌,老刑警劉巖敢艰,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诬乞,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡钠导,警方通過查閱死者的電腦和手機(jī)震嫉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牡属,“玉大人票堵,你說我怎么就攤上這事〈ぃ” “怎么了悴势?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長措伐。 經(jīng)常有香客問我瞳浦,道長,這世上最難降的妖魔是什么废士? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任叫潦,我火速辦了婚禮,結(jié)果婚禮上官硝,老公的妹妹穿的比我還像新娘矗蕊。我一直安慰自己,他們只是感情好氢架,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布傻咖。 她就那樣靜靜地躺著,像睡著了一般岖研。 火紅的嫁衣襯著肌膚如雪卿操。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天孙援,我揣著相機(jī)與錄音害淤,去河邊找鬼。 笑死拓售,一個(gè)胖子當(dāng)著我的面吹牛窥摄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播础淤,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼崭放,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼哨苛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起币砂,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤建峭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后决摧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亿蒸,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蜜徽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片票摇。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拘鞋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出矢门,到底是詐尸還是另有隱情盆色,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布祟剔,位于F島的核電站隔躲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏物延。R本人自食惡果不足惜宣旱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望叛薯。 院中可真熱鬧浑吟,春花似錦、人聲如沸耗溜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抖拴。三九已至燎字,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阿宅,已是汗流浹背候衍。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洒放,地道東北人脱柱。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像拉馋,于是被迫代替她去往敵國和親榨为。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惨好,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • webpack 把我們所有的文件都打包成一個(gè)JS文件,這樣即使你是一個(gè)小項(xiàng)目随闺,打包后的文件也會(huì)非常大日川。下面就來講下...
    Simon王小白閱讀 2,518評(píng)論 0 4
  • 無意中看到zhangwnag大佬分享的webpack教程感覺受益匪淺,特此分享以備自己日后查看矩乐,也希望更多的人看到...
    小小字符閱讀 8,140評(píng)論 7 35
  • 最近在學(xué)習(xí) Webpack,網(wǎng)上大多數(shù)入門教程都是基于 Webpack 1.x 版本的,我學(xué)習(xí) Webpack 的...
    My_Oh_My閱讀 8,166評(píng)論 40 247
  • 寫在開頭 先說說為什么要寫這篇文章, 最初的原因是組里的小朋友們看了webpack文檔后, 表情都是這樣的: (摘...
    Lefter閱讀 5,273評(píng)論 4 31
  • 你說事情的輪廓清晰明了的出現(xiàn)在你腦海龄句,但你的行動(dòng)卻偏離的軌跡。 你無奈拿出一根讓你有些許惡心的香煙開始吞云吐霧散罕。 ...
    夜之公英閱讀 219評(píng)論 0 1