webpack学习(四)— code splitting

什么是code splitting

首先说,code splitting指什么。咱们打包时一般会生成一个大的bundle.js(或者index,看你如何命名)文件,这样全部的模块都会打包到这个bundle.js文件中,最终生成的文件每每比较大。code splitting就是指将文件分割为块(chunk),webpack使咱们能够定义一些分割点(split point),根据这些分割点对文件进行分块,并实现按需加载。jquery

code splitting的意义

  1. 第三方类库单独打包。因为第三方类库的内容基本不会改变,能够将其与业务代码分离出来,这样就能够将类库代码缓存在客户端,减小请求。webpack

  2. 按需加载。webpack支持定义分割点,经过require.ensure进行按需加载。web

  3. 通用模块单独打包。咱们代码中可能会有一些通用模块,好比弹窗、分页、通用的方法等等。其余业务代码模块经常会有引用这些通用模块。若按照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

  1. vendor配置的模块(jquery,bootstrap)打包到vendor.bundle.js中。插件

  2. 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.jsb.js(固然名字会有所不一样),且为按需加载。只有在访问a时,a.js才会被加载,b同理。可是这种作法存在两个问题:

  1. 若路由分配不合理,会打包出不少很小的文件,每一个文件或许只有几k,却多了不少网络请求,得不偿失。

  2. 会形成通用模块的重复打包,好比a模块和b模块都引用了c模块,

a
import 'c' from './c'

b
import 'c' from './c'

这样咱们会发现打包出的a.jsb.js中都包含c模块的代码,形成了代码冗余。

对于问题1,能够经过webpack提供的插件来解决:

//在plugins中添加该插件:
plugins: [
    new webpack.optimize.AggressiveMergingPlugin()
]

对于问题2:
能够按照下文中所说方式解决。

通用模块打包

这个问题我再网上查阅了一些资料,没有发现特别好的方案,如下所述为本身的一些尝试,可是也并不是最优解,但愿有更好解决方案的同窗可以指出。

一样是利用entrycommonsChunkPlugin来处理的。以下:

//在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.jsvendor.js两个文件。common为通用功能模块。

可是这种方式在项目依赖复杂状况下的效果仍是不太理想,没法作到某段代码只加载一次。
但愿有更好方案的同窗可以不吝赐教。

(本文完)

相关文章
相关标签/搜索