知海

为什么选择 webpack

webpackjsorg-main开始-简介

title: 为什么选择 webpack
sort: 13
contributors:

  • debs-obrien
  • montogeek
  • jeremenichelli
  • EugeneHlushko

要理解为什么应该使用 webpack,让我们回顾一下在打包器出现之前,我们是如何在 Web 上使用 JavaScript 的。

在浏览器中运行 JavaScript 有两种方式。第一种是为每个功能引入一个 script;这种方案难以扩展,因为加载太多脚本可能导致网络瓶颈。第二种是使用一个包含项目所有代码的大型 .js 文件,但这会带来作用域、体积、可读性和可维护性方面的问题。

IIFE —— 立即调用函数表达式

IIFE 解决了大型项目的作用域问题;当脚本文件被 IIFE 包裹时,你可以安全地拼接或合并文件,而不用担心作用域冲突。

IIFE 的使用催生了 Make、Gulp、Grunt、Broccoli 或 Brunch 等工具。这些工具被称为任务运行器(task runner),它们会将所有项目文件拼接在一起。

然而,修改一个文件就意味着必须重新构建整个项目。拼接让脚本在文件之间复用变得更容易,但也让构建优化变得更加困难。你怎么知道代码是否真的被使用?

即使你只使用了 lodash 中的单个函数,也必须添加整个库,然后再压缩到一起。如何对代码中的依赖进行 tree shaking?在大规模项目中,按需加载代码块非常困难,并且需要开发者做大量手动工作。

JavaScript 模块的诞生得益于 Node.js

webpack 运行在 Node.js 上,Node.js 是一种可用于浏览器环境之外的计算机和服务器的 JavaScript 运行时。

Node.js 发布后,一个新时代开始了,随之而来的是新的挑战。既然 JavaScript 不再运行在浏览器中,Node 应用程序应该如何加载新的代码块?已经没有可以添加 HTML 文件和 script 标签的页面了。

CommonJS 出现了,并引入了 require,它允许你在当前文件中加载和使用模块。按需导入每个模块,天然解决了作用域问题。

npm + Node.js + 模块 —— 大规模分发

JavaScript 正作为一种语言、一个平台以及一种快速开发和创建高性能应用的方式席卷全球。

但浏览器不支持 CommonJS。没有实时绑定(live bindings)。存在循环引用问题。同步的模块解析和加载速度缓慢。虽然 CommonJS 对 Node.js 项目来说是一个很好的解决方案,但浏览器不支持模块,因此出现了打包器和工具,如 Browserify、RequireJS 和 SystemJS,使我们能够编写可在浏览器中运行的 CommonJS 模块。

ESM —— ECMAScript 模块

对于 Web 项目来说,好消息是模块正在成为 ECMAScript 标准的正式特性。然而,浏览器支持还不完整,打包仍然更快,目前推荐使用打包而不是这些早期的模块实现。

自动收集依赖

旧式任务运行器甚至 Google Closure Compiler 都要求你预先手动声明所有依赖。而 webpack 等打包器会根据导入和导出的内容自动构建并推断你的依赖图。这与其他插件loader一起,带来了出色的开发者体验。

如果有一个工具……

如果有一个工具,不仅能让我们编写模块,还支持任何模块格式(至少在过渡到 ESM 之前),并同时处理资源和静态资源,那该多好?

这正是 webpack 存在的原因。它是一个可以打包 JavaScript 应用(同时支持 ESM 和 CommonJS)的工具,并且可以通过扩展支持许多不同类型的资源,如图像、字体和样式表。

webpack 关注性能和加载时间;它一直在改进或添加新功能,例如异步代码块加载和预取,为你的项目和用户提供尽可能好的体验。

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。