Vite
1、特点
1.开发时效率极高
2.开箱即用, 功能完备
3.社区丰富, 兼容rollup的特性
4.超高速的热重载
5.预设应用和类库打包模式, 减少了我们很多需要自己配置的内容
6.与前端类库无关的工具
2、什么是vite
是构建工具的高阶封装
3、目标
1.使用简单
2.快
3.便于扩展
4、区别
1.High Level API
2.不包含自己的编译能力
3.完全基于ESM加载的方式来进行开发的
4.减少了很多配置的工作
5、创建vue3项目
使用vite创建项目
npm init @vitejs/app
使用vite指定模板创建项目
npm init @vitejs/app my-vue-app --template vue 【npm 6.x】
npm init @vitejs/app my-vue-app – --template vue 【npm 7.x】
import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
import vueJsx from “@vitejs/plugin-vue-jsx"
export default defineConfig({
plugins: [vue(), vueJsx()],
})
6、创建vue2项目
自己通过脚手架建立一个空的项目
npm install vite-plugin-vue2
import { createVuePlugin } from “vite-plugin-vue2"
export default {
plugins: [createVuePlugin()],
}
通过现有的模板进行创建
github: github.com/matt-auckland/vite-vue2-starter
7、创建react项目
FastRefresh
解决了很多react热加载插件无法解决的问题
速度快
支持局部更新
npm init @vitejs/app my-react-app --template react
创建项目时vite会自动安装@vitejs/plugin-react-refresh插件
import { defineConfig } from 'vite’
import reactRefresh from ‘@vitejs/plugin-react-refresh’
export default defineConfig({
plugins: [reactRefresh()]
})
8、vite中使用css
// vite.config.js
import { defineConfig } from “vite"
import vue from “@vitejs/plugin-vue"
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
“@styles”: “/src/styles”,
},
},
})
css变量、引入css以及console的使用
@import url(”@styles/other.css”);
:root {
–main-bg-color: blue;
}
.root {
// @console.error hello root
color: var(–main-bg-color);
}
// postcss.config.js
module.exports = {
plugins: [require(”@postcss-plugins/console”)]
}
css module的使用
import { defineComponent } from 'vue’
import classes from '@styles/test.module.css’
// moduleClass为样式表中的样式类
export default defineComponent({
setup() {
return () => {
return <div class={root ${classes.moduleClass}
}>Hello Vue3 Jsx;
}
}
})
vite天生支持less等预编译工具, 只需要npm相应预编译即可
9、vite中使用typeScript
只编译, 不校验
export interface A {
name: string;
age: Number;
}
export const a: A = {
name: “Jokcy”,
age: ‘18’ // 这时候如果没有特殊配置的话页面还是可以正常编译, 但是没有报错提示
}
tsc --noEmit && vue-tsc --noEmit
“scripts”: {
“build”: "vue-tsc --noEmit && tsc --noEmit && vite build"
},
“dependencies”: {
“typescript”: “^4.3.4”,
“vue-tsc”: "^0.1.7"
}
tsconfig
{
“compilerOptions”: {
“target”: “esnext”,
“module”: “esnext”,
“moduleResolution”: “node”,
“strict”: true,
“jsx”: “preserve”,
“sourceMap”: true,
“resolveJsonModule”: true,
“esModuleInterop”: true,
“lib”: [“esnext”, “dom”],
“types”: [“vite/client”], // * 引入模块必须配置的项
“isolatedModules”: true // * 配置独立模块导出
},
“include”: [“src//*.ts", "src//.d.ts", "src/**/.tsx”, "src//*.vue"]
}
10、vite中处理静态资源的方法
types url, raw, worker
import test from “./test?url” // 仅仅返回的是路径
import test from “./test?raw” // 把代码以字符串的形式展示出来
console.log(test)
// main.js
import Worker from './worker?worker’
const worker = new Worker()
worker.onmessage = (e) => {
console.log(e) // 开启一个线程, 执行一部分代码, 定时监听
}
resolve
resolve: {
alias: {
“@styles”: "/src/styles"
}
}
// 使用
import “@styles/test.less”
11、vite中集成eslint && pritter
依赖
“devDependencies”: {
“eslint”: “^7.29.0”,
“eslint-config-standard”: “^16.0.3”,
“eslint-plugin-import”: “^2.23.4”,
“eslint-plugin-node”: “^11.1.0”,
“eslint-plugin-promise”: "^5.1.0"
}
根目录新建.eslintrc.js文件
module.exports = {
extends: ‘standard’,
globals: {
postMessage: true
},
rules: {
‘space-before-function-paren’: 'off’
}
}
自动格式化 新建.prettierrc文件, vscode安装prettier-code插件
// vscode设置勾选 format on save, 保存时自动格式化
{
“semi”: false,
“singleQuote”: true
}
命令校验是否符合规则
“scripts”: {
“lint”: "eslint --ext js src/"
}
12、vite中的env变量
使用
import.meta.env
/
- BASE_URL 主路径
- DEV 是否是开发环境
- MODE 环境变量
- PROD 是否是生产环境
- SSR 是否是服务端渲染
/
different envs
.env
.env.test
.env.development
VITE_TITLE = Jerry // 必须要加前缀VITE
mode 改变编译环境
“scripts”: {
“dev”: "vite --mode test"
}
13、vite中的HMR热更新功能
如果使用vite 空模板进行创建项目, 则默认不会集成HMR功能, 需要自己实现
// main.js
export function render () {
…
}
render()
if (import.meta.hot) {
// newModule 整个文件module的更新
// 如果只执行render, 则不会执行, 原因与闭包原理有关, 会执行老的render
import.meta.hot.accept((newModule) => {
newModule.render()
})
}
那是如何实现的呢
是使用websocket进行的, 会对main.js进行第二次请求
{ type: ‘connected’ }
{ type: ‘update’, … … }
14、vite glob-import 批量导入文件
const globModules = import.meta.glob(’./glob/’)
Object.entries(globModules).forEach(([k, v]) => {
v().then(m => console.log(k + ‘:’ + m.default))
})
globEager是已经编译好了代码, 不需要再异步获取, 直接用即可
const globModules = import.meta.globEager(’./glob/’)
还可以按照不同的文件类型去获取
const globModules = import.meta.globEager(’./glob/.js’)
const globModules = import.meta.globEager(’./glob/.json’)
…
15、预编译优化
什么是预编译
是vite编译的代码的时候会在node_modules里面产生一个缓存包.vite, 后面会读取这个缓存, 所以速度会比较快
如果不是ESModule的依赖可以手动配置
optimizeDeps: {
exclude: [‘react’]
}
16、非Node服务中集成vite
// vite.config.js
import { defineConfig } from 'vite’
import vue from '@vitejs/plugin-vue’
export default defineConfig({
plugins: [vue()],
build: {
manifest: true
}
})
17、Node服务中集成vite
const express = require(‘express’)
const fs = require(‘fs’)
const app = express()
const { createServer: createViteServer } =require(‘vite’)
createViteServer({
server: {
middlewareMode: ‘ssr’
}
}).then(vite => {
app.use(vite.middlewares) // 可以通过这个使用vite的中间件
app.get(’’, async (req, res) => {
let template = fs.readFileSync(‘index.html’, ‘utf-8’)
template = vite.transformIndexHtml(req.url, template)
const { render } = await vite.ssrLoadModule(’/src/entry.js’)
const html = render(req.url)
const responseHtml = template.replace(’ ’)
res.set(‘content-type’, ‘text/html’)
res.send(responseHtml)
})
app.listen(4000)
})
// 入口文件
import ReactDOMServer from 'react-dom/server’
import { StaticRouter } from 'react-router-dom’
import App from './App’
export function render (url, context) {
return ReactDOMServer.renderToString(
<StaticRouter location={ url } context={ context }>
)
}