webpack中的Code Splitting以及配置參數

代碼分割 Code Splitting

在最開始的時候,webpack都是將全部的代碼打包到一個文件中,可是當項目過大的時候,頁面所須要加載的時間就會變長,這個時候咱們就須要Code Splitting對文件進行分塊,實現代碼的按需加載。node

接下來咱們來看看下面兩種方式:webpack

當用第一種方式的時候, 咱們須要等打包文件加載完成以後,纔會去實現文件裏面的邏輯,再將頁面展現出來。那麼這樣帶來的問題是什麼呢,有一個問題想必你們都很清楚,那就是打包文件很大,加載時間很長web

那還有一個問題是什麼呢,咱們都知道,lodash是一個第三方庫,咱們不會隨便去修改它,可是業務邏輯是常常會被改變的。假設咱們修改了業務代碼,那咱們就須要從新去加載打包中的js文件,才能獲取到最新的代碼,顯示最新的內容。由於業務代碼和第三方庫都在同一個文件中,因此lodash相應的也要被從新加載。緩存

index.jsapp

// 同步邏輯
// 第一種方式
// 首次訪問頁面的時候, 加載main.js 2mb
// 當業務邏輯發生變化時 又要加載main.js 2mb的內容
import _ from 'lodash' //假設1mb
// 業務邏輯 1mb
console.log(_.join(['a','d','c'], "***"));
// 中間省略幾千行代碼....
console.log(_.join(['a','b','c'], "***"));
複製代碼

第二種方式咱們將上面代碼拆分紅了兩個文件main.jslodash.js,咱們將不須要修改的第三方庫拎出來放在一個單獨的文件中,當頁面業務邏輯發生變化的時候,只須要加載main.js頁面就能夠了。異步

這種動態加載的方式就能提高咱們頁面展現的速度,相應的也提升了性能。async

index.js性能

// 第二種方式
// main.js被拆成lodash.js(1Mb), main.js(1mb)
// 當業務邏輯發生變化時,只要加載main.js便可(1MB)
// 業務邏輯 1mb
console.log(_.join(['a','d','c'], "***"));
console.log(_.join(['a','b','c'], "***"));
複製代碼

lodash.js學習

// 加載了lodash,而後將lodash掛載到了全局上面
import _ from 'lodash'; //1mb

window._ = _
複製代碼

webpack插件幫助代碼自動拆分

Code Splitting其實本質上是和webpack沒有任何關係的,但爲何只要一說到webpack,咱們在不少時候都能聽到webpack裏面有Code Splitting呢?這是由於webpack裏面有一些插件能夠很是容易的幫助咱們實現Code Splittingui

在webpack4裏面有一個插件splitChunksPlugin,這個插件直接與webpack作了捆綁,不須要安裝,直接就能夠拿來用了。這樣的話咱們進行代碼分割就很是容易了。

同步代碼分割

咱們先將以前的lodash.jsindex.js合併,而後咱們在webpack.config.js裏面配置一個optimization

optimization: {
    splitChunks: {
      chunks: 'all'
    }
}
複製代碼

咱們從新對代碼進行打包,查看dist目錄:

咱們能看見,只要作一個很是簡單的配置,就能實現代碼分割,徹底不須要咱們再手動進行文件的拆分。

異步代碼的分割

上面咱們說的是同步加載。那麼接下來咱們看看異步加載吧!

// 異步加載lodash
function getComponent() {
  return import('lodash').then(({default: _}) => {
    const element =  document.createElement('div')
    element.innerHTML = _.join(["linna", "mao"], '-')
  })
}

getComponent().then(element => {
  document.body.appendChild(element)
})
複製代碼

若是你們實踐過的話,就知道即使咱們不在webpack.config.js中配置optimization,異步載入的組件也會自動打包再一個單獨的文件中。

SplitChunksPlugin配置詳解

從上圖中咱們能夠看到,異步代碼分割中,dist目錄中打包生成的文件是一個0.js這個0是Code Splitting產生的一個id的值

若是咱們想要將它改爲咱們能夠識別的名字,咱們就能夠在上面異步代碼的第一個參數前面添加/*webpackChunkName:"lodash"*/,這個是在異步加載組件中存在的一個magic comment(語法註釋)。

magic comment只能在官方動態加載組件的插件使用

//詳細代碼看異步代碼中的index.js
return import(/*webpackChunkName:"lodash"*/'lodash').then(({default: _})
複製代碼

打包後咱們能夠看到vendors~lodash.js,那麼爲何會在lodash前面添加vendors呢?這裏咱們就須要去看咱們的配置了,官方文件中在optimization中會有一個默認配置

splitChunks: {
    chunks: "async",
    minSize: 30000,
    minChunks: 1,
    maxAsyncRequests: 5,
    maxInitialRequests: 3,
    automaticNameDelimiter: '~',
    name: true,
    cacheGroups: {
        vendors: {
            test: /[\\/]node_modules[\\/]/,
            priority: -10
        },
    default: {
            priority: -20,
            reuseExistingChunk: true
        }
    }
}
複製代碼

其中:

更多詳解參考官網split-chunks-plugin

  • chunks:默認配置aysnc的意思是對異步代碼進行分割,這就是爲何在以前代碼中異步代碼分割不須要進行配置的緣由。
  • minSize:引入的模塊的大小大於30000才能進行代碼分割。
  • minChunks:當模塊被引用了至少1次的時候進行代碼分割。
  • maxAsyncRequests:同時加載的模塊數最可能是5個。若是加載模塊超出了五個,那就加載前五個,後面的就不會再進行代碼分割了。
  • maxInitialRequests:入口文件引入的庫最多能分割成3個代碼文件。
  • automaticNameDelimiter:文件生成時候,組和文件名之間的鏈接,就像以前咱們說到的vendors~lodash.js
  • name: 默認爲true,打包生成的文件,取名的時候讓cacheGroup裏的名字有效。
  • cacheGroup: 至關一個緩存組。
    • 當引入的模塊在node_modules中的時候,符合vendors,就會在分割文件中添加前綴vendors,當有多個node_modules模塊時候,就會將全部引用模塊先進行緩存,最後的時候一塊兒打包成vendors文件。
    • index.js引入一個本身寫的js文件,它就找到cacheGroup,不符合vendors的時候,就會進入default中,這個時候打包文件的前綴就會有default
    • priority: default中全部的模塊都是符合的,當一個模塊既符合vendors又符合default的時候,那麼priority的值越大,優先級越高。
    • reuseExistingChunk: 若是一個模塊已經被打包過,再打包的時候就會忽略這個模塊,直接使用以前被打包過的模塊。

注:此文爲本人學習過程當中的筆記記錄,若是有錯誤或者不許確的地方請大佬多多指教~

相關文章
相關標籤/搜索