Vite入门篇:学会它,一起提升开发幸福感

相信大部分兄弟都体验过 Vite 了,知道它很快。但你知道它为什么快,相比 Webpack 有哪些不同吗?今天咱们就来全面了解一下 Vite ,尤其适合新手兄弟。一起学起来吧!

成都创新互联公司专业为企业提供广南网站建设、广南做网站、广南网站设计、广南网站制作等企业网站建设、网页设计与制作、广南企业网站模板建站服务,十余年广南做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。

什么是构建工具

很多人对构建工具没有什么概念,只知道是用来打包的。那么到底什么是构建工具呢?

大家都知道浏览器只支持 Html、CSS、JavaScript,但一个企业级项目可能会用到各种各样的前端技术,如 Less、Sass、TS、Vue组件、语法降级、体积优化等,这时候我们就需要相应的工具去处理这些内容:

  • 使用 less-loader/sass-loader处理 less / sass。
  • 使用 tsc将 typescript 转换为 javascript。
  • 使用 vue-complier将 vue 组件模板转换为 render 函数。
  • 使用 babel将 es 的新语法转换为旧版浏览器认识的语法。
  • 使用 uglifyjs将我们的代码压缩成体积更小的文件。

我们可以手动把代码挨个处理一遍,但这样效率非常低,当我们稍微修改一点代码,这个流程又要重新走一遍,非常麻烦。有个神奇的东西,可以把以上工具集成到一起,整个流程交给它自动处理。而且当代码发生变化时,自动帮我们重新走一遍,这个东西就叫做构建工具。当然构建工具做的事情远不止于此,比如:

  1. 模块化开发支持:支持直接从 node_modules 里引入代码。
  2. 提高项目性能:压缩文件、代码分割。
  3. 优化开发体验:热更新、跨域问题。
  4. ......

构建工具减轻了我们的心智负担,让我们不用关心我们写的代码如何在浏览器运行,只需要关心代码怎么写就可以了。市面上主流的构建工具有 Webpack、Vite、esbuild、Rollup、Parcel,以及最近刚出的 turbopack ,但目前最流行的依然是 Webpack 和 Vite 。

Vite 相较于 Webpack 的优势

当项目体积越来越庞大时,构建工具需要处理的代码量呈指数级增长,包含数千个模块的项目也是相当普遍。类似 Webpack 的构建工具就会遇到性能瓶颈:通常需要很长时间,甚至几分钟项目才能启动起来。热更新(HMR)也可能需几秒,甚至十几秒。不知道大家目前的项目怎么样,反正我们公司稍微大一点的 Vue2 项目是真的慢,等的捉急。这种情况已经很大程度影响到了我们的开发效率和幸福感。

Webpack 有没有办法进行优化呢?很难。Webpack 先递归分析各模块依赖关系-构建依赖图谱,然后进行打包,再启动本地服务器。而且 Webpack 支持多种模块化规范,比如 CommonJS 、ES-Module ,一开始就要统一模块化代码,将所有的依赖全部处理一遍。整个流程如下图:

即使使用按需加载,也有一系列工作需要做,所以 Webpack 基本没有优化空间。

那么 Vite 为什么能解决这个问题呢?

  1. 底层语言。Vite 使用 esbuild预构建依赖。esbuild使用 Go 编写,比用 JS 编写的打包器预构建依赖快 10-100 倍。
  2. 先启动服务器,再按需请求模块并编译。Vite 利用的是现代浏览器本身支持 ES-Module这个特性,直接向依赖的模块发出请求。Vite 启动时不需要分析模块之间的依赖关系,也不用打包,项目越大,优势越明显。

这个是 Vite 的启动过程:

这样大家应该看得出来 Vite 为什么快了吧!

依赖预构建

上面提到了依赖预构建,可能很多兄弟对这个不太理解,这里我也来讲一下。现代浏览器已经支持 ES-Module ,但导入模块只能用相对路径或绝对路径,直接使用模块名称的方式是行不通的:

// main.js
// 假设我们已经安装了 lodash 模块
import a from './a.js' // 支持
import b from '/b.js' // 支持
import _ from 'lodash' // 报错

依赖预构建就可以很好的解决这个问题。Vite 首先会找到依赖的模块,然后调用 esbuild,将 CommonJS 等其他规范的代码转换成 ES-Module 规范,然后把它放在 node_modules/.vite/deps 目录下,接着再修改相应的引入路径。

由于浏览器是通过 HTTP 来请求模块文件的,一旦模块的依赖关系比较多的话,就会发起很多个网络请求。例如,lodash-es 内置模块超过 600 个,它们之前相互导入。当我们执行以下代码时,浏览器会同时发出 600 多个 HTTP 请求!大量的请求造成网络堵塞,导致页面的加载非常的慢。

import { debounce } from 'lodash-es'

这时候还得靠依赖预构建,预构建将 lodash-es 整体转换为一个模块,这样我们就只需要发起一个 HTTP 请求了!

总结一下,依赖预构建为我们解决了以下三个头痛的问题:

  1. 兼容其他规范。不同的第三方依赖包会有不同的导出格式(如 CommonJS规范)。
  2. 重写导入路径。例如 lodash或重写为/node_modules/.vite/deps/lodash.js?v=fef37e66,以便浏览器能够正确导入。
  3. 网络性能优化。Vite 会将内部有众多依赖关系的 ES-Module模块转换为一个模块,提高页面的加载性能。

对不同内容的处理

学习一项技术,最好的方式是单独使用它。抛开脚手架工具,Vite 使用起来也非常的简单,直接在项目中安装 vite ,给个配置就可以了。当然不给也可以,Vite 会使用内置的默认配置:

npm install vite -D
// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
// ...
})

为了方便使用,可以在 package.json 添加启动和打包命令。

"scripts": {
"dev": "vite",
"build": "vite build"
}

然后在根目录下新建一个 index.html,npm run dev 项目就跑起来了!

对 CSS 的处理

「CSS Modules」

在不同模块中定义相同类名,会导致样式被覆盖,这时候就要用到 CSS module 。以 .module.css 结尾的文件都会被认为是一个 CSS modules 文件。导入这样的文件会返回一个相应的对象:

/* example.module.css */
.red {
color: red;
}
// main.js
import example from './example.module.css'
console.log(example) // { red: '_red_te83z_1' }
document.getElementById('foo').className = example.red

「CSS 预处理器」

Vite 同时提供了对 .scss,.sass,.less,.styl 和 .stylus 文件的内置支持,仅需安装相应的预处理器就可以了:

# .less
npm install less -D

# .scss and .sass
npm install sass -D

# .styl and .stylus
npm install stylus -D

感觉这块要比 Webpack 简单的多,Webpack 需要给不同类型的文件配置不同的 loader 去处理,而 Vite 内部直接帮我们配置好了。如果使用的是 Vue 单文件组件,可以通过