诞生:Vite 封装构建工具 rollup,v1版本随Vue3正式版一起发布,为vue服务的工具。
进化:很快就发布了V2版本,变成了独立于框架的工具。
优势:
上手简单,开发效率高
社区活跃 (兼容rollup插件)
- 没有多余的配置
Webpack:
cra项目需要eject;
vue-cli修改配置需要了解configureWebpack和chainWebpack;
Vite:
插件模式:有很多已经内置在Vite里,天然支持post-css、pre-processors、ts集成等功能;
引入插件只需在plugins引入,不需要像webpack那样配置rules;
- 快
解决了当前主流打包工具的痛点,项目越大'快'得越明显。
从入口文件开始,把所有文件编译打包成一个Bundle,打包过程非常慢,项目越大需打包的文件越多,耗时会随项目的复杂性线性增加。
Vite启动的时候,不需要去做编译(只是做了些预编译),把需要提前编译的文件编译好,真正访问它的入口(index.html文件)的时候,通过
<script type="module" src="./src/index.jsx"></script>
引入再去编译这个文件,编译过程加载文件里面的依赖实时的编译,所以首次打开项目只需要加载首页用到的依赖不需要把整个应用加载下来,节省了很多加载的时间和编译的时间。
Esbuild
进行文件编译,速度比webpack/rollup......快10~100倍
Esbuild
Vite使用
支持jsx语法
默认支持sfc的写法,不支持jsx。
兼容jsx:安装 @vitejs/plugin-vue-jsx 插件,并使用。
post-css
Vite 天然支持post-css,只需要在根目录创建postcss.config.js
配置文件安装需要使用的plugins。
css-modules
编译css类名,使名字无意义,长度收缩,去重。
民命为xxx.module.css
就会自动识别为css-modules文件
css pre-processors
Vite 天然支持预编译样式,只需要安装预编译的工具:
例如安装less: yarn add less
,就能写less的语法了
ts集成
Vite 天然支持,只需要安装ts: yarn add typescript
。Vite 只编译,不校验。
增加ts检验:
添加 tsconfig.json
配置,这也是初始化vue项目选择ts默认生成的配置文件:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx ", "src/**/*.vue"]
}
通过使用tsc工具做校验:tsc --noEmit
(只校验,不输出文件)
运行 tsc --noEmit
命令就会展示ts的语法错误
到这里能支持普通ts文件的校验
vue-tsc for SFC
vite原生不支持.vue
文件里ts语法的校验,需要借助 vue-tsc
- 添加 vue-tsc
yarn add vue-tsc
vue-tsc --noEmit
(对ts文件和vue文件中的ts编译和校验,不输出文件)
增加命令配置:
// package.json
// 在build之前校验
"scripts": {
"build": "vue-tsc --noEmit && vite build",
}
isolatedModules
开启isolatedModules检测:
// tsconfig.json
{
"compilerOptions": {
...,
"isolatedModules": true
}
}
开启isolatedModules遇到以下三种情形,在编码阶段就会有错误的提示,配合语法检测(tsc/vue-tsc)在打包前拦截Vite不支持的语法。
- Exports of Non-Value Identifiers
Vite 提供ts的编译是只编译语法针对单文件,但对于ts来说它是可以关联不同文件间的模块信息的。
A文件export一个类型 B文件里import这个类型可以直接用,但Vite提供的编译没有ts这么强大,只编译单文件中ts的语法变成js,不会在编译的时候读其他文件的内容,导致有些ts的功能没有办法使用:
// a.ts
export interface IA {
...
}
// b.ts
import { IA } from './a.ts';
...
export { IA };
上面代码编译时会报错:
Vite对ts的编译支持使得在b文件里不存在IA这个interface的类型,把isolatedModules开启会有相应提示:
-
Non-Module Files
开启isolatedModules后,会强制在每个ts文件中有import/export,才会认定这个文件里有模块
References to const enum members
在ts文件里定义enum类型常量,ts文件在编译成js的过程中使用到该常量的地方会被替换成enum中的value,但Vite里使用到esbuild提供的ts语法编译不支持这种语法,文件里的enum会被直接去掉,但还是会保留enum的引用导致报错
开启isolatedModules也会收到编译器的提示:
开启isolatedModules之后,配合tsc语法检测会发现多了很多错误:
是因为 vue-tsc 会将node_modules的代码包含做检测,vue-tsc的github里也有很多issue提到这个问题:
How does vue-tsc skip node_modules?
How to ignore node_modules package checks ?
Why verify node_modules
❌ 但目前没有办法解决,问题不大,自行忽略node_modules相关错误~
按需引入style插件:
npm i vite-plugin-style-import consola -D
- vite-plugin-style-import@2 仅支持node14+
- 注意vite-plugin-style-import的版本,用法不同(推荐用2.x版本,代码更简洁):
- 官方封装了很多resolve,涵盖大多数主流ui库:
-
1.x版本使用方式:
import styleImport from 'vite-plugin-style-import'; export default defineConfig(({ command, mode }) => ({ plugins: [ vue(), styleImport({ libs: [ { libraryName: 'ant-design-vue', esModule: true, resolveStyle: (name) => { return `ant-design-vue/es/${name}/style/css`; }, }, ], }), ], }));
2.x版本使用方式:
```
import { createStyleImportPlugin, AndDesignVueResolve } from 'vite-plugin-style-import';
export default defineConfig(({ command, mode }) => ({
plugins: [
vue(),
createStyleImportPlugin({
resolves: [AndDesignVueResolve()],
}),
],
}));
```
插件
vite的插件可以看成是受限制的rollup插件,支持部分Hooks。
Vite支持的内部变量
引入type:
# tsconfig.json
// 配置types开启
{
"compilerOptions": {
...,
"types": ["vitejs/client"]
}
}
引入type前:
引入type后:编译器会提示内部变量,每个变量都会有其属性和类型提示
client types
Asset imports: 引入静态文件的返回类型
帮助ts认识import文件返回值的类型:
例如import png文件,会返回string类型。-
types
-
url: 返回文件的url
import a from './a?url'; console.log(a); // 文件路径: '.../a.ts'
-
raw: 返回文件的内容(string类型)
# a.ts export interface IA { a: string; } # b.ts import a from './a?raw'; console.log(a); // console info: // export interface IA { // a: string; // }
-
worker/worker inline:
web worker: 更好性能的构建应用的工具,js是单线程的,如果计算量大的代码和渲染进程并行,可能会阻塞渲染造成卡顿,把计算量很大需要耗长时间的任务放到web worker就不会影响页面渲染。
Vite使我们引入web worker 变得非常简单:// webWorker.ts var count = 0; (function timedCount() { count++; postMessage(count); setTimeout(timedCount, 500); })(); // 在main.ts中引入worker import Worker from './webWorker?worker'; const worker = new Worker(); // 接收worker传递的内容 worker.onmessage = (e) => { console.log(e); };
-
JSON
import pkg from '../package.json'; console.log(pkg);
引入JSON Vite处理返回parse过后的对象:
Web Assembly
浏览器可运行的二进制内容
-
env:环境变量
HMR api:.hot的配置