【问题标题】:webpack require.ensure first parameter usewebpack require.ensure 第一个参数使用
【发布时间】:2016-07-26 04:55:54
【问题描述】:

webpack的第一个参数require.ensure第一个参数有什么用?

https://webpack.github.io/docs/code-splitting.html

require.ensure(dependencies, callback)

我试图让第一个参数填充或为空:

require.ensure(['./module'], function() {  //filled first param

require.ensure([], function() {  //empty first param
  let module = require('./module');
  $ocLazyLoad.load([{
    name: module.default,
  }]);
});

两者都在工作。那么第一个参数有什么用呢?

文档中还有一个require.include函数,我不明白这个函数的用例。谁能解释一下?

【问题讨论】:

    标签: javascript webpack commonjs oclazyload code-splitting


    【解决方案1】:

    这些函数与Code Splitting 相关,它允许将某些代码段与主代码分开捆绑,然后在代码运行时加载和运行。

    代码示例 1:

    require.ensure(['./module'], function() {  //filled first param
    

    第一个参数是一个模块数组,以确保在运行回调之前加载。如果./module 尚未加载到其中一个包中,它将加载此模块包含在新HTTP 请求中的块,然后调用回调函数。

    使用 Webpack 的例子:

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

    module-amodule-b 现在可以拆分为不同的文件,并且回调函数在加载之前不会运行。

    代码示例 2:

    require.ensure([], function() {  //empty first param
      let module = require('./module');
      $ocLazyLoad.load([{
        name: module.default,
      }]);
    });
    

    这里require.ensure 定义了一个分割点。由于它在数组中没有任何依赖关系,因此它本身不会加载任何模块。但是,回调中的require 语句仍将通过 webpack 的魔力动态加载,./module 将捆绑在一个单独的文件中。

    require.include

    文档中还有一个require.include函数,我不明白这个函数的用例。谁能解释一下?

    require.include 可用于确保捆绑模块,即使它不是require-ed。通常如果一个模块不是require-ed,它根本不会被捆绑。这可以用来强制它包含模块,即使它不是 requir-ed 在包本身中。

    【讨论】:

    • 很好的问题/答案,webpack 的这个领域很快就会变得混乱。如果 require.ensure 什么都不做,代码示例 2 的意义何在,我们会通过删除它并要求文件顶部的模块得到相同的结果吗?我看到这种模式与 react-router 一起用于异步路由here。为什么 react-router 示例没有列出它们将要异步加载的模块依赖项?
    • @cchamberlain 是的,为什么 react-router 示例在要异步加载时没有列出模块依赖项,是 react-router 示例中的错误还是代码示例 2 的答案是不正确?
    • 对于require.include,当我可以正常要求时,拥有require.include有什么意义?
    • 代码示例 2 的描述不正确,这确实是上述问题的核心。它仍然为确保内部所需的任何模块创建一个拆分。
    • @AKnox 谢谢指正,看来我的测试一定是出错了。
    【解决方案2】:

    第一个参数很少有用。要了解它为何存在并导致混淆,请查看我的另一个 answer

    遵守规范

    第一个参数的一个用例可能是为了清楚起见指定所有依赖项并遵守spec。但这完全是可选的。

    将模块添加到块中以使块相似

    假设您在应用的不同部分有两个分割点。第一个分割点依赖于模块a,第二个依赖于模块ab。 为了消除下载a 两次的风险,您可以决定将两个模块放在一个块中:

    // First split point
    require.ensure(['b'], (require) => {
      require('a');
    });
    

    将模块拉入父块中

    考虑以下代码拆分场景:

    require.ensure([], (require) => {
      ...
      require.ensure([], (require) => {
        require('a');
        require('b');
      });
    
      require.ensure([], (require) => {
        require('a');
        require('c');
      });
      ...
    });
    

    在这种情况下,模块a 将在两个嵌套块中结束。如果经常加载至少一个嵌套块,您可以决定将a 移动到父块中:

    require.ensure(['a'], (require) => {
      ...
    

    使用require.include 将模块添加到块中

    考虑前面的例子。还有另一种方法可以将a 拉到父块中:

    require.ensure([], (require) => {
      require.include('a');
      ...
    

    在这个特定示例中,两种解决方案是等效的,使用require.include 没有任何优势。但是,如果您无权访问拆分点的代码,父块是入口块,或者您使用现代的import() 语法,require.include 是您唯一的选择。

    可以使用同步requireimport 将模块拉入块中。 require.include 的优点是它只加载模块而不评估它们。如果模块的评估成本很高或取决于应用程序状态,例如,需要加载 polyfill、存在 DOM 节点等,这可能有助于推迟模块的评估。

    【讨论】:

      猜你喜欢
      • 2016-04-24
      • 1970-01-01
      • 2017-05-27
      • 1970-01-01
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      • 1970-01-01
      • 2017-04-15
      相关资源
      最近更新 更多