基于vue多入口項(xiàng)目升級(jí)webpack4實(shí)踐

項(xiàng)目背景簡(jiǎn)介

  • 多頁面應(yīng)用川无,每個(gè)頁面獨(dú)立entry,單個(gè)頁面內(nèi)使用vue-router
  • 基于vue诅岩,使用vue-loader加載.vue文件
  • 單頁內(nèi)使用懶加載異步chunk

項(xiàng)目二期上線后痘括,相對(duì)不辣么忙,眼看著webpack4也出來快半年了并且日趨穩(wěn)定挥唠,之前雖然寫過demo測(cè)試使用抵恋,但還未在項(xiàng)目中用過,于是擇日不如撞日一鼓作氣開啟了升級(jí)【踩坑】之旅

升級(jí)之旅

首先保證 node>= 6.11.5宝磨,建議使用8以上LTS版本

相關(guān)依賴包安裝或更新

以下是我的項(xiàng)目中使用到的依賴安裝或更新情況弧关,不同項(xiàng)目使用loader盅安、插件不同,這部分得根據(jù)自身情況調(diào)整
主要依賴:
- webpack安裝最新
- webpack-cli安裝(啟動(dòng)webpack)
- webpack-dev-server更新至3以上
- vue-loader更新至15以上
- 安裝mini-css-extract-plugin
其他:
babel相關(guān)依賴世囊、html-webpack-plugin别瞭、file-loader、url-loader株憾、sass-loader等我都升級(jí)了版本蝙寨,或者也可以修改完配置后,運(yùn)行起來看看控制臺(tái)是否有相關(guān)報(bào)警再更新
輔助:
推薦安裝webpack-bundle-analyzer插件嗤瞎,可以分析構(gòu)建結(jié)果依賴關(guān)系

配置變更

接下來來到這次愉快踩坑之旅的重頭戲了墙歪!

mode

mode是webpack4新增的配置項(xiàng),也是本次更新的亮點(diǎn)之一贝奇,簡(jiǎn)單理解就是告訴webpack本次構(gòu)建模式虹菲,使其可以對(duì)構(gòu)建使用對(duì)應(yīng)的優(yōu)化策略〉敉回想之前寫工程化配置毕源,也會(huì)區(qū)分開發(fā)模式和生產(chǎn)模式的配置入口,webpack4提供了mode降低了不少配置成本陕习。

mode可被設(shè)置為development(默認(rèn))或production

module.exports = {
  mode: 'production'
};

development側(cè)重于優(yōu)化開發(fā)體驗(yàn)霎褐,production側(cè)重于優(yōu)化模塊體積和線上部署,具體優(yōu)化內(nèi)容這里就不搬運(yùn)官方文檔了该镣,對(duì)于我的項(xiàng)目而言比較在意的有以下幾點(diǎn):

  • 將自動(dòng)設(shè)置process.env.NODE_ENV為對(duì)應(yīng)值(developmentproduction)冻璃,原手工配置process.env.NODE_ENV = 'development' ;的代碼可以刪除
  • production模式將自動(dòng)加入代碼壓縮功能,可刪除原new UglifyJsPlugin()相關(guān)代碼

更多說明參考 https://medium.com/webpack/webpack-4-mode-and-optimization-5423a6bc597a

optimization

webpack4根據(jù)mode配置對(duì)構(gòu)建進(jìn)行優(yōu)化拌牲,也可以通過覆蓋optimization配置進(jìn)一步定制兩種構(gòu)建模式下的優(yōu)化策略俱饿,并且官方移除了CommonsChunkPlugin插件。

其中項(xiàng)目升級(jí)最大的變更就在CommonsChunkPlugin插件的移除和optimizationsplitChunks塌忽、runtimeChunk的配置
另外由于代碼壓縮功能將在production模式下自動(dòng)開啟拍埠,如果需要對(duì)js壓縮或css壓縮策略定制,則需要覆蓋默認(rèn)optimization.minimizer配置

splitChunks

關(guān)于splitChunks可以單獨(dú)用一篇文章進(jìn)行詳細(xì)說明土居,這里我只是按原項(xiàng)目的緩存策略修改(CommonsChunkPlugin配置): 抽取/node_modules/下第三方依賴作為公共vendor(基于第三方依賴更新頻率低)

默認(rèn)配置下枣购,splitChunks只對(duì)懶加載的模塊產(chǎn)生影響
注釋部分是splitChunks的默認(rèn)配置,這里僅修改cacheGroups內(nèi)vendor相關(guān)配置擦耀,將chunks改成'initial'避免將部分異步加載的較大的第三方依賴也合并到vendor中

splitChunks: {
      //chunks: 'async',
      //minSize: 30000,
      //minChunks: 1,
      //maxAsyncRequests: 5,
      //maxInitialRequests: 3,
      //automaticNameDelimiter: '~',
      //name: true, 
      cacheGroups: {
        vendor: {
        name: 'vendor',
        //@NOTE 配置成all 會(huì)把a(bǔ)sync的也打進(jìn)來
        chunks: 'initial', 
        priority: -10,
        test: /[\\/]node_modules[\\/]/
        }
    }
}
runtimeChunk

之前的production模式構(gòu)建會(huì)使用CommonChunkPlugin抽取runtime code(這部分概念不了解的可以參考https://webpack.js.org/concepts/manifest/#src/components/Sidebar/Sidebar.jsx)作為單獨(dú)的chunk棉圈,升級(jí)后這部分配置需要寫到optimization.runtimeChunk中:

  • 默認(rèn)設(shè)置為false,runtime code包含在基于各個(gè)entry抽取的第一個(gè)chunk中(注意:由于本項(xiàng)目抽取了公用vendor眷蜓,針對(duì)本項(xiàng)目會(huì)將所有entry的runtime代碼抽取到公用vendor中分瘾,vendor將失去瀏覽器緩存意義)
  • 配置為single string,所有entry的runtime代碼將會(huì)抽取為一個(gè)chunk
  • 配置為一個(gè)生成函數(shù)吁系,可以基于每個(gè)entry獨(dú)立抽取runtime代碼(本項(xiàng)目使用德召,多個(gè)獨(dú)立頁面多入口)

配置成生成函數(shù)的代碼:

runtimeChunk: {
    name: entrypoint => `manifest~${entrypoint.name}`
},
minimizer

這個(gè)接收單個(gè)對(duì)象或?qū)ο髷?shù)組白魂,指定壓縮插件和配置,相對(duì)比較簡(jiǎn)單上岗,這里就不詳細(xì)描述了

minimizer: [
    // 配置UglifyJsPlugin壓縮js文件
    new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true 
    }),
    // 配置css文件壓縮
    new OptimizeCSSAssetsPlugin({
        cssProcessor: require('cssnano'),
        cssProcessorOptions: {
        discardComments: {removeAll: true},
        // 避免 cssnano 重新計(jì)算 z-index
            safe: true
        },
        canPrint: false
     })
]

mini-css-extract-plugin

webpack4之后福荸,Extract-text-plugin不再適用于css文件抽取,如果還要繼續(xù)使用安裝時(shí)只能通過@next版本安裝(yarn add extract-text-plugin@next)肴掷,除此之外contenthash不支持使用在文件名中敬锐、會(huì)生成一些多余的chunk css文件

mini-css-extract-plugin專用于抽取css文件支持async-loading,只能配合webpack4使用呆瞻,但目前暫時(shí)還不支持HMR(Hot Module Replace)台夺,本項(xiàng)目只在production下使用這個(gè)插件

配置相對(duì)Extract-text-plugin是簡(jiǎn)單一些

// loader部分(項(xiàng)目使用scss)
test: /\.(sa|sc|c)ss$/,
    use: [
      isProd ? MiniCssExtractPlugin.loader : 'style-loader',
      'css-loader',
      {
        loader: 'sass-loader',
        options: {
                    ... ...
        }
    },
    ],
},

// plugin部分
plugins.push(
    new MiniCssExtractPlugin({
        filename: isProd ? "css/[name].[contenthash:8].css" : "css/[name].css";
    })
);

vue-loader

vue-loader配合webpack4升級(jí)到了v15版本,升級(jí)之后配置方式發(fā)生了一些改變栋烤,以下是項(xiàng)目中使用到的部分:

  • 增加一個(gè)步驟:需要以plugin方式添加到webpack配置中
  • v15版本之后谒养,使用了不同的策略推導(dǎo).vue文件中各個(gè)語言塊使用的loader挺狰,將各個(gè)語言塊視為獨(dú)立的文件使用webpack中配置了規(guī)則的loader處理明郭,由此帶來的配置變化就是針對(duì)樣式處理,webpack.rules中必須顯示提供對(duì)應(yīng)loader處理的規(guī)則丰泊,原vue-loader配置中內(nèi)聯(lián)傳入的樣式相關(guān)loader可以去除
  • 鑒于推導(dǎo)變化薯定,<script></script>標(biāo)簽內(nèi)的js代碼將被視為獨(dú)立的js文件并根據(jù)webpack配置使用babel-loader轉(zhuǎn)譯;項(xiàng)目配置babel-loader時(shí)使用exclude: /node_modules/排除依賴包中代碼的轉(zhuǎn)譯瞳购,如果導(dǎo)入了/node_modules/中的.vue文件话侄,<script>部分將不能被轉(zhuǎn)譯,故需要將.vue文件加入到排除白名單中
// 增加一個(gè)plugin
const VueLoaderPlugin = require('vue-loader/lib/plugin')
plugin.push( new VueLoaderPlugin())

// rules loader配置
// @UPDATED 
// vue-loader v15+版本 .vue文件中的樣式將被抽取出來并認(rèn)為和獨(dú)立引入的css文件相同
// 故需要配置單獨(dú)loader處理
... ...
{
    test: /\.(sa|sc|c)ss$/,
    use: [
        isProd ? MiniCssExtractPlugin.loader : 'style-loader',
        'css-loader',
        {
            loader: 'sass-loader',
            options: {
                includePaths: ['src/static/scss']
            }
        },
    ],
},
// .vue文件
{
    test: /\.vue$/,
    loader: 'vue-loader',
    options: {
        // @UPDATED @DEPRECATED
        // v15+版本不再需要提供內(nèi)聯(lián)的cssloader配置
        // 如果不去掉會(huì)報(bào)錯(cuò)
        // loaders: util.cssLoaders({
        //  sourceMap: false,
        //  extract: build,
        //  build: build
        // })
    }
},
// .js文件
{
    test: /\.js$/,
    loader: 'babel-loader',
    exclude: file => (
        // @UPDATED
        // vue-loader v15+版本 
        // /node_modules/中的.vue文件需要經(jīng)過babel-loader轉(zhuǎn)譯
        /node_modules/.test(file) &&
        !/\.vue\.js/.test(file)
    )
}
... ...

其他變更可以參考vue-loader官方文檔說明https://vue-loader.vuejs.org/migrating.html#notable-breaking-changes

DEMO

項(xiàng)目webpack4配置demo学赛,可以參考~~
https://github.com/icyfanfan/try-webpack4

參考

webpack官方文檔
https://medium.com/webpack/webpack-4-mode-and-optimization-5423a6bc597a
https://medium.com/webpack/webpack-4-import-and-commonjs-d619d626b655
https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366

mini-css-extract-plugin
https://github.com/webpack-contrib/mini-css-extract-plugin

vue-loader
https://vue-loader.vuejs.org/migrating.html#notable-breaking-changes

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末年堆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子盏浇,更是在濱河造成了極大的恐慌变丧,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绢掰,死亡現(xiàn)場(chǎng)離奇詭異痒蓬,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)滴劲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門攻晒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人班挖,你說我怎么就攤上這事鲁捏。” “怎么了萧芙?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵给梅,是天一觀的道長(zhǎng)乙嘀。 經(jīng)常有香客問我,道長(zhǎng)破喻,這世上最難降的妖魔是什么虎谢? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮曹质,結(jié)果婚禮上婴噩,老公的妹妹穿的比我還像新娘。我一直安慰自己羽德,他們只是感情好几莽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宅静,像睡著了一般章蚣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上姨夹,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天纤垂,我揣著相機(jī)與錄音,去河邊找鬼磷账。 笑死峭沦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的逃糟。 我是一名探鬼主播吼鱼,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绰咽!你這毒婦竟也來了菇肃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤取募,失蹤者是張志新(化名)和其女友劉穎琐谤,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矛辕,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笑跛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了聊品。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片飞蹂。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖翻屈,靈堂內(nèi)的尸體忽然破棺而出陈哑,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布惊窖,位于F島的核電站刽宪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏界酒。R本人自食惡果不足惜圣拄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望毁欣。 院中可真熱鬧庇谆,春花似錦、人聲如沸凭疮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽执解。三九已至寞肖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間衰腌,已是汗流浹背新蟆。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桶唐,地道東北人栅葡。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓茉兰,卻偏偏與公主長(zhǎng)得像尤泽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子规脸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

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

  • 1 Webpack 1.1 概念簡(jiǎn)介 1.1.1 WebPack是什么 1坯约、一個(gè)打包工具 2、一個(gè)模塊加載工具 3...
    Kevin_Junbaozi閱讀 6,645評(píng)論 0 16
  • GitChat技術(shù)雜談 前言 本文較長(zhǎng)莫鸭,為了節(jié)省你的閱讀時(shí)間闹丐,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,681評(píng)論 7 110
  • 很難想象生活里沒有你的樣子被因,所有的視線都追逐著你突然有天就消失不見卿拴,這里已經(jīng)沒有你。后來才發(fā)現(xiàn)梨与,心心念念的人永遠(yuǎn)都...
    _Dtath閱讀 287評(píng)論 0 0
  • 我的老家在福建省連城縣廟前鎮(zhèn)的一個(gè)不大不小的村莊一一江畬村堕花。今早打電話給老媽。我問起天氣粥鞋。老媽說不冷缘挽。往年百公僚打...
    汐鲌閱讀 1,196評(píng)論 0 2
  • 近年來前往日本旅游的人越來越多,去日本旅行對(duì)中國(guó)許多年輕人來說越來越像周末去霓虹國(guó)度假~(此處滿滿噠國(guó)家富強(qiáng)...
    大白to小黑閱讀 257評(píng)論 0 0