JavaScript 打包器是什么?

2025 年 4 月 18 日 | 阅读 9 分钟

打包器(Bundler)是一种开发工具,它将代码文件打包成一个单一的、可供生产环境使用的 JavaScript 文件。这使得浏览器可以从多个文件中加载代码并无缝运行。打包器的强大之处在于它能够构建一个依赖图来导航原始代码文件。这意味着模块打包器会记录第三方文件以及从指定入口点开始的源文件的依赖关系。这个依赖图确保了所有相关的源文件和代码文件都能被维护且没有错误。

在打包器出现之前,这个过程对 Web 开发者来说一定很困难。当时要维护所有文件及其依赖关系非常复杂,准备工作是一项艰巨的任务。假设你有一个简单的 JavaScript CRUD 应用,比如一个购物清单。在打包器出现之前,你可能已经将这些函数创建在其他 JS 文件中了。

如何创建一个 JavaScript 打包器?

JavaScript 打包器会创建打包后的文件(bundles)。一个 JavaScript 打包器首先必须知道入口点,入口点就像是我们“代码树”的根。在上一段示例的 JavaScript 应用中,`index.js` 文件会是一个很好的入口点选择。现代打包器支持多个入口点。对于一个有多页面的应用程序,为每一页设置一个独立的入口点会很有帮助。

下一步是构建依赖图。JavaScript 打包器会遍历从根(入口点)引用的所有依赖项,以及这些依赖项的所有依赖项,基本上是从上到下进行遍历。通过依赖图,打包器能够精确地确定应用程序中哪些内容依赖于什么,以及在哪里。

Webpack 和其他模块打包器不仅了解入口点的依赖项,它们还能验证每个依赖项的使用情况。由于庞大的依赖树,打包器会将多种优化策略集成到打包后的文件中。

最后,JavaScript 打包器会生成实际的打包文件。采用代码分割、CSS 内联、HMR(热模块替换)和其他性能优化策略可以极大地优化打包文件。

JavaScript 打包器还可以帮助保证与旧版 Web 浏览器的向后兼容性。它会将你代码中最新的 JavaScript 映射到早期 JS 版本中的相应代码。

JavaScript 模块的 Top 5 打包器

你可能在想“哪种打包器适合我”,但 JavaScript 已经阐述了打包器模块及其操作的重要性。在 JavaScript 生态系统中,存在许多模块打包器,每种都有其打包技术。我们将考察 JavaScript 社区中最常用的五种模块打包器,并分析它们的特性、优点和缺点。

1. Webpack

Webpack 是目前最流行的 JavaScript 模块打包器,每周下载量超过 1800 万次,在 GitHub 上拥有 60k 颗星。它拥有大量高级且高度可配置的功能,作为一个静态模块打包器处理 JavaScript 文件,同时也可作为其他文件资源和资产的转换器、最小化器和优化器。但这还不是全部。Webpack 的加载器和插件生态系统也非常强大。

好处

  1. 多资源支持: Webpack 不仅内置支持 JS 文件,还拥有强大的插件生态系统,可以用来打包其他文件,如 CSS 和图片。
  2. 资产优化: 代码分割(Code-splitting)是一个特性,它允许你将代码文件分割成更小的部分,从而减少加载时间。热模块替换(Hot module replacement)是一种工具,可以在不完全重新加载浏览器的情况下帮助你管理模块。
  3. 开发者生产力: 在处理模块打包等复杂任务时,开发者拥有以下几点至关重要:
    • 大量的文档。
    • 可靠的外部工具网络。
    • 一种有效的错误调试方法,可以简化你的工作。
    • Webpack 满足了这三个标准,它提供了强大的源代码映射(source map)调试功能,以及庞大的插件和加载器生态系统。

缺点

  • 复杂: 许多开发者与 Webpack 之间有一种爱恨交织的关系,因为它很复杂,这可能是一把双刃剑。它的学习曲线陡峭,非常复杂。
  • 不稳定且缓慢: 由于 Webpack 采用“万能”方法,Webpack 应用连接器有时会过度设计。当打包器过度依赖插件来完成基本任务时,它可能会变慢,并需要技术排查才能正确优化。

2. Browserify

Browserify 是一个开源的 JavaScript 打包器,允许你将浏览器兼容的 Node.js 文件打包。通过使用 Node.js 风格的 `require()` 方法,开发者可以在浏览器中加载 npm 模块。自 2010 年首次发布以来,这款 JS 打包器一直深受开发者喜爱。

它是如何工作的?

  • 与其他 JavaScript 打包器一样,Browserify 在打包模块时遵循预设步骤。首先是构建依赖图。
  • 此时,Browserify 会从选定的入口点文件开始,递归地检查文件中的所有 `require()` 调用。
  • 每次 `require()` 调用都会返回一个文件路径,并且通过迭代探索每个文件路径来发出额外的 `require()` 调用。
  • 应用程序会生成一个自包含的包来创建和合并文件。在映射整个应用程序的依赖树之后,它会被映射到唯一的 ID。
  • 请记住,Browserify 提供了更高级的自定义选项,例如替换这些 ID 的选项。
  • $ browserify main.js > bundle.js

优点

以下优势显示了 Browserify 打包器的优点。

  • 易于使用: 对于大多数开发者来说,Browserify 是创建功能较少应用程序的理想选择。它提供了简单的 npm 集成,让你无需使用原生 CLI 即可重用你的 Node.js 代码。
  • 开发者生产力: Browserify 吸引人的主要功能是它让你能够受益于强大的 npm 生态系统。它拥有出色的文档,易于学习。此外,它还有一个集成的自动构建系统,简化并加速了模块的构建。所有这些结合起来,使你的应用程序创建过程变得愉快。

缺点

以下缺点显示了 Browserify 打包器的不足之处。

  • 缺乏多资源支持: 与 Webpack 不同,Browserify 不处理多种资产。但是,你可以通过使用 Gulp 流程来解决这个问题。然而,这个过程会增加不必要的复杂性。
  • 缺乏高级管理工具: Browserify 没有强大的资产管理功能来帮助你优化模块,并且它将你限制在 Node.js npm 环境中。例如,它不支持动态加载。

3. Parcel

Parcel 是一个零配置、即插即用的构建工具,它使开发者能够轻松地打包开发所需的各种文件(如 HTML、CSS 和 JS)。它是继 Webpack 之后第二受欢迎的 JS 打包器,在 GitHub 上获得了超过 39k 的评分。

它是如何工作的?

Parcel 打包涉及以下步骤:

  • 资产树构建:以入口点资产为起点,Parcel 遍历文件以查找构建类似依赖图的资产树所需的依赖项。
  • 打包树构建:将资产树中的各个项目与连接它们的依赖项组合起来,构建打包树。
  • 打包:最后一步是将打包树中的每个包与适当的打包器文件类型关联起来,并将其转换为最终编译后的文件。
  • 之后,你可以针对 Parcel 使用单个入口资产。Parcel 也允许使用多个入口点。
  • 运行以下命令即可开始使用此 JavaScript 打包器。
  • 假设你有一个 HTML 样板示例。
  • 然后,可以通过执行 `parcel index.html` 来使用 Parcel 创建 HTML 文件。令人印象深刻的是,Parcel 会编译 HTML 文件引用的 `index.js` 以及它所链接的 HTML 文件。

好处

以下优势展示了 Parcel JavaScript 打包器的优点。

  • 无需配置: Parcel 通过解决 Webpack 和 Browserify 的配置问题,为开发者提供了快速 Web 开发所需的高效架构。此外,Webpack 的多资产支持允许打包各种非 JavaScript 资产,包括 CSS、HTML 和图片。
  • 快速便捷: Parcel 提供快速的高级资源优化功能,如热模块替换和代码分割延迟加载。最近的基准测试表明,Parcel 的打包速度为 9.98 秒。Browserify 和 Webpack 的打包速度分别为 22.98 秒和 20.71 秒。使用 Parcel 的内置缓存方法,基准测试时间为 2.64 秒,可以产生更快的结果。

缺点

  • 缺乏高级定制: Parcel 因其固有的设计理念,是中小型应用程序的理想打包器。但是,对于需要配置更改的复杂应用程序,可能很难进行定制。在这种情况下,大多数开发者会选择使用 Webpack。

4. Fusebox

Fusebox 是一个开源的 TypeScript 和 JavaScript 打包器和加载器。它用于集成 Webpack 的有效优化方法。它是提供丰富 API 接口的最快、最轻量级的打包器。

它是如何工作的?

  • Fusebox 打包过程提供了一种安装方式,可以无需进行重大更改即可运行。
  • 以下命令用于安装 Fusebox。
  • 要运行该工具,需要将脚本文件的主配置文件命名为 `fuse.js` 或 `fuse.ts`。
  • 需要以下示例代码,其中包含入口点模式和目标文件。
  • Fusebox 会创建一个类似于依赖图的虚拟文件结构,并开始打包过程。
  • 配置文件会被合并并在操作时同时发布。

优点

  • 出色的开发者体验: Fusebox 由于其极简的设计,对新用户来说学习曲线很平缓。这使得安装 Fusebox 的配置过程快速而简短。
    它由于极简的资产优化功能而提供快速的操作。打包器使用 HRM(热模块替换)功能管理资产,而无需刷新浏览器。通过强大的缓存系统和内置代码功能加速浏览器加载。

缺点

  • 对多种资源的有限支持: Fusebox 内置支持 JavaScript 和 TypeScript 文件。为了处理 CSS 等其他文件,需要集成 SassPlugin 或 CSSPlugin。与 Webpack 相比,这个较新的打包器没有提供强大的生态系统。

5. Rollup

Rollup 是下一代 JavaScript 打包器,于 2018 年发布。其主要特性是“摇树”(tree-shaking),它可以过滤掉不必要的资源,然后再合并较小的代码。它将单个模块转换为更大的函数。由于其摇树特性,它引起了开发者的广泛关注。每周下载量超过 400 万次,并在 GitHub 上拥有超过 20,000 颗星。

它是如何工作的?

  • Rollup 使用一个名为 `rollup.config.js` 的基本配置文件来定义打包规范。
  • 在分析入口点打包器文件后,它会排序依赖项并建立顺序。
  • 此外,在解析过程中会加入摇树功能。
  • 最后,所有声明的函数都可以在指定的模块中找到。这些函数会被组合成一个全局作用域,同时考虑了可能的名称冲突。
  • 要开始使用,可以通过 `npm i rollup` 命令安装 Rollup。打包可以使用 JavaScript API 或 CLI 配置文件进行。
  • 这是一个操作配置文件,其中包含格式类型、输出文件位置和入口点。
  • 与其他的 JavaScript 打包器一样,Rollup 也兼容多个入口点。

优点

  • 资产优化: 你可以使用 Rollup 强大的资产功能将代码分割到打包文件中。它是加速浏览器加载的管理工具。此外,摇树功能有助于开发者消除无用的变量或函数。
  • 原生支持 ES6: JavaScript ES6 的发布是为了在共享导入和导出时提高浏览器兼容性。你可以使用 Rollup 将现有的导入和导出函数转换为其他模块格式。其他的模块格式如 AMD 和 CommonJS,用于利用新的 ES6 模块系统。

结论

JavaScript 打包器是创建单页功能和运行多个功能所必需的工具。


下一主题免费 JavaScript