bundle-loader

bundle-loader是一个用来在运行时异步加载模块的loader。

  1. // 在require bundle时,浏览器会加载它
  2. var waitForChunk = require("bundle!./file.js");
  3. // 等待加载,在回调中使用
  4. waitForChunk(function(file) {
  5. // 这里可以使用file,就像是用下面的代码require进来一样
  6. // var file = require("./file.js");
  7. });
  8. // todo:这句注释说的是?
  9. // wraps the require in a require.ensure block

上面的例子中,在require时文件就会加载,如果你想在使用的时候再加载的话,可以这样:

  1. var load = require("bundle?lazy!./file.js");
  2. // 只有在调用load的时候才会真正加载
  3. load(function(file) {
  4. });

但前面我们已经在“分片”相关的内容中知道,将代码分片之后,本身就是异步加载的。为什么要使用bundle-loader呢?

这是因为webpack在进行分片的时候,会根据“分割点”,分片配置项等各种情况选择性地将各个模块打包在一起。例如:

  1. require(["./f1", "./f2"], function(f1, f2) {/*...*/});

在打包的时候,f1f2会被打包到同一个文件中去(也可能还有其它的文件一起),这样加载的时候f1f2是一起加载的。

而如果使用bundle-loader的话,则是独立的文件和独立的请求:

  1. var f1 = require("bundle!./f1");
  2. var f2 = require("bundle!./f2");

f1f2是独立打包和请求的。

这有什么意义呢?是的,如果f1f2都是确定的,当然是打包到一起更好,能很好地减少浏览器发起的请求,加快页面加载速度。但如果模块名是动态的呢?

  1. function loadPage(pageName, callback) {
  2. try {
  3. require(["./pages/" + pageName], function(page) {
  4. callback(null, page);
  5. });
  6. } catch(e) {
  7. calback(e);
  8. }
  9. }

这种情况下webpack为了保证不管pageName传什么都能正确加载,会将./pages/目录下的所有文件打包到一个文件中去,而很多时候,我们更希望每传一个pageName就动态加载一个文件,而不是全部加载。此时就可以用bundle-loader解决:

  1. function loadPage(pageName, callback) {
  2. try {
  3. var pageBundle = require("bundle!./pages/" + pageName)
  4. } catch(e) {
  5. return callback(e);
  6. }
  7. pageBundle(function(page) { callback(null, page); })
  8. }

每个模块会被打包到一个独立的文件中去,加载时也只会加载一个模块的内容。