Webpack支持两种按需拆分,切入点分别是import()和require.ensure(),首选前者,它是ECMAScript的建议,import也是es6的关键词;后者是webpack所特有的。
其中http、fs、net等都是node.js提供的核心模块,使用C/C++实现,外部用JavaScript封装。
动态导入import
Webpack把import()作为拆分点,把导入的模块放在单独的chunk中。import()接收模块名作为参数并返回Promise:import(name) -> Promise。
require.ensure的格式如下
require.ensure(dependencies: String[], callback: function(require), errorCallback: function(error), chunkName: String)webpack
在编译时,会静态地解析代码中的
require.ensure() ,同时将模块添加到一个分开的 chunk 当中。这个新的 chunk 会被 webpack 通过 jsonp 来按需加载。 |
dependencies是字符串数组,声明在callback被执行之前可用的模块;
- callback是当dependencies被加载完毕可用状态后,webapck执行的回调函数;虽然callback的参数是实现require函数的,但这个形参的名字却不能随意,必须是require;
- errorCallback是可选项,当webpack加载dependecies失败时执行;
- chunkName可选项,指定chunk的名字;
webpack编译时静态解析require.ensure,依赖(dependency)以及在回调函数中require的资源都会被添加一个新的chunk中。
webpack根据下述条件自动进行代码块分割:
- 新代码块可以被共享引用,OR这些模块都是来自
node_modules
文件夹里面 - 新代码块大于30kb(min+gziped之前的体积)
- 按需加载的代码块,最大数量应该小于或者等于5
- 初始加载的代码块,最大数量应该小于或等于3
将公共被引用代码放在每一个依赖的块里,可能就意味着,用户重复会下载它两次。通过用一个独立的代码块分割,它只需要被下载一次。实际上,这只是一种折衷方案,因为我们为此需要付出额外的一次请求的代价。这就是为什么默认webpack将最小代码块分割体积设置成30kb(译注:太小体积的代码块被分割,可能还会因为额外的请求,拖慢加载性能)。
require.ensure(['./a.js'], function(require) {
require('./b.js');
});
上面代码, a.js
和 b.js
都被打包到一起,而且从主文件束中拆分出来。但只有 b.js
的内容被执行。a.js
的内容仅仅是可被使用,但并没有被输出。
想去执行 a.js
,我们需要异步地引用它,如 require('./a.js')
,让它的 JavaScritp 被执行。