原创翻译,转载请注明出处。
原文地址:https://webpack.js.org/guides/code-splitting-require/
在这一章里,我们将讨论webpack怎样使用require.ensure来分割代码。
require.ensure()
编译的时候,webpack对代码里的require.ensure()进行静态解析。任何一个作为一个依赖被引用,或者在回调函数里要求的模块,将会被添加到一个新的代码块里。这个代码块被写到异步包里,webpack通过jsonp按需调用它。
语法:
require.ensure(dependencies: String[], callback:function(require), chunkName: String)
依赖
这是一个字符串数组,在这里我们声明所有模块,确保它们在回调函数里所有的代码都能被执行之前都可用。
回调
一旦依赖被加载完,webpack就会执行回调函数。require函数的一个动作就是向这个函数里传递一个参数。方法体可以使用这个参数给require()模块提供执行需要的东西。
代码块名
由这个require.ensure()生成的代码块的名字。通过给各个require.ensure()调用传递相同的代码块名,我们可以把这些代码结合到一个代码块里,这样的话就只有一个包是浏览器必须加载的。
例子
让我们考虑一下下面的文件构成:
. ├── dist ├── js │ ├── a.js │ ├── b.js │ ├── c.js │ └── entry.js └── webpack.config.js
entry.js
require('./a'); require.ensure(['./b'],function(require){ require('./c'); console.log('done!'); });
a.js
console.log('***** I AM a *****');
b.js
console.log('***** I AM b *****');
c.js
console.log('***** I AM c *****');
webpack.config.js
var path =require('path'); module.exports =function(env){ return{ entry:'./js/entry.js', output:{ filename:'bundle.js', path: path.resolve(__dirname,'dist'), publicPath:'https://cdn.example.com/assets/', // tell webpack where to load the on-demand bundles. pathinfo:true, // show comments in bundles, just to beautify the output of this example. // should not be used for production. } } }
在这个项目上运行webpack,我们会发现webpack生成了两个包,bundle.js和0.bundle.js
entry.js和a.js被打包到bundle.js里
bundle.js
/******/(function(modules){// webpackBootstrap //webpack bootstrap code... /******/ // __webpack_public_path__ /******/ __webpack_require__.p ="https://cdn.example.com/assets/"; // webpack bootstrap code... /******/}) /******/([ /* 0 */ /* unknown exports provided */ /* all exports used */ /*!*****************!*\ !*** ./js/a.js ***! \*****************/ /***/(function(module, exports){ console.log('***** I AM a *****'); /***/}), /* 1 */, /* 2 */, /* 3 */ /* unknown exports provided */ /* all exports used */ /*!*********************!*\ !*** ./js/entry.js ***! \*********************/ /***/(function(module, exports, __webpack_require__){ __webpack_require__(/*! ./a */0); __webpack_require__.e/* require.ensure */(0).then((function(require){ __webpack_require__(/*! ./c */2); console.log('done!'); }).bind(null, __webpack_require__)).catch(__webpack_require__.oe); /***/}) /******/]);
b.js和c.js被打包到0.bundle.js里
0.bundle.js
webpackJsonp([0],[ /* 0 */, /* 1 */ /* unknown exports provided */ /* all exports used */ /*!*****************!*\ !*** ./js/b.js ***! \*****************/ /***/(function(module, exports){ console.log('***** I AM b *****'); /***/}), /* 2 */ /* unknown exports provided */ /* all exports used */ /*!*****************!*\ !*** ./js/c.js ***! \*****************/ /***/(function(module, exports){ console.log('***** I AM c *****'); /***/}) ]);
现在只需将bundle.js加到HTML文件里并在浏览器里打开,0.bundle.js将在需要的时候由webpack加载。
更多地例子:
- https://github.com/webpack/webpack/tree/master/examples/code-splitting
- https://github.com/webpack/webpack/tree/master/examples/named-chunks --代码块名的例子
许诺polyfill
参照7.代码分割 – 使用import()的许诺polyfill。
require.ensure()的一些可伸缩特性
空数组作为参数
require.ensure([],function(require){ require('./a.js'); });
依赖作为参数
require.ensure(['./b.js'],function(require){ require('./c.js'); });
在上面的例子里,b.js和c.js被打包到一起,并且和应用程序包分开。但是只有c.js的内容被执行了。b.js的内容只是被提供了,没有被执行。要想执行b.js,我们需要对要执行的JavaScript代码使用同步的方式像require(‘./b.js’)。
-- End --