antd项目各类webpack打包方案

前言

项目后台使用antd的组件,一直感受很好很强大。无奈总体打包的话太大,光是antd的js就有990k(3.1.1),因此着手优化打包后的大小。css

使用官方推荐的babel-plugin-import插件

基本上前期组件使用少的状况下,这个插件完美解决了问题。这个插件实际上是优化了写法,将本应该html

import Button from 'antd/lib/button';
import 'antd/lib/button/style'; // 或者 antd/lib/button/style/css 加载 css 文件
复制代码

优化成了react

import { Button } from 'antd';
复制代码

本质上是单独引入了Button组件,打包的时候固然只会将Button组件打进去。webpack

模板初始状况

  1. 使用CommonsChunkPlugin插件将react,,react-dom,react-router-dom包单独导出成vendor.js。git

  2. 使用babel-plugin-import插件按需引入antd组件。github

  3. 项目初始包含两个页面,使用HashRouter:主页(Home.js)->app.js和使用bundle-loader异步加载的列表页(List.js)->app-list.jsweb

    import ListC from 'bundle-loader?lazy&name=app-list!./List';
    const List = Bundle(ListC)
    ...
    <Route path={`${match.url}/list`} component={List} />
    复制代码
  4. 模板初始时没有使用任何ui组件,build后各资源大小以下:bash

    app.js->15k
     app-list->1.5k
     vendor.js->150k(包含react,react-dom,react-router-dom)
    复制代码

使用antd组件配合异步加载(以Button组件为例,List和Home里均使用了Button)

  1. 只在List组件里使用Button组件babel

    app.js->15k
     app-list->99k
     vendor.js->150k
    复制代码
  2. 只在Home组件里使用Button组件antd

    app.js->113k
     app-list->1.5k
     vendor.js->150k
    复制代码
  3. Home和List组件都使用Button组件

    app.js->113k
     app-list->1.63k
     vendor.js->150k
    复制代码

结论:能够看出antd配合异步加载Button组件不会重复打包,若是Home和List组件都使用Button组件,只在app.js里打包了Button组件

使用commonChunk将antd打入vendor,同时开启antd按需引入(以Button组件为例,List和Home里均使用了Button)

app.js->94k
app-list->1.64k
vendor.js->1.38M !!!
复制代码

结论:也就是说完整的antd被打入vendor,并且按需引用Button组件的时候又打包了一次

使用commonChunk将antd打入vendor,同时关闭antd按需引入:

app.js->15.2k
app-list->1.61k
vendor.js->1.38M !!!
复制代码

结论:完整的antd被打入vendor,引用Button的时候虽然没有重复打包,可是咱们强烈须要按需引入,毕竟antd 990k大。

开启dll打包(react,react-dom,react-router-dom),开启CommonsChunkPlugin插件(react,react-dom,react-router-dom),开启antd按需引用

app.js->113k
app-list->1.61k
vendor.js->1.6k
common-1.0.0.js->161k
复制代码

结论:DllPlugin插件其实与CommonsChunkPlugin做用差很少,区别是CommonsChunkPlugin每次从新打包打出的vendor.js都会改变,而DllPlugin插件打出的common.js是不变的。若是两个插件同时使用而且打包的库也相同(react,react-dom,react-router-dom),那么commonChunk打出的vendor内容基本上会全到common.js里。antd按需引用的组件没有被重复打包,此种状况也就是说能够省掉commonChunk组件打react,react-dom,react-router-dom的步骤了。

增长多入口(app.js app2.js),关闭commonChunk插件,开启dll,开启antd按需引用

app.js->114k(使用Button组件)
app2.js->4.88k(未使用Button组件)
app-list->1.63k(使用Button组件)
app-list2->105k(使用Button组件)
common-1.0.0.js->161k
复制代码

结论:dll插件能够达到commonChunk的做用,而后用此脚手架为模板新开一个项目,发现common-1.0.0.js在另外一个项目中也通用,直到dll插件中打的库发生改变(react,react-dom,react-router-dom)

使用webpack的externals属性,将react,react-dom,react-router-dom经过script引入,不使用antd任何组件,不使用commonChunk和dll.

app.js->12.4k(不使用Button组件)
复制代码

使用webpack的externals属性,将react,react-dom,react-router-dom经过script引入,使用antd Button组件

app.js->115.k(使用Button组件)
app-list->1.63k(使用Button组件)
复制代码

使用webpack的externals属性,将react,react-dom,react-router-dom,antd经过script引入,使用antd Button组件

app.js->16.6k(使用Button组件)
app-list->1.61k(使用Button组件)
复制代码

结论:此种方法成功把antd剥离出去了,可是html里须要引入antd.min.js和antd.min.css和moment.min.js!!!,moment.min.js必须放在antd以前,不然datepicker组件会报错。同时,.babelrc文件里须要去掉babel-plugin-import的使用,若是不去掉,app.js会有115k,也就是说antd的Button组件仍是会被打进了app.js里。

综上:

  1. 使用AutoDllPlugin插件替代webpack自带的dllPlugin插件更加方便。
  2. 使用AutoDllPlugin与commonChunk插件均可以,若是不要求多项目公用基础js的话。
  3. 使用extarnals没法使用按需加载。
  4. commonChunk+antd按需引入+页面按需加载使用最方便。
  5. 使用页面按需加载时,为防止组件被多个页面重复打包,可将组件放到根组件上。例如:app-list与app-list页面均使用Button,但根组件app.js没有使用,那么app-list和app-list都会把Button打进各自的js里,打包时间将会延长,可将Button在app.js里使用下,这样app-list和app-list都不会在打Button了。

项目地址

相关文章
相关标签/搜索