vite这玩意相对于webpack来讲确实是打包速度更快,但是生态还没有webpack成熟,但是未来应该是有发展潜力的,所以这里来记录一下vite的相关知识。
官网:为什么选 Vite {#why-vite} | Vite中文网
一. vite和webpack的区别
为什么使用vite,其实最主要的原因就是打包速度更快。其原理是按需打包。
webpack支持多种导入格式,import和require,在开始编译之前会将他们都读一遍统一化为webpakc_require()。
而vite只支持es6的import,从而支持按需打包。
一个兼容性更强,一个更加快捷。
下图为区别示意。
二. 初体验
yarn init
yarn add vite -D
安装之后为了方便在json中配置script。
{
"name": "vite",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev":"vite"
},
"devDependencies": {
"vite": "^3.0.9"
}
}
三. vite预编译
vite在dev环境打包会将需要的模块预编译,例如将common.js转换为es6.
在pro环境打包,会全权交给rollup。
为了防止网络多包的情况,vite还会把多包引用集成到一个js中。
四. vite 配置
1.基本配置
目录结构:
vite.config.js
这里使用defineConfig 是为了获得语法提示,内部是做了ts。
这里主要是涉及到了环境变量的使用。
import { defineConfig, loadEnv } from "vite"
import viteBaseConfig from "./vite/vite.base.config"
import viteDevConfig from "./vite/vite.dev.config"
import viteProdConfig from "./vite/vite.prod.config"
//策略模式
const envResolver = {
"build": () => ({ ...viteBaseConfig, ...viteDevConfig }),
"serve": () => ({ ...viteBaseConfig, ...viteProdConfig })
}
//commond根据我们的指令会变成对应的值
export default defineConfig(({ command,mode }) => {
//cwd用于返回node的工作进程 第三个参数默认值为.env 肯定解析
//mode 为development 或 production
//当mode为 xxx时会读取env.[xxx]进行解析,并且合并原来的env
//vite会将环境变量注入到import.meta.eny中 这里我在index.js中打印
//但是vite会先做一层拦截 防止隐私变量被直接注入,不是以vite开头就不会被直接注入
//想要更改前缀可以在envPrefix配置
const env=loadEnv(mode,process.cwd(),"")
console.log(env,"@@@");
return envResolver[command]()
})
修改前缀实例:在vite.base.config.js
import {defineConfig} from "vite"
export default defineConfig({
optimizeDeps:{
exclude:[]
}
})
2. vite原理
实现简单的vite开发服务器
略
3. vite对css以及css模块化的处理
vite天生支持对css的处理。
原理就是vite读取入口文件时,会读到引用的css,将其添加到html的style标签里。
使用css模块化处理css样式冲突。
使用方法
import add from "./count";
import "./style/base.css";
import demo1 from "./style/demo1.module.css"
console.log("index");
console.log(add(1, 3, 6, 2));
console.log(demo1);
let demo=document.createElement("div")
demo.className=demo1.demo1
document.body.appendChild(demo)
效果
原理就是,凡是module.css,再塞到style里之前,将类名使用类名+hash替换,同时创建一个映射对象。
当使用less或者scss等使用的css预处理时。同样支持上面的模块化。
以less为例,安装less预处理。
yarn add less
后面操作一致。
css配置流程
import { defineConfig } from "vite"
export default defineConfig({
optimizeDeps: {
exclude: []
},
css: {
//最终丢给postcss
modules: {
//用来配置css模块化映射对象是驼峰还是横线
localsConvention: "camelCase",
//配置module.css是模块还是全局 默认就是我们一开始的local
//设置全局的化就不会加hash值
scopeBehaviour: "local",
//生成类名格式 下面是示例 也可以使用函数的形式自定义
generateScopedName: "[name]_[local]_[hash:5]",
//hash前缀
// hashPrefix:"Ts",
//不想参与模块化的路径 纯没用
globalModulePaths:[]
}
}
})
配置css预处理器的全局参数和sourcemap
import { defineConfig } from "vite"
export default defineConfig({
optimizeDeps: {
exclude: []
},
css: {
//最终丢给postcss
modules: {
//用来配置css模块化映射对象是驼峰还是横线
localsConvention: "camelCase",
//配置module.css是模块还是全局 默认就是我们一开始的local
//设置全局的化就不会加hash值
scopeBehaviour: "local",
//生成类名格式 下面是示例 也可以使用函数的形式自定义
generateScopedName: "[name]_[local]_[hash:5]",
//hash前缀
// hashPrefix:"Ts",
//不想参与模块化的路径 纯没用
globalModulePaths: []
},
//预处理器
preprocessorOptions: {
less: {
math:"always",
globalVars:{
//全局变量
mainColor:"pink"
}
},
scss: {},
},
//css 的 sourcemap
devSourcemap:true
}
})
vite使用postcss
安装postcss预环境
npm i postcss-preset-env -D
在vite中使用
postcss: {
plugins: [postcssPresetEnv()]
},
例子
编译前
.demo1{
/* 设置宽度为30% 最小不小于100px 最大不大于200px */
width: clamp(100px,30%,200px);
height: 100px;
background-color: red;
user-select: none;
}
编译后效果
4. vite对静态资源的处理
路径别名
resolve: {
//路径别名
alias: {
"@": path.resolve(__dirname)
}
},
vite在生产环境对静态资源的处理。
配置rollup构建策略
build: {
rollupOptions: {
//配置rollup打包构建策略
output: {
//控制输出
assetFileNames: "[hash].[name].[ext]"
},
},
assetsInlineLimit: 4096000, //4000kb小于都打包为base64 大于就是静态
// outDir: "", //输出目录
assetsDir: "static", //静态资源目录
}
5. vite插件使用
(1)自动别名插件
GitHub - Subwaytime/vite-aliases: Alias auto generation for Vite
生成例子
使用就完全按照文档就好。
(2)动态修改html title
其实合webpack-html-plugin功能一样,但是大部分vite内部已经配置好了比如设置template。
https://github.com/vbenjs/vite-plugin-html
yarn add vite-plugin-html -D
使用也是对应文档即可。
(3)vite-plugin-mock
模拟数据
我用不上就不装了
(4)总结
插件使用
之前使用的插件
plugins: [
ViteAliases(),
createHtmlPlugin({
inject: {
data: {
title: "666"
}
}
})
],
plugin本身是附带很多api的
vite和vue差不多 也有插件中的生命周期钩子。
6. vite和ts
vite对于ts天生支持。
让ts错误展示在控制台
用来阻塞开发
使用 vite-plugin-checker
Getting Started | vite-plugin-checker
注意这个插件依赖于ts 所以要按照ts
npm i typescript
创建tsconfig.json
效果
不管是打包还是开发过程都会直接语法报错,阻塞过程。
使用三斜线指令进行环境变量提示
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_URL: string
}
这样就可以在其他地方的import.meta.env处出现属性提示。(在ts文件有效)
在ts里使用第三方包按模块引入可能会没有提示,这个就是按上面警告按照对应的ts类型提示就行。
7. vite性能优化
(1)开发方面的构建速度优化。
分包策略
分包是为了将不会经常变动的代码进行单独打包,为了防止浏览器不读缓存频繁请求。
例如我们不希望多次读取node_modules的文件
build: {
rollupOptions: {
//配置rollup打包构建策略
output: {
//控制输出
assetFileNames: "[hash].[name].[ext]",
//配置分包
manualChunks:(id)=>{
if(id.includes("node_modules")){
return "vendor"
}
}
},
},
assetsInlineLimit: 4096000, //4000kb小于都打包为base64 大于就是静态
// outDir: "", //输出目录
assetsDir: "static", //静态资源目录
emptyOutDir: true, //清除输出目录
minify:false,//是否压缩代码
}
那么最后生成的文件就会是这样
(2)页面性能指标 fcp首屏渲染时间 lcp最大元素时长。