三分钟简单理解webpack和vite的区别

1,581 阅读4分钟

在Vue3出来前,我们更多地是使用webpack作为构建工具。webpack基于他的 高度可配置性以及丰富的插件生态等强大的功能而被大家所使用。但Vue3出来的同时,一个新的Vite打包工具又出现在了大家的眼前。那么它们的有什么区别,我们在什么情况下去使用它们呢。这篇文章,带大家一起做个粗浅的了解吧

1、Vite速度快

构建速度快、开发环境下热更新快、生产打包快。

先讲一个概念,热更新,动态模块热重载(HMR):允许一个模块 “热替换” 它自己,而不会影响页面其余部分。在实践中我们发现,即使采用了 HMR 模式,其热更新速度也会随着应用规模的增长而显著下降。在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失活[1](大多数时候只是模块本身),使得无论应用大小如何,HMR 始终能保持快速更新。

于是,Webpack使用传统的开发模式,在开发阶段需要将所有的代码打包成一个或多个bundle,然后在浏览器进行动态加载。

Vite采用了ES模块原生的开发模式,在开发阶段不需要将所有代码打包成一个bundle,而是以原生ES模块的方式直接在浏览器中加载和运行文件。这个特性使得Vite能够实现更快的冷启动和热更新,修改文件后无需刷新浏览器即可立即看到更新的效果。

同时,在打包生产代码时,webpack在生产环境下会将所有代码打包成一个或多个bundle,以便进行优化、压缩和代码拆分等操作,以提高性能和加载速度。 Vite在生产环境下,使用rollup,仍然保持了开发时的原生ES模块导入方式。

2、Vite 是基于 rollup 和 esbuild 实现的

上述一点优势,就是rollup带来的。rollup本身就是更好地支持treeshaking,基于ESM模块。比如,ESM都是顶部静态导入时,代码编译时,会先将全局的函数和对象记录下来,然后与import做对比,最后可去除无用的代码。

Esbuild:

Vite在开发环境下,就先用了esbuild预构建依赖,比如node_modules里一些包先转换成ESM后再确定依赖关系。并且生产环境下,vite也利用了esbuild的代码转换功能,相较于webpackbabel快了很多。

Esbuild之所以能这么快,主要原因: Go 语言开发,可以多线程打包,代码直接编译成机器码;相应的,webpack存在大量的 resolve、load、transform、parse 操作,而这些操作通常是通过 javascript 代码来执行的。而JS是单线程的,esbuild可以在Go环境的优势下,完成自己内部的transformbuild操作,速度会快很多。

需要注意的点:

Vite3中,### 为何不用 ESBuild 打包?

Vite 目前的插件 API 与使用 esbuild 作为打包器并不兼容。尽管 esbuild 速度更快,但 Vite 采用了 Rollup 灵活的插件 API 和基础建设,这对 Vite 在生态中的成功起到了重要作用。目前来看,我们认为 Rollup 提供了更好的性能与灵活性方面的权衡。

3、Vite 支持直接导入静态资源,如图片、字体等,无需经过Webpack的处理。

比如:webpack必须配合require或者loader来处理静态资源,而vite可以直接导入,并且会自动处理。

//webpack:
<img class="size" :src="require('@@/assets/img/radio_checked.png')" />
//vite:
import homeBg from 'src/assets/images/home/home_bg.png'
<img :src="homeBg" />

4、Vite更好的 CSS 支持:Vite 支持直接导入 CSS 文件,同时也支持 CSS 模块化。

webpack中,我们在文件内写style标签或引入css文件,是需要单独去处理的。比如:style-loader, css-loader

style-loader:

将 标签插入到 DOM 中。

css-loader:

解析通过 @import、url()、import/require() 这些方式引入的样式文件。

比如Vite中,build有个属性 ## build.cssCodeSplit,启用/禁用 CSS 代码拆分。当启用时,在异步 chunk 中导入的 CSS 将内联到异步 chunk 本身,并在其被加载时插入。如果禁用,整个项目中的所有 CSS 将被提取到一个 CSS 文件中。