webpack高級概念code splitting 和 splitChunks (系列五)


當你把所有的代碼都打包到一個文件的時候,每次改一個代碼都需要重新打包。且用戶都要重新加載下這個js文件。但是如果你把一些公共的代碼或第三方庫抽離並單獨打包。通過緩存加載,會加快頁面的加載速度。(分割成多個文件,不必打包成一個文件,提高性能)

  1. 異步加載的代碼,webpack會單獨打包到一個js文件中
  2. 同步加載的代碼有兩種方式

入口文件index.js

引入的第三方庫
import _ from 'lodash'

業務邏輯代碼
console.log(666)

 

打包后的文件main.js

main.js 551 KiB main [emitted] main
可以看到,webpack將業務代碼跟lodash庫打包到一個main.js文件了,每次更改業務代碼,就要重新被打包一次,浪費性能

方法一:手動代碼分割,不推薦

index.js

業務邏輯代碼
console.log(666)

創建一個新文件lodsh.js入口, 將第三方的庫單獨抽離

import _ from 'lodash'
window._ = _

將文件掛載到 window 對象上,這樣其他地方就可以直接使用了。

然后在webpack配置文件中的entry增加一個入口為該文件。

module.exports = {
    entry: {
        main: './src/index.js',
     //新增一個打包的文件,lodash為打包后的文件名稱 ./src/lodash.js為入口文件, 映射關系 lodash:
'./src/lodash.js' },
    output: {
     //模糊匹配entry需要打包文件名稱  filename:
'[name].js', path: path.resolve(__dirname, '../dist') }

 

打包后,打包成main,js和lodash.js兩個文件,html會引入這兩個文件。

當我們業務邏輯更改,webpack重新打包只需打包main.js,lodash.js會緩存在瀏覽器中代碼分割打包,此時提高了性能

Asset Size Chunks Chunk Names lodash.js 551 KiB lodash [emitted] lodash main.js 3.79 KiB main [emitted] main


方法二: webpack自動代碼分割

 

2.1,同步引入第三方庫

入口文件index.js

// 同步加載lodash
import _ from 'lodash'
console.log(_.join(['a','b','c','***']))

在webpack.base.js配置optimization配置參數

 optimization: { // 代碼分割配置
 splitChunks: { chunks: 'all' } },
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, '../dist')
    }
module.exports = {
    entry: {
        main: './src/index.js'
    },

 

打包后的文件,webapck的optimization會自動將諸如lodash等庫抽離成單獨的chunk,還會將多個模塊公用的模塊抽離成單獨的chunk,提高性能

 

 

2.2,異步引入代碼第三方庫

index.js入口文件

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

getComponent().then(element => {
    document.body.appendChild(element);
});

不需要webpack做任何配置

打包后文件, lodash第三方庫自動打包成單獨的0.js,   vue中的路由懶加載就是這樣,import函數

 

 

總結

// 代碼分割,和webpack無關
// webpack中實現代碼分割,兩種方式
// 1. 同步代碼: 只需要在webpack.common.js中做optimization的配置即可
// 2. 異步代碼(import): 異步代碼,無需做任何配置,會自動進行代碼分割,放置到新的文件中

 

 

splitChunks里面還可以在添加個參數cacheGroups

optimization: {
    splitChunks: {
        chunks: 'all',
        cacheGroups: {
              // 下面的意思是:將從node_modules中引入的模塊統一打包到一個vendors.js文件中
            vendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10,
                filename: 'vendors.js'
            },
            default: false
        }
    }
}

 

 

 index.js入口文件

同步加載lodash
import _ from 'lodash'
console.log(_.join(['a','b','c','***']))

打包加載后,cacheGroupsvendors配置表示將node_modules中引入的模塊(所有引入的第三方庫)統一打包到一個vendors.js文件中

 如果venders的 filename: 'vendors.js',屬性注釋掉,那么默認會把第三方庫lodash統一打包到vendors~main.js文件中(main.js為第三方庫引入的文件)

 

splitChunksdefault參數:

根據上下文來解釋,如上配置了vendors,打包node_modules文件夾中的模塊,

那么default將會打包自己編寫的公共方法

添加default的配置

optimization: {
    splitChunks: {
        chunks: 'all',
        cacheGroups: {
              // 下面的意思是:將從node_modules中引入的模塊統一打包到一個vendors.js文件中
            vendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10,
                filename: 'vendors.js'
            },
            // 打包除上面vendors以外的公共模塊
            default: {
                priority: -20,
                reuseExistingChunks: true, // 如果該chunk已經被打包進其他模塊了,這里就復用了,不打包進common.js了
                filename: 'common.js'
            }
        }
    }
}

 

新增test.js

export default {
    name: 'Dell Lee'
}

入口文件index.js,引入test模塊

import test from './test.js';
console.log(test.name);

打包后,自己編寫test.js的公共模塊打包成common.js文件

 

 

splitChunks: {
  chunk: 'all', // all(全部), async(異步的模塊),initial(同步的模塊)
  minSize: 3000, // 表示文件大於3000k的時候才對他進行打包
  maxSize: 0,
  minChunks: 1, // 當某個模塊滿足minChunks引用次數時,才會被打包。例如,lodash只被一個文件import,那么lodash就不會被code splitting,lodash將會被打包進 被引入的那個文件中。如果滿足minChunks引用次數,lodash會被單獨抽離出來,打出一個chunk。
  maxAsyncRequests: 5, // 在打包某個模塊的時候,最多分成5個chunk,多余的會合到最后一個chunk中。這里分析下這個屬性過大過小帶來的問題。當設置的過大時,模塊被拆的太細,造成並發請求太多。影響性能。當設置過小時,比如1,公共模塊無法被抽離成公共的chunk。每個打包出來的模塊都會有公共chunk
  automaticNameDelimiter: '~', // 當vendors或者default中的filename不填時,打包出來的文件名就會帶~
  name: true,
  cashGroups: {} // 如上
}

 

注意;chunk:'all' 默認等於下面一大竄的配置,我們一般默認all即可就行了

    optimization: {
        // 代碼分割配置
        splitChunks: {
            chunks: 'all'
        }
    },

 

    optimization: {
     splitChunks: {
      chunks: 'all',
      minSize: 30000,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          // filename: 'vendors.js',
        },
        default: {
          priority: -20,
          reuseExistingChunk: true,
          filename: 'common.js'
        }
      }
    }
    },

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM