打包工具
Webpack
Webpack
是一个强大的静态模块打包工具,它可以对 JavaScript
文件进行模块化打包,同时还可以利用相应的 loader
,将其他类型的静态资源(如 CSS
、图片
、字体
等)转换为模块,然后打包到项目中。它的理念是一切皆模块和按需加载。
总的来说,Webpack
主要一站式解决了开发中的以下需求:
- 代码转换:将
ES6
语法转换为ES5
、TypeScript
转换为JavaScript
、SCSS
转换为CSS
等。 - 模块整合:将多个
JavaScript
文件整合起来,形成大的bundle.js
文件,有助于减少网络请求次数。 - 万物皆可模块:
Webpack
可以将任何静态资源视为模块,包括JavaScript
、CSS
、图片
、字体
等,所有资源按需加载。 - 文件压缩:可对
JavaScript
变量名进行缩短、对图片等大文件进行压缩,减少文件体积,提高加载速度。
构建流程
Webpack
的构建流程主要分为以下几个步骤:初始化、编译构建以及输出。
初始化步骤主要是从 webpack.config.js
配置文件或者命令行中读取打包选项,并初始化要使用的插件 Plugin
等。编译构建从 entry
入口文件开始,串行地对 module
中的模块进行编译。编译开始后进行 loader
加载、依赖分析(构建每个依赖的模块)、生成 AST
、遍历 AST
、生成代码、优化代码、生成 chunk
等。然后新的 chunk
会作为下一轮编译的入口文件,直到所有的模块都编译完成。最后输出流程将编译好的 chunk
转换为文件输出到 dist
目录。
plugin
和 loader
的区别
loader
用于对模块的源代码进行转换。webpack
本身只能理解JavaScript
和JSON
文件,对于其他类型的文件,需要使用loader
进行转换。plugin
用于扩展webpack
的功能,通过plugin
可以监听webpack
构建生命周期的每个阶段,执行相应的任务。plugin
主要用于解决loader
无法实现的其他事情,如打包优化、资源管理、环境变量注入等。plugin
可以存在于webpack
的全流程,而loader
在完成转换之后就不会再参与后续的流程。
一些常用的 loader 和 plugin
style-loader
: 将 CSS 添加到 DOM 的内联样式标签 style
里
css-loader
:允许将 CSS 文件通过 require
的方式引入,并返回 CSS 代码
less-loader
和 sass-loader
: 处理 less 和 sass 文件
file-loader
: 分发文件到 output
目录并返回相对路径
url-loader
: 和 file-loader
类似,但是当文件小于设定的 limit
时可以返回一个 Data Url
html-minify-loader
: 压缩 HTML
babel-loader
:用 babel
来转换 ES6 文件到ES5
html-webpack-plugin
:在打包结束后,⾃动生成⼀个 HTML ⽂文件,并把打包生成的 js
模块引⼊到该 HTML 中
mini-css-extract-plugin
:将 CSS
提取到单独的文件中
clean-webpack-plugin
:在每次构建前清理 /dist
目录
热更新
Webpack 的热更新(HMR)通过 webpack-dev-server
创建两个服务器实现:Express 服务器负责直接提供静态资源(如打包后的 JS、CSS),供浏览器请求和解析;Socket 服务器则通过 WebSocket 长连接与客户端实时通信。当代码变化时,Webpack 重新编译并生成描述模块变化的 manifest.json
文件和包含更新代码的 update chunk.js
文件。Socket 服务器主动将这两个文件推送给客户端,由客户端的 HMR Runtime 接收并加载,根据 manifest.json
定位需更新的模块,用 update chunk.js
替换旧模块,实现不刷新页面的热替换。整个过程为运行时增量更新。
Rollup
Rollup
是一款 ES Modules 打包器,从作用上来看,Rollup
与 Webpack
非常类似。但它比 Webpack
更加小巧,专注于 ES6
模块的打包,生成的代码非常简洁,完成不像 Webpack
那样存在大量引导代码和模块函数;并且借助 Tree-shaking
优化,能够更好地消除无用代码,生成更小的包。目前,Vue3
的官方脚手架 Vite
就是基于 Rollup
构建的。
但它不如 Webpack
那样强大,需要借助其他模块来支持其他类型的资源,并且不支持热更新。但它在打包 ES6
代码库时,是一个非常好的选择。
什么是摇树优化
摇树优化(Tree Shaking)是一种用于优化 JavaScript 代码的技术。它的目标是通过静态分析,从代码中剔除未被使用的模块,从而减少最终打包文件的大小。
在一个大型的 JavaScript 应用程序中,通常会引入多个模块和库,但并不是所有的模块都会被使用到。如果没有进行优化,所有引入的模块都会被打包到最终的输出文件中,导致文件变得很大。ES6 模块系统的静态特性使得 Webpack/Rollup
能够在打包时识别出哪些模块被引入,哪些模块没有被引入,从而实现摇树优化。注意:摇树优化是基于 ES6 模块的静态特性实现的,对于 CommonJS 模块则无法实现。
有些模块中可能存在有副作用的代码(如操纵了全局变量、修改了原型链等),这些代码就算没有被引用,也不能被删除。Webpack
会通过 sideEffects
配置项来标记哪些模块有副作用,哪些模块没有副作用,以便进行摇树优化。因此,为了尽量减少打包后的文件大小,应该尽可能减少模块的副作用。
Vite
Vite
是一种新型的前端开发工具,尤其适合于 Vue3 项目。它的核心思想是利用浏览器原生 ES 模块导入,并在每次请求时编译代码,可以做到极快的冷启动时间和热更新速度。
Vite
会在运行时直接启动开发服务器,无需打包,而是利用浏览器原生支持 Module
按需引入特性,在浏览器做出请求时编译代码,这样可以实现按需编译,只编译当前请求的文件,而不是整个项目。由此大大提高开发效率。当修改一个模块时,只需要让浏览器重新请求该模块即可,而不是整个项目。同样,Vite
会使用一个 WebSocket
服务器来实现热更新,当文件发生变化时,这一变化会由此推送到浏览器。
在生产环境下,Vite
可使用 Rollup
进行打包,生成高效的生产代码。

Vite 按需编译