最近接到一個任務是幫忙優化jsbundle的體積,項目是用ts開發,多入口。在分析以後發現每一個bundle都打了同一份代碼(這份代碼是其它組提供的ts,編譯出來的js在3k左右),並且是不常常變更的。webpack
最初想到的就在打包的時候經過CommonChunkPlugin
或者Dll & DllReference
插件來把這塊提取出來,代碼拆分作成一個獨立的js,可是這樣有個問題:就是每次其餘組把這塊代碼更新的時候須要在工程裏再跑一遍打包構建的過程,這就涉及到一個組更新了代碼須要另外的組打包構建,在某些場景下是不可接受的。web
在考慮了以後,決定將這部分公共的代碼以庫的方式提供出來,在提供給別人以後,打成單獨的jsbundle,讓別人在頁面引。這就涉及到兩次打bundle,那這兩次打的bundle如何打通呢?ide
output.library + out.libraryTarget + externals的方式
library: 配合libraryTarget使用。能夠簡單的看作這個庫暴露給別人用的時候,關鍵詞是啥。類比jQuery。
libraryTarget: 配合如何去暴露library。支持下面幾種:優化
經過var以變量的方式暴露出去。默認配置ui
{ library: 'clam' }打出來的jsbundle就是
var clam = /**_entry_return_*/;
直接在頁面引的話可能就直接掛window上了。this
assign
能夠將return掛載到已經存在的某個變量上。經過其它一些變量的方式暴露出去。能夠配置this
,global
,commonjs
,window
,這些配置加上library,就能夠把對應的庫掛載到這些變量上。對應的就是:插件
this
=>this['clam'] = /**_entry_return_*/
global
=>global['clam'] = /**_entry_return_*/
window
=>window['clam'] = /**_entry_return_*/
commonjs
=>exports['clam'] = /**_entry_return_*/
經過上述兩個配置就解決了打庫文件的文件,可是當時不想把太多的東西掛載到window上,就利用了assign的方式掛載在一個變量底下。即:code
library: `$VAR['clam']`, libraryTarget: `assign`
使用assign的方式只會,返回值會掛載在$VAR['clam']上,在打包的時候須要創建起與這個"庫"的鏈接而且排除這個bundle就好。這個時候就該externals出場了。開發
externals的配置主要就是爲了解決上述說的兩個問題:文檔
具體的配置能夠看下官方文檔,不一樣的配置方式只是應對不一樣的場景,做用仍是上面提到的兩點。
好比咱們利用output.library & output.libraryTarget
發佈的包名叫Lib,使用的方式是import {xxx} from 'Lib';
其全部的實現都已經掛載了$VAR['clam'] 上,那咱們能夠像下面這樣配置externals:
externals:{ 'Lib': `$VAR['clam']` }
這樣生成的jsbundle裏以下的方式:
... var xxx = webpack_require(`$VAR['clam']`); ...
這篇記錄主要記錄了一次利用output.library & output.libraryTarget & externals
來以庫的方式將每一個bundle的js減小3k仍是不錯的。
具體怎麼打一個庫能夠看看建立Library文檔。不一樣的配置能夠將你的庫打成一個commonjs庫,es2015庫甚至是一個UMD庫。