【问题标题】:How "include" and "exclude" works in webpack loader“包含”和“排除”如何在 webpack 加载器中工作
【发布时间】:2016-10-15 21:06:44
【问题描述】:

更新&答案:

我的误解是:

所有导入/需要的文件都会被加载器转换。

但是,某些导入的/必需的文件不需要进行转换。例如,“node_module”中的js文件已经处理完毕。所以不需要再被 Babel loader 改造。这基本上就是为什么我们需要在加载器中“排除:/node_modules/”。

同样,如果您知道加载器要转换哪些文件,您可以使用“include”。

简单地说,entry.js 将包含所有导入/需要的文件。但在这些文件中,只有少数需要转换。这就是“loader”引入“include”和“exclude”的原因。


我仍然不太清楚为什么我们需要在 webpack 的加载器中使用“包含”或“排除”的原因。

因为入口 js 文件总是需要递归地包含其导入/需要的 js 文件。所有导入/需要的文件都将由加载器进行转换。如果是这样,为什么我们需要在加载器中“包含”或“排除”?

一种常见的情况是“排除:/node_modules/”。让我困惑的是,如果入口 js 文件需要来自 node_modules 的一些文件,然后我们排除 node_modules。那么最终的捆绑文件将不包含来自 node_modules 的所需文件。在这种情况下,最终的 bundle.js 将无法正常工作。我在这里有什么遗漏吗?

module.exports = {
  entry: [
    './index.js'
  ],
  output: {
    path: path.join(__dirname,"public"),
    filename: 'bundle.js'
  },
  module: {
    loaders: [{
      test: /\.js$/,
      loader: 'babel',
      exclude: /node_modules/,
      query: {
          presets: ['es2015']
        }
    }]
  }
}; 

谢谢

德里克

【问题讨论】:

    标签: webpack


    【解决方案1】:

    如果 webpack 捆绑(或外部化)所有依赖项,为什么还需要自定义 webpack include/exclude 设置?

    这似乎是 OP 的主要问题。我的答案的要点与以前的答案相似:因为捆绑器的性能。需要/导入的所有内容都将被捆绑或外部化。 exclude 不会改变这一点,但只会根据module.rules转换 中排除文件。您通常不希望转换所有捆绑的依赖项(例如node_modules),因为它们通常已经是您的应用程序“非常容易消化”的格式,因此不需要额外的转换传递。简而言之:如果可能,尽量避免转换,或者:“excludegood,includebad”。

    然而,虽然这种类型的性能优化旨在减少捆绑时间,但它并不是一个完美的解决方案。在关于运行时性能优化的讨论中(当我再次找到它们时会链接),您会发现如果加载器有助于改善全局(交叉-module) 运行时性能优化。

    另一个可能对include 已经转换的库有利的例子:假设某个库被转换为用对可怕的regeneratorRuntime 的依赖替换async functions,除了在运行时减慢速度之外因causing a lot of pain 而臭名昭著。在这种情况下,如果你不想要这种依赖,你可能(通过一些努力)能够将 webpack 获取到 include,使用并转换其原始源文件以使用你自己的 webpack 配置重新编译并保留 @ 987654337@,而仍然是excluding 其他大多数node_modules

    “包含”和“排除”在 webpack 加载器中是如何工作的?

    问题标题的措辞可能会导致一些人(比如我自己)从 Google 来到这里,以便更好地了解如何自定义他们的 webpack.config 的 includeexclude 选项,因为相关的官方文档有些分散。简而言之:

    1. excludeinclude(以及 testresource)是 documented here
    2. 他们是Conditions,也就是documented here
      • 从该文档中可以看出,Conditions(即include/exclude)可以是函数,甚至可以是函数数组,也可以是函数、正则表达式、字符串等的混合体。
      • 我发现function 位特别有趣。您不仅可以使用它来更好地自定义条件,还可以调试 webpack 解析问题。它允许您记录并清楚地了解所有included/excluded 文件,因为它们是由webpack 的解析算法提取的。您可以使用如下函数:
        {
          test: /\.js$/,
          // ...
          include(resourcePath, issuer) {
            console.log(`  included: ${path.relative(context, resourcePath)} (from ${issuer})`);
            return true; // include all
          }
        }
        
    3. 这些函数的两个参数(resourcePathissuer)是documented here
      • 在这里,他们还提到resourcePath 是解析的路径(不是相对路径或名称)。

    PS:虽然include/exclude 的函数的使用在技术上(有点)被记录在案,但显然不是很明显,从this github issue comment 的许多投票中可以看出。

    【讨论】:

      【解决方案2】:

      问题在于,如果没有 exclude(或 include),当您在代码中指向依赖项并处理它们时,webpack 将遍历依赖项。即使这样可行,也会带来严重的性能损失。

      我更喜欢自己设置一个include(允许名单而不是拒绝名单/阻止名单),因为这样我可以更好地控制行为。我include我的应用程序目录,然后根据需要将更多项目添加到include。如果绝对需要,这使我可以轻松地进行异常处理并处理来自node_modules 的位。

      【讨论】:

      • 那么我的问题是,如果我们排除“node_modules”,它如何工作?生成的“bundle.js”中“node_modules”中的一些函数将丢失。那么“bundle.js”就不能正常工作了。对吗?
      • 假设 npm 包默认应该是不需要任何处理的形式。有极少数例外,但大多数应该可以开箱即用。
      • 我不明白你的意思。让我把我的问题说得更清楚一些:假设我们的 entry.js 需要“react”,因为生成的“bundle.js”是一个自包含文件,它应该包含来自“node_modules”的“react”相关的 js 文件,在这里更正?如果是这种情况并且我们排除了“node_modules”,则“react”相关的 js 文件将不会包含在“bundle.js”中。然后“bundle.js”无法工作,因为“react”功能不存在。
      • 它将包含 React 相关文件。它只是不会通过 Babel 处理它们。这正是我们想要避免的。这就是include/exclude 所说的。 React 仍然会被捆绑。我们只是不通过 Babel 传递它,因为它没有意义。
      • +1,这非常有用。您能否举例说明您如何使用include 来拉入一些node_modules 以在您的项目之外进行处理?我需要这样做,而且我认为我做对了,但得到一些确认会很棒。
      【解决方案3】:

      到目前为止,答案还没有真正回答您的核心问题。您想知道您的捆绑应用如何在其依赖项已被“排除”的情况下仍能正常运行。

      实际上,那些 'include' 和 'exclude' 属性告诉 loaders 是否包含/排除所描述的文件(例如 node_modules 的内容) , 不是 webpack 本身

      因此,您从 node_modules 导入的“排除”模块将被捆绑 - 但它们不会被转换 通天塔。这通常是期望的行为:大多数库已经被转换为 ES 5.1(甚至 ES 3),因此浪费 CPU 周期用 babel 解析它们(例如)充其量是毫无意义的。在最坏的情况下,就像 jQuery 这样的大型单文件库,它可能会引发错误并使您的构建崩溃。所以我们排除了node_modules

      【讨论】:

      • 那么如何告诉 webpack 排除文件呢?
      • @ShaileshVaishampayan 我认为externals 是您正在寻找的。 Webpack 不会捆绑您指定为外部的包,而是在运行时您的应用程序/库会期望它们在环境中可用。
      猜你喜欢
      • 2018-10-10
      • 1970-01-01
      • 2016-04-09
      • 2016-11-06
      • 1970-01-01
      • 2019-08-27
      • 2017-09-13
      • 2017-07-16
      • 2017-12-01
      相关资源
      最近更新 更多