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
为通用功能模块。
可是这种方式在项目依赖复杂状况下的效果仍是不太理想,没法作到某段代码只加载一次。
但愿有更好方案的同窗可以不吝赐教。
(本文完)