最近接到一个任务是帮忙优化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库。