code splitting
首先說,code splitting
指什麼。咱們打包時一般會生成一個大的bundle.js
(或者index
,看你如何命名)文件,這樣全部的模塊都會打包到這個bundle.js
文件中,最終生成的文件每每比較大。code splitting
就是指將文件分割爲塊(chunk
),webpack
使咱們能夠定義一些分割點(split point
),根據這些分割點對文件進行分塊,並實現按需加載。jquery
code splitting
的意義第三方類庫單獨打包。因爲第三方類庫的內容基本不會改變,能夠將其與業務代碼分離出來,這樣就能夠將類庫代碼緩存在客戶端,減小請求。webpack
按需加載。webpack
支持定義分割點,經過require.ensure
進行按需加載。web
通用模塊單獨打包。咱們代碼中可能會有一些通用模塊,好比彈窗、分頁、通用的方法等等。其餘業務代碼模塊經常會有引用這些通用模塊。若按照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
將vendor
配置的模塊(jquery
,bootstrap
)打包到vendor.bundle.js
中。插件
將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.js
和b.js
(固然名字會有所不一樣),且爲按需加載。只有在訪問a
時,a.js
纔會被加載,b
同理。可是這種作法存在兩個問題:
若路由分配不合理,會打包出不少很小的文件,每一個文件或許只有幾k
,卻多了不少網絡請求,得不償失。
會形成通用模塊的重複打包,好比a
模塊和b
模塊都引用了c
模塊,
a import 'c' from './c' b import 'c' from './c'
這樣咱們會發現打包出的a.js
和b.js
中都包含c
模塊的代碼,形成了代碼冗餘。
對於問題1
,能夠經過webpack
提供的插件來解決:
//在plugins中添加該插件: plugins: [ new webpack.optimize.AggressiveMergingPlugin() ]
對於問題2
:
能夠按照下文中所說方式解決。
這個問題我再網上查閱了一些資料,沒有發現特別好的方案,如下所述爲本身的一些嘗試,可是也並不是最優解,但願有更好解決方案的同窗可以指出。
一樣是利用entry
和commonsChunkPlugin
來處理的。以下:
//在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.js
和vendor.js
兩個文件。common
爲通用功能模塊。
可是這種方式在項目依賴複雜狀況下的效果仍是不太理想,沒法作到某段代碼只加載一次。
但願有更好方案的同窗可以不吝賜教。
(本文完)