在webpack中,模块、块和捆绑包分别是什么?

67

我不太理解 module、chunk 和 bundle 这些概念。

{
  entry: {
    foo: ['webpack/hot/only-dev-server.js', './src/foo.js'],
    bar: ['./src/bar.js']
  },
  output: {
    path: './dist',
    filename: '[name].js'
  }
}
在上述配置中,only-dev-server.jsfoo.js是否都是块?foobar是否都是捆绑包?foo.jsbar.js是否都是模块? 答案:在上述配置中,“only-dev-server.js”和“foo.js”都是块,而“foo”和“bar”都是捆绑包。“foo.js”和“bar.js”都是模块。”

1
这是一篇很好的文章,可以让你更清楚地了解如何管理Webpack依赖项。https://www.toptal.com/javascript/a-guide-to-managing-webpack-dependencies - chchrist
4
虽然这篇文章写得不错,但遗憾的是它没有回答“bundle vs chunk”这个简单的问题。 - Rafael Eyng
讨论:https://github.com/webpack/webpack.js.org/issues/970 和 https://github.com/webpack/webpack/issues/162 - Ben Creasy
3个回答

81

经过一天的研究,我想提供一个我认为更准确的答案。Webpack团队发布了一个有用(但很难注意到)的术语表

我认为有关块和捆绑包的混淆在于这些术语可以指同一件事,在Webpack进程的不同阶段应该使用不同的术语。

Webpack术语表定义

模块:提供比完整程序更小的表面积的离散功能块。编写良好的模块提供了稳定的抽象和封装边界,构成了一种连贯的设计和明确的目的。

:这是Webpack特定的术语,用于内部管理过程。捆绑包由多个块组成,其中有几种类型(例如入口和子级)。通常,块直接对应于输出捆绑包,但有一些配置不会产生一对一的关系。

捆绑包:由许多不同的模块生成,捆绑包包含已经进行加载和编译处理的源文件的最终版本。

(我添加的强调)

解释

我将区别总结为:块是Webpack过程中的一组模块,捆绑包是一个已发射的块或一组块

在谈论Webpack过程正在发生时,这种区别是有用的。随着模块被分块在一起,它们可能会发生重大变化(特别是在插件处理期间),因此在这个阶段称它们为捆绑包并不准确,这些块甚至可能不会作为捆绑包在最终输出中发出!然后,在Webpack完成后,拥有一个术语来指代所有已发射的最终文件(捆绑包)是很有用的。

你的示例

因此,对于你的示例:

{
  entry: {
    foo: ["webpack/hot/only-dev-server.js","./src/foo.js"],
    bar: ["./src/bar.js"]
  },
  output: {
    path: "./dist",
    filename: "[name].js"
  }
}
  • 模块: "webpack/hot/only-dev-server.js", "./src/foo.js", "./src/bar.js" (以及任何其他这些入口点的依赖模块!)
  • 代码块: foo、bar
  • 打包文件: foo、bar

在你的示例中,代码块和打包文件之间存在一对一的关系,但并非总是如此。例如,添加源映射会导致一个代码块与一个打包文件之间存在1:2的关系。

资源


35

捆绑包(bundle)是指将相关代码打包成一个单一文件。

如果你不想将所有的代码放到一个巨大的捆绑包中,可以将其分割成多个捆绑包,webpack 术语中称之为chunks。在某些情况下,你可以自己定义如何拆分代码块(使用指向多个文件的 entry 和输出文件模板,例如 [name].[chunkhash].js),在其他情况下,webpack 将为您完成此操作(例如使用 CommonsChunkPlugin)。

模块是 JS 模块(例如 CommonJS 或 ES6 模块)。因为 webpack 内部仅处理模块,所以所有非 JS 资源也被包装成模块。因此,如果你有一些 .sass 文件,你需要在 JS 文件中使用 import/require 导入它们以进行捆绑,但如果你使用 ExtractTextWebpackPlugin,它会为这些文件输出一个单独的 CSS 捆绑包。


2
你的回答很好,但是它仍然没有为我澄清chunk和bundle之间的区别。两者似乎都指的是生成的文件,但我找不到它们之间的区别。 - Rafael Eyng
据我所知,块只是由插件自动产生或手动配置输出块名称生成的捆绑包。基本上,块只是webpack生成的捆绑包。一些块是入口点,将依赖于其他块。 - Ivan
是的,我还是不太明白。我不知道这些术语与我最终得到的输出文件有什么关系。我在这个问题上发表了评论,你可能会感兴趣。 - Rafael Eyng
1
我从未见过两者的定义。但是从上下文来看,chunks 是由 webpack 生成的包束。 "chunk" 这个词意味着它是某个东西的一部分,它确实是如此。多个有相互依赖的 chunks 聚合在一起用于一个目的。因此您可以拥有多个 chunks,每个 chunk 包含一些代码,例如单个网页,并且它们都依赖于一些共享 code 中的一堆共享 chunks。 - Ivan

2
我正在寻找有关将捆绑包拆分成小部分的更多详细信息,并找到了您的问题......同时,我在这个话题上走得很远,并从一篇好的文章中找到了这个,我真的建议您阅读:

一个 chunk 是指会从主 bundle(即main.js)中分离出来的代码,并形成自己的文件,称为 chunk 文件。有两种类型的 chunk,即同步和异步。同步 chunk 与 main.js 同步加载,您会在源代码中看到元素。异步 chunk 在需要时进行加载(懒加载),您会在开发者工具中看到异步 chunk 文件的网络请求。这些 chunk 基于某些条件从 main.js 中拆分出来,我们需要告诉 Webpack。这是通过 Webpack 插件 splitChunksPlugin 完成的。

更多信息请参见:https://itnext.io/react-router-and-webpack-v4-code-splitting-using-splitchunksplugin-f0a48f110312


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接