前言
构建工具就是指能自动对代码执行检验、转换、压缩等功能的工具。从目前市场上流行的构建工具来看,常见的功能有:
- 代码转换,例如将 ts 文件转换为 js 文件。
- 代码打包,将有关联的代码打包在一起。
- 代码压缩、文件压缩、gzip 压缩等。
- 热加载,修改代码后自动刷新页面。
- 代码检验,检查代码格式是否符合规范。 ...
在开发中使用构建工具,能够大大的提升了开发效率。
前端为什么需要构建工具?
构建工具有着一个重要的功能,那就是打包。比如提到Webpack时,许多人的第一反应它是一个打包工具。前端为什么需要打包工具呢?而打包工具出现之前,前端开发有着什么问题呢?我们是否真正需要打包工具呢?
在node.js未诞生之前,javascript单纯的作为一个脚本语言,它只能运行在HTML的 <script>
标签中,如果一个网站功能有很多的话,为了方便维护,我们通常会按照功能去划分多个js文件,那就需要添加多个 <script>
标签,这种方法存在一些明显的局限性和问题,但也是当时唯一可行的办法。例如开发者必须手动确保 <script>
标签按正确的顺序加载,以满足依赖关系。例如,如果 file2.js
依赖于 file1.js
中的某些功能,那么 file1.js
必须先被加载。
js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example</title>
<script src="file1.js"></script>
<script src="file2.js"></script>
</head>
<body>
<script>
// 使用 file1.js 和 file2.js 中定义的变量和函数
</script>
</body>
</html>
以上的方法是十分麻烦的,随着项目规模的增大和复杂度的提高,需要更好的模块化解决方案。那么就有人设计出了模块化方案,例如IIFE 、CommonJS 、AMD 、ESM等。这里我就不介绍这些方案了,喜欢的小伙伴们可以网上了解一下。
模块化可以帮助我们更好地解决复杂应用开发过程中的代码组织问题,但是随着模块化思想的引入,我们的前端应用又会产生了一些新的问题,比如:
兼容问题
首先,我们所使用的 ES Modules 模块系统本身就存在环境兼容问题。尽管现如今主流浏览器的最新版本都支持这一特性,但是目前还无法保证用户的浏览器使用情况。所以我们还需要解决兼容问题。但是在几年前还是有许多浏览器用不了的。
网络资源问题
其次,模块化的方式划分出来的模块文件过多,而前端应用又运行在浏览器中,每一个文件都需要单独从服务器请求回来。零散的模块文件必然会导致浏览器的频繁发送网络请求,影响应用的工作效率。
对于开发过程而言,模块化肯定是必要的,所以我们需要在前面所说的模块化实现的基础之上引入更好的方案或者工具,去解决上面提出的 2 个问题,让我们的应用在开发阶段继续享受模块化带来的优势,又不必担心模块化对生产环境所产生的影响。
这时候,webpack就诞生了。
Webpack
作用
1. 模块打包
Webpack 将应用程序中的各种模块(如 JavaScript 文件、CSS、图片、字体等)视为依赖图,通过打包生成一个或多个优化后的文件。
- 输入: 各种源文件(HTML、JS、CSS、图片等)。
- 输出: 一个或多个打包后的文件,通常用于生产环境。
2. 模块化支持
Webpack 支持多种模块系统,如:
- ES Modules (ES6)
- CommonJS
- AMD
- 其他模块系统
通过模块化开发,代码更加清晰且便于维护。
3. 代码优化
Webpack 提供多种优化功能,使得代码运行得更快、更小:
- 代码压缩(如 UglifyJS/Terser)
- Tree Shaking(删除未使用的代码)
- 代码分割(按需加载,减少首屏加载时间)
4. 支持加载各种资源
通过加载器(Loaders),Webpack 可以处理各种资源文件,如:
- Babel-loader: 转换 ES6+ 代码到 ES5
- CSS-loader: 加载 CSS 文件
- File-loader: 处理图片、字体等静态资源
- Sass/LESS-loader: 编译 Sass/LESS 为 CSS
5. 插件(Plugins)扩展功能
Webpack 提供插件系统,可以自定义构建过程,比如:
- HtmlWebpackPlugin: 自动生成 HTML 文件,并引入打包后的文件
- CleanWebpackPlugin: 清理输出目录
- MiniCssExtractPlugin: 提取 CSS 为独立文件
6. 开发工具支持
Webpack 提供开发工具支持,如:
- 开发服务器(Webpack Dev Server) :实现热更新(HMR),无需刷新页面即可查看修改效果。
- Source Maps:帮助调试时定位源代码中的错误。
核心原理
首先我们先来看看Webpack官网首页的一张图:
Webpack在启动之后,首先会查看我们的配置项,找到入口文件(一般会是一个JS文件)。顺着这个js文件,分析js中的import, require等语句,找到这个文件的资源模块。之后再从文件的资源模块中找到对应的依赖模块,就这样层层递归,最后得出整个项目文件的依赖关系树。
得到了依赖关系树后,webpack使用对应的loader去解析每个文件,例如css-loader,可以将scss和less文件转成css文件,bable可以将es5+ → es5,读到整个项目的文件代码,放到出口文件中,从而实现整个项目的打包。