代码拆分

对于大型项目,将所有的代码放在一个文件中不是很好,特别是一些代码只会在响应的情况下才会
用到,webpack的其中一个特性就是将你的原代码拆分成块按需加载,一些其余的打包工具将它称之
为”层”,”片段”,webpack将其称为”代码拆分”.
这是一个可被选择的特性,你可以在你的原代码中定义拆分点,webpack会维持好依赖性,输出文件
以及运行时文件。
为了澄清一个常见的误解,代码拆分并不仅仅是将公共代码提取出来到一个公共的模块,更重要的特性
是可以将拆出来的代码块按需加载,这可以保证首次加载的代码更少,请求会按需加载所需要的代码。

定义分离点

AMD和CommonJs指定不同的方法实现按需加载,webpack都支持并且并且都是定义为分离点的形式。
CommonJs: require.ensure

1
require.ensure(dependencies, callback)

require.ensure方法保证 每个依赖都会在回调函数被同步的请求进来,回调函数被执行时,
require是回调函数的参数.例如:

1
2
3
4
require.ensure(["module-a", "module-b"], function(require) {
var a = require("module-a");
// ...
});

注意:require.ensure仅仅是加载模块,但是并不会去执行他们

AMD:require

AMD规范以下面的方式定义了一个异步的require方法

1
require(dependencies, callback)

当调用时,所有的依赖都会被加载,并且将他们作为参数给回调函数,例如

1
2
3
require(["module-a", "module-b"], function(a, b) {
// ...
});

注意:AMDrequire加载并执行响应的模块,在webpack中模块是从左向右执行的,并且可以省略
回调函数。

ES6模块

Webpack不支持ES6模块,直接使用require.ensure或者require取决于设计哪个模块组成你的
编译.
Webpack1.x.x(2.0即将来临)原生的不支持ES6模块,但是你可以通过转换器解决他,比如使用Babel
转换ES6的import语法为CommonJs或者AMD模块,这种途径是有效的,但是当动态加载时会有警告。
这种模块添加方式import x from 'foo'是故意设计为静态分析的,意味着你不能用于动态导入

1
2
// INVALID!!!!!!!!!
['lodash', 'backbone'].forEach(name => import name )

幸运的是,JavaScript有loader规范去处理动态导入:System.load或者System.import)
原生的API和require的定义是等价的,但是大多数编译器不支持转化System.load为’require.ensure’
所以如果想使用动态代码拆分的话直接使用require.ensure

1
2
3
4
5
6
7
//static imports
import _ from 'lodash'

// dynamic imports
require.ensure([], function(require) {
let contacts = require('./contacts')
})

分块内容

分离点处的所有依赖都会被独立成一个块,依赖会递归的被添加。
如果在分离点处的回调函数是一个函数,webpack 会把该函数里的依赖都提取到按需加载的代码块中。

分块优化

如果两个分块包含相同的模块,它们会被合并成一个,这会造成分块有多个父模块,如果一个模块
在一个分块中的所有父模块都可用,那么它将会从该分块中移除。
如果一个分块包含了另一个分块中的所有模块,它会被储存起来,满足多个分块.

分块加载

根据配置文件的target选项的值,打包时执行不同的逻辑去加载分块,比如webtarget,分块通
过jsonp被加载,一个分块只会被加载一次,并发的请求将会被合并成一个,运行时检查加载的分块是
否满足多个分块

分块类型

入口块