对于大型项目,将所有的代码放在一个文件中不是很好,特别是一些代码只会在响应的情况下才会
用到,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) {
// ...
});注意:AMD
require
加载并执行响应的模块,在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
选项的值,打包时执行不同的逻辑去加载分块,比如web
target,分块通
过jsonp被加载,一个分块只会被加载一次,并发的请求将会被合并成一个,运行时检查加载的分块是
否满足多个分块
分块类型
入口块