webpack學習(四)— code splitting

什麼是code splitting

首先說,code splitting指什麼。咱們打包時一般會生成一個大的bundle.js(或者index,看你如何命名)文件,這樣全部的模塊都會打包到這個bundle.js文件中,最終生成的文件每每比較大。code splitting就是指將文件分割爲塊(chunk),webpack使咱們能夠定義一些分割點(split point),根據這些分割點對文件進行分塊,並實現按需加載。jquery

code splitting的意義

  1. 第三方類庫單獨打包。因爲第三方類庫的內容基本不會改變,能夠將其與業務代碼分離出來,這樣就能夠將類庫代碼緩存在客戶端,減小請求。webpack

  2. 按需加載。webpack支持定義分割點,經過require.ensure進行按需加載。web

  3. 通用模塊單獨打包。咱們代碼中可能會有一些通用模塊,好比彈窗、分頁、通用的方法等等。其餘業務代碼模塊經常會有引用這些通用模塊。若按照2中作,則會形成通用模塊重複打包。這時能夠將通用模塊單獨打包出來。bootstrap

下文將詳細說明。緩存

如何進行code spliting

第三方類庫

咱們項目中經常會用到一些第三方的類庫,好比jquery,bootstrap等。能夠配置多入口來將第三方類庫單獨打包,以下:網絡

//在entry中添加入口
entry: {
    index: './index',
    vendor: ['jquery', 'bootstrap']
},

//在plugins中配置
plugins: [
    new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.bundle.js"),
]

說明
CommonsChunkPlugin提供兩個參數,第一個參數爲對應的chunk名(chunk指文件塊,對應entry中的屬性名),第二個參數爲生成的文件名。
這個插件作了兩件事:ui

  1. vendor配置的模塊(jquery,bootstrap)打包到vendor.bundle.js中。插件

  2. index中存在的jquery, bootstrap模塊從文件中移除。這樣index中則只留下純淨的業務代碼。code

按需加載

以基於backbone的單頁面應用爲例,能夠在router中進行配置實現按需加載,以下:router

router.js

var Router = Backbone.Router.extend({
    routes: {
        'a': 'a',
        'b': 'b'
    },
    
    a: function() {
        require.ensure(['./a'], (require) => {
            let a = require('./a');
            //do something
        })
    },
    
    b: function() {
        require.ensure(['./b'], (require) => {
            let b = require('./b');
            //do something
        })
    }
})

說明
如上方式將打出兩個文件,a.jsb.js(固然名字會有所不一樣),且爲按需加載。只有在訪問a時,a.js纔會被加載,b同理。可是這種作法存在兩個問題:

  1. 若路由分配不合理,會打包出不少很小的文件,每一個文件或許只有幾k,卻多了不少網絡請求,得不償失。

  2. 會形成通用模塊的重複打包,好比a模塊和b模塊都引用了c模塊,

a
import 'c' from './c'

b
import 'c' from './c'

這樣咱們會發現打包出的a.jsb.js中都包含c模塊的代碼,形成了代碼冗餘。

對於問題1,能夠經過webpack提供的插件來解決:

//在plugins中添加該插件:
plugins: [
    new webpack.optimize.AggressiveMergingPlugin()
]

對於問題2:
能夠按照下文中所說方式解決。

通用模塊打包

這個問題我再網上查閱了一些資料,沒有發現特別好的方案,如下所述爲本身的一些嘗試,可是也並不是最優解,但願有更好解決方案的同窗可以指出。

一樣是利用entrycommonsChunkPlugin來處理的。以下:

//在entry中添加入口
entry: {
    index: './index',
    common: ['./c', './d'],  //其中c,d模塊爲通用功能模塊
    vendor: ['jquery', 'bootstrap']
},

//在plugin中
plugins: [
    new webpack.optimize.CommonsChunkPlugin(["common", "vendor"], "[name].js")  //[name]對應'common'和'vendor'
]

這樣則會打包出common.jsvendor.js兩個文件。common爲通用功能模塊。

可是這種方式在項目依賴複雜狀況下的效果仍是不太理想,沒法作到某段代碼只加載一次。
但願有更好方案的同窗可以不吝賜教。

(本文完)

相關文章
相關標籤/搜索