Vite学习(一)

108 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

项目初始化

pnpm create vite

根据提示创建项目

项目入口加载

.
├── index.html
├── package.json
├── pnpm-lock.yaml
├── src
│   ├── App.css
│   ├── App.tsx
│   ├── favicon.svg
│   ├── index.css
│   ├── logo.svg
│   ├── main.tsx
│   └── vite-env.d.ts
├── tsconfig.json
└── vite.config.ts

项目入口就是这个index.html

image-20220424113601811.png 现代浏览器原生支持了ES模块规范,所以原生的ES语法可以直接在浏览器里执行,只需要在script中设置type=“module”,其中src指向了/src.main.tsx,vite的dev server会接受这个请求,进行中间处理,最后将处理的结果返回给浏览器

再看main.tsx

image-20220424113926974.png

浏览器它认不得tsx,也没法import css文件,之所以页面能够按照我们的期望展示,是因为vite dev server的中间处理,将tsx,import css

转换为浏览器认得的内容。在vite中,一个import代表一个http请求,vite dev server会读取本地文件,返回浏览器可以解析的代码,当浏览器解析道新的import请求,又会加载新的请求。

如图为main.tsx index.css经过vite dev server转化的结果

image-20220424114441123的副本.png

image-20220424114525642.png

Vite 所倡导的no-bundle理念的真正含义: 利用浏览器原生 ES 模块的支持,实现开发阶段的 Dev Server,进行模块的按需加载,而不是先整体打包再进行加载。 Vite 所倡导的no-bundle理念的真正含义: 利用浏览器原生 ES 模块的支持,实现开发阶段的 Dev Server,进行模块的按需加载,而不是先整体打包再进行加载

初步配置

实际项目中,配置文件一般使用vite.config.ts作为配置文件

image-20220424114824101.png

通过plugin数组引入react插件,提供react编译和热更新

生产环境

dev阶段,vite利用dev server实现了不打包,在打包阶段,vite会基于rollup。

image-20220424115128730.png tsc是ts的类型检查,vite并没有集成ts检查,所以借助tsc在打包前进行ts类型检查,来提高代码的健壮性。

通过tsconfig.json进行配置

image-20220424115317058.png

依赖预构建

vite是一个提倡bundleless的构建工具,但不打包是针对源代码来的,对于依赖,即node_modules,vite还是选择打包,使用速度极快的esbuild来完成这一过程,依赖编译速度秒级。

为什么要预构建

  • vite是基于浏览器原生es模块实现的dev server,无论是src还是node_modules里的代码,都需要符合esm,才能运行。然而第三方用不用esm,我们管不着,比如react他就用commonjs,所以vite要把他转换esm规范。
  • import请求代表一个http请求,chrome对同一个浏览器的请求有6个的并发限制,一个模块可能会imoprt 非常非常多的模块,http请求会居多,页面加载会很慢,所以vite会把这些第三方库的文件合并到一起,来减少http请求

这两件事都是通过esbuild来完成的(基于go开发),所以非常非常快。

Vite 1.x 使用了 Rollup 来进行依赖预构建,在 2.x 版本将 Rollup 换成了 Esbuild,编译速度提升了[近 100 倍],那为什么vite不用esbuild来进行打包呢?

其实也想用,但是 esbuild 目前对生产包支持不够健壮,很多配置无法通过 esbuild 实现。所以目前而言,Rollup 是一个好选择,虽然远比 esbuild 慢。

另外,可以用 esbuild 作为压缩器,替代 terser,详见 build.minify,(vitejs.dev/config/#bui…)这样会更快,但是包的体积可能会有 5% - 10% 左右的增长,看用户取舍。

怎样开启预构建

pnpm create vite 脚手架运行时会自动构建

http设置了cache-control:max-age 一年,强缓存做了一年

image-20220425144848169.png 手动开启:

  1. 删除node_modules/.vite目录。
  2. 在 Vite 配置文件中,将server.force设为true
  3. 命令行执行npx vite --force或者npx vite optimize

Vite 项目的启动可以分为两步,第一步是依赖预构建,第二步才是 Dev Server 的启动,npx vite optimize相比于其它的方案,仅仅完成第一步的功能。

自定义配置

vite将预构建的相关配置都集中optimizeDeps属性上

entries

通过这个参数可以自定义预构建的入口文件,项目第一次启动,vite会默认抓取项目中的所有html文件,工具入口文件来扫描第三方依赖,如果扫描html满足不了需求,当项目入口为vue,就需要修改entries参数

// vite.config.ts
{
  optimizeDeps: {
    // 为一个字符串数组
    entries: ["./src/main.vue"];
  }
}

不止vue和html文件,任何可能import的文件,vite都能解析

include

include决定了强制预构建的依赖项

// vite.config.ts
optimizeDeps: {
  // 配置为一个字符串数组,将 `lodash-es``vue`两个包强制进行预构建
  include: ["lodash-es", "vue"];
}
​

即然vite能够通过entries入口来扫描第三方依赖,为什么还要include?

因为vite的扫描并不是完全可靠的,所以需要联合include

在什么场景下会不可靠?

动态import

const comp=(bar)=>import(`XXXX${bar}`)
comp(XXX)

这个就无法在预购见阶段被扫出来,运行时遇见了这个,vite就发现了新的依赖,随之就会进行依赖预先构建,页面会被刷新,也可以叫做二次预构建。

配置include可以避免二次预构建

手动exclude

通过exclude可以让某些依赖从预构建中移除,但是这个依赖可能有依赖,且这个依赖不具有ESM格式,所以就需要通过include来强制预购建这个依赖,让他具有ESM格式