webpack獨(dú)立打包與緩存處理

前言

先前寫了一篇webpack入門的文章《webpack入門必知必會(huì)》俄认,簡單介紹了webpack拆分、打包、壓縮的使用方法典尾。本文將在上篇文章的基礎(chǔ)上進(jìn)一步講解在使用webpack構(gòu)建的項(xiàng)目中存在的優(yōu)化方案與解決方法。

上篇文章中寫了一份webpack最基本的配置文件來打包壓縮我們的代碼:

var path = require('path');

module.exports = {
  entry: './app/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}

在入口文件index.js中我們引入了jQuery:

// index.js
var $ = require('jquery');
var str = require('./hello.js');

function main() {
    $('body').html(str);
}

main();

這樣我們雖然能夠?qū)崿F(xiàn)代碼的統(tǒng)一打包河闰,將jQuery褥紫、index.js、hello.js統(tǒng)統(tǒng)打包到了bundle.js里髓考,但是會(huì)存在一個(gè)問題:每次打包都會(huì)生成一個(gè)體積較大的新bundle.js,瀏覽器無法緩存像jQuery這樣的基本不會(huì)改動(dòng)的框架庫代碼文件儡炼,影響加載速度查蓉。

發(fā)現(xiàn)問題我們就來解決問題,我們最終希望的是將像jQuery這樣的框架庫代碼與項(xiàng)目自身的代碼分開打包豌研,生成一個(gè)獨(dú)立的打包文件,縮減單個(gè)文件體積鬼佣,瀏覽器也不用每次都進(jìn)行加載霜浴。

步驟

1.獨(dú)立打包

為了解決上述問題,我們需要修改我們的webpack配置文件:

var webpack = require('webpack');
var path = require('path');

module.exports = {
    entry: {
        main: './app/index.js',
        vendor: ['jquery']
    },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    },
    plugins:[
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor'
        }),
    ]
}

上方我們將原本的單入口文件改成了多入口文件坷随,并加入了vendor屬性驻龟。vendor屬性用于配置打包第三方類庫翁狐,寫入數(shù)組的類庫名將統(tǒng)一打包到一個(gè)文件里。

同時(shí)我們將輸出的filename用[name]變量來自動(dòng)生成文件名露懒,最后我們添加了一個(gè)CommonsChunkPlugin的插件砂心,用于提取vendor。

配置完成后我們運(yùn)行webpack命令:

Hash: ee1daf95c1986768927a
Version: webpack 2.3.2
Time: 573ms
        Asset       Size  Chunks                    Chunk Names
      main.js  340 bytes       0  [emitted]         main
vendor.js     274 kB       1  [emitted]  [big]  vendor
   [0] ./~/jquery/dist/jquery.js 267 kB {1} [built]
   [1] ./app/hello.js 53 bytes {0} [built]
   [2] ./app/index.js 114 bytes {0} [built]
   [3] multi jquery 28 bytes {1} [built]

最終發(fā)現(xiàn)我們成功將jQuery打包到了vendor.js中坎弯,實(shí)現(xiàn)了獨(dú)立打包译暂,但是問題又來了:每次打包后生成的文件名都是一樣的,瀏覽器可能緩存上一次的結(jié)果而無法加載最新數(shù)據(jù)崎脉。

2.添加hash

為了解決上述問題,我們需要為打包后的文件名添加hash值伯顶,這樣每次修改后打包的文件hash值將改變,修改配置文件如下:

module.exports = {
    ...
        output: {
            filename: '[name].[chunkHash:5].js',
            path: path.resolve(__dirname, 'dist')
        },
    ...
}

上方我們在輸出文件名中增加了[chunkHash:5]變量啦撮,表示打包后的文件中加入保留5位的hash值汪厨。我們再次運(yùn)行打包命令:

Hash: c7d1295f2f9a27c412d2
Version: webpack 2.3.2
Time: 603ms
          Asset       Size  Chunks                    Chunk Names
  main.2a7ad.js  337 bytes       0  [emitted]         main
vendor.49eb4.js     274 kB       1  [emitted]  [big]  vendor
   [0] ./~/jquery/dist/jquery.js 267 kB {1} [built]
   [1] ./app/hello.js 50 bytes {0} [built]
   [2] ./app/index.js 114 bytes {0} [built]
   [3] multi jquery 28 bytes {1} [built]

上方我們發(fā)現(xiàn)打包后的文件成功加上了hash值赃春,這樣每次修改文件后hash值也會(huì)跟著變劫乱,就不怕瀏覽器緩存了,但是當(dāng)我們嘗試去修改一個(gè)js文件后再次打包狭吼,問題又來了:vendor.js的hash值也變了殖妇,我們并沒有修改jQuery的源碼。

3.修改vendor配置

上述問題產(chǎn)生的原因是因?yàn)镃ommonsChunkPlugin插件是用于提取公共代碼的,上方我們只是提取了vendor作為公共代碼疲吸。為了繼續(xù)解決上述問題摘悴,其實(shí)方法很簡單,我們需要修改CommonsChunkPlugin的配置蹂喻,如下:

module.exports = {
    ...
        plugins:[
            new webpack.optimize.CommonsChunkPlugin({
                names: ['vendor', 'manifest']
            }),
        ]
    ...
}

如此我們修改一下hello.js中的代碼葱椭,發(fā)現(xiàn)vendor的hash值并未改變口四,并且多了一個(gè)manifest.js的小文件蔓彩。manifest.js為webpack的啟動(dòng)文件代碼,它會(huì)直接影響到hash值粪小,用mainfest單獨(dú)抽出來了抡句,這樣vendor的hash就不會(huì)變了。

4.生成index.html

通過以上對(duì)webpack配置文件的一系列修改待榔,我們成功實(shí)現(xiàn)了webpack的獨(dú)立打包與緩存處理锐锣,但是還差最后一步。

因?yàn)槲覀冏罱K打包后生成的文件名中帶有hash值姿骏,每次都是會(huì)變的斤彼,所以我們不能像目前這樣在index.html中寫死路徑。

index.html

...
<body>
    <script src="./dist/main.js"></script>
    <script src="./dist/vendor.js"></script>
    <script src="./dist/manifest.js"></script>
</body>
...

以上寫法是不對(duì)的嘲玫,因?yàn)槿鄙倭丝勺兊膆ash值并扇,因此我們希望每次打包后index.html中的路徑也會(huì)自動(dòng)加上hash值,解決方法如下:

var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    ...
        plugins:[
            ...
            new HtmlWebpackPlugin({
                title: 'demo',
                template: 'index.html' // 模板路徑
            }),
            ...
        ]
    ...
}

上方我們引入了html-webpack-plugin這一個(gè)插件土陪,該插件可以幫助我們根據(jù)模板生成html文件旺坠。在plugins設(shè)置中,title配置了生成html中的title部分取刃,template為模板html的路徑地址璧疗。

我們需要下載html-webpack-plugin:

npm install html-webpack-plugin --save-dev

安裝和配置完畢后崩侠,運(yùn)行打包命令:webpack

Hash: 0c4b91e206579b31544d
Version: webpack 2.3.2
Time: 856ms
            Asset       Size  Chunks                    Chunk Names
  vendor.e1868.js     268 kB       0  [emitted]  [big]  vendor
    main.44412.js  337 bytes       1  [emitted]         main
manifest.ed186.js    5.81 kB       2  [emitted]         manifest
       index.html  292 bytes          [emitted]
   [0] ./~/jquery/dist/jquery.js 267 kB {0} [built]
   [1] ./app/hello.js 50 bytes {1} [built]
   [2] ./app/index.js 114 bytes {1} [built]
   [3] multi jquery 28 bytes {0} [built]

我們發(fā)現(xiàn)在dist目錄下生成了一個(gè)index.html文件漆魔,打開該文件后代碼如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>demo</title>
</head>
<body>
<script type="text/javascript" src="manifest.ed186.js"></script>
<script type="text/javascript" src="vendor.e1868.js"></script>
<script type="text/javascript" src="main.44412.js"></script>
</body>
</html>

至此我們實(shí)現(xiàn)了每次打包后index.html中的路徑也會(huì)自動(dòng)加上hash值的功能改抡,因此dist目錄下的index.html即為以后的首頁文件阿纤,最后我們在瀏覽器中打開該文件成功顯示:

結(jié)語

本文在webpack入門的基礎(chǔ)上講解了webpack獨(dú)立打包與緩存處理的方式,實(shí)例代碼已上傳我的github藐窄,地址為:https://github.com/luozhihao/webpack-course/tree/master/vendor荆忍, 供參考东揣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市芥吟,隨后出現(xiàn)的幾起案子钉稍,更是在濱河造成了極大的恐慌贡未,老刑警劉巖俊卤,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異狠怨,居然都是意外死亡邑遏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門记盒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蹂午,你說我怎么就攤上這事∠锾郏” “怎么了灵奖?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長擅编。 經(jīng)常有香客問我,道長境钟,這世上最難降的妖魔是什么慨削? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任缚态,我火速辦了婚禮宙橱,結(jié)果婚禮上环葵,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪砰诵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天善镰,我揣著相機(jī)與錄音,去河邊找鬼炫欺。 笑死乎完,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的品洛。 我是一名探鬼主播树姨,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼桥状!你這毒婦竟也來了帽揪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤辅斟,失蹤者是張志新(化名)和其女友劉穎转晰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體士飒,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡查邢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了酵幕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扰藕。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖裙盾,靈堂內(nèi)的尸體忽然破棺而出实胸,到底是詐尸還是另有隱情他嫡,我是刑警寧澤番官,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站钢属,受9級(jí)特大地震影響徘熔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜淆党,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一酷师、第九天 我趴在偏房一處隱蔽的房頂上張望讶凉。 院中可真熱鬧,春花似錦山孔、人聲如沸懂讯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽褐望。三九已至,卻和暖如春串前,著一層夾襖步出監(jiān)牢的瞬間瘫里,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國打工荡碾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留谨读,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓坛吁,卻偏偏與公主長得像劳殖,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拨脉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • 寫在開頭 先說說為什么要寫這篇文章, 最初的原因是組里的小朋友們看了webpack文檔后, 表情都是這樣的: (摘...
    Lefter閱讀 5,273評(píng)論 4 31
  • GitChat技術(shù)雜談 前言 本文較長闷尿,為了節(jié)省你的閱讀時(shí)間,在文前列寫作思路如下: 什么是 webpack女坑,它要...
    蕭玄辭閱讀 12,671評(píng)論 7 110
  • webpack 介紹 webpack 是什么 為什么引入新的打包工具 webpack 核心思想 webpack 安...
    yxsGert閱讀 6,450評(píng)論 2 71
  • 無意中看到zhangwnag大佬分享的webpack教程感覺受益匪淺填具,特此分享以備自己日后查看,也希望更多的人看到...
    小小字符閱讀 8,140評(píng)論 7 35
  • 記得2004年的時(shí)候匆骗,互聯(lián)網(wǎng)開發(fā)就是做網(wǎng)頁劳景,那時(shí)也沒有前端和后端的區(qū)分,有時(shí)一個(gè)網(wǎng)站就是一些純靜態(tài)的html碉就,通過...
    陽陽陽一堆陽閱讀 3,272評(píng)論 0 5