因为 vite
是使用原生浏览器的模块化功能,内部不能使用 node
,也就没有了 require
方法。本小节主要介绍 vite
中常见的使用,包括 css
、ts
、env
环境变量,import.meta
等功能。
CSS 处理
基本使用
src
目录下新增 index.css
@import url('@styles/others.css')
// 对于 HTML 来说, :root 表示<html>元素,除了优先级更高之外,与 html 选择器相同
:root {
--bg-color: pink;
}
body {
background-color: var(--bg-color);
}
vite
推荐 css variable
配置路径别名
代码语言:javascript复制// vite.config.js
export default defineConfig({
...
resolve: {
alias: {
'@styles': "/src/styles"
}
}
})
使用 postcss
vite
内部已经集成了 postcss
,想使用的话直接在根目录下新建 postcss.config.js
module.exports = {
plugins: [
require('@postcss-plugins/console') // 使用 postcss 插件
]
}
使用(记得修改配置文件,要重新启动项目)
代码语言:css复制body {
background-color: var(--main-bg-color);
@console.warn hello postcss // 会在命令行打印,不是浏览器控制台
}
css modules
css modules
可以让你的 css
像模块一样使用,内部的类名都变成了对象属性, vite
中使用也很方便,文件命名以 xxx.module.css
形式。css modules学习
// styles/test.module.css
.moduleTest {
color: red;
}
vue
文件中使用
<script setup>
import classModule from '@styles/test.module.css'
console.log(classModule) // 对象形式
</script>
变量形式使用
<template>
<p :class="classModule.moduleTest">ppppppppppp</p>
</template>
预处理器
vite
好处是不用配置 loader
,很多已经内置了。这里以 less
为例,yarn add less
// styles/test.less
@bgColor: red;
.root {
background-color: @bgColor;
}
vite
中 css
的使用就介绍到这里,有疑问的话欢迎小伙伴留言讨论。
ts 使用
需要全局安装 tsc
,需要在根路径下创建 tsconfig.js
vite
对 ts
的态度是,只编译,不校验
,只是把 ts
处理成 js
供浏览器使用,但是 ts
的语法无法做校验处理。我们更多依赖的是 vscode
和 Volar
插件,打包校验的话可以配置
"scripts": {
"build": "tsc --noEmit && vite build"
}
因为 ts
对 vue
文件不生效,增加 ts
对 vue
文件的支持,yarn add vue-tsc
,修改配置
"scripts": {
"build": "vue-tsc --noEmit && tsc --noEmit && vite build"
}
我们可以配置 "isolatedModules": true
, 因为 vite
开发环境不能正确校验 ts
,
isolatedModules 作用
- exports of Non-Value Identifiers// a.ts export interface Test{} // b.ts import { Test } from './a' export { Test } // 报错 未定义就导出每个文件必须是个模块,要不 import,要不 export 导出const enum Test { a = 0, b = 1 } let test = { age: Test.a,// 会报错,这里没有 Test 枚举,导致报错 }
- Non-Modules Files
- References to const enum members
我们知道 vite
中无法使用 node
语法,访问路径,环境变量需要使用 import.meta
,我们需要在 tsconfig.js
中进行相关的配置
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": [
"ESNext",
"DOM"
],
"types": [
"vite/client" // 配合 vite 使用 import.meta.xxx
],
"isolatedModules": true,
},
"include": [ // 校验哪里的ts文件
"src/**/*.ts",
"src/**/*.d.ts"
]
}
静态文件处理
基本使用
代码语言:txt复制<script setup>
import logo from './assets/logo.png'
</script>
<template>
<img :src="logo" alt="">
</template>
自带的 types
我们在引入的文件后面拼接 url
或 raw
,会打印文件的路径和文件的内容
import test from './test?url'
console.log(test, 11)
import test1 from './test?raw'
console.log(test1, 22)
web worker
vite
中也为我们内置了 web worker
,我们可以单独开个线程处耗时计算
// main.js
import Worker from './worker?worker'
const worker = new Worker()
worker.onmessage = function (e) {
console.log(e)
}
代码语言:txt复制let i = 0
function timedCount() {
i = 1
postMessage(i)
setTimeout(timedCount, 1000)
}
timedCount()
处理 json 文件
vite
帮我们自动处理了 json
格式
import {version} from '../package.json'
console.log(version)
webassembly
我们需要用其他语言生成 wasm
文件,这里使用 assemblyscript
,安装 npm i assemblyscript
新建 assembly.ts
export function fib(n: i32): i32 {
var a = 0, b = 1
if (n > 0) {
while (--n) {
let t = a b
a = b
b = t
}
return b
}
return a
}
执行 ./node_modules/.bin/asc assembly --binaryFile fib.wasm
main.js
代码语言:txt复制import init from './fib.wasm'
init().then(m => {
console.log(m.fib(10)) // 55
})
集成 eslint pritter
eslint
根目录新建 .eslintrc.js
,安装 npm i eslint-config-standard eslint-plugin-import eslint-plugin-promise eslint-plugin-node -D
module.exports = {
extends: 'standard',
globals: {
代码语言:txt复制postMessage: true, // 防止全局未定义 报错
},
}
代码语言:txt复制### pritter
根目录新建 `.prettierrc` 文件,
{
"semi": false, // 无分号
"singleQuote": true, // 单引号
}
代码语言:txt复制![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2f64f144e3fd4524a6f9d77580876f4c~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7d3d3b8f3b4842b39bcdd1fa9ee2aac3~tplv-k3u1fbpfcp-zoom-1.image)
### 配置校验
"lint": "eslint --ext js src/"
代码语言:txt复制如果我们想在 `commit` 前校验,这里使用 `husky` 包,根目录必须要有 `.git` 目录,执行如下命令可以进行校验
- npx husky install
- npx husky add .husky/pre-commit "npm run lint"
## 环境变量
`vite` 的环境变量存在 `import.meta.env` 中,根路径下创建集中环境文件(文件名 `VITE_APP=xxx` 形式)
1. `.env` 中的变量什么环境都会存在
2. `env.development` 测试环境使用
3. `.env.development.local`
`local` 本地环境,以 `development` 方式打包出来的环境运行在其他机器上,可以区分,`local` 优先级高
4. `.env.production` 正式环境使用的变量
5. `.env.test` 测试环境使用的变量,配置命令 `vite --mode test`
如果您使用 `ts` 开发,可以配置 `ts` 类型
根目录创建 `vite-env.d.ts`
```ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
VITE_TITLE: string
}
代码语言:txt复制## hmr
热更新的实现是基于 `ws`,这里就不详细介绍了。如果我们建一个基础模板,基础逻辑如下
```js
// main.js
document.querySelector("#app").innerHTML = `
<h1>Hello Vite!</h1>
<a href="https://vitejs.dev/guide/features.html" target="_blank">Documentation</a>
`;
}
代码语言:txt复制如果我们去改变里面的文字内容,发现页面是刷新的,不是热更新,如果想实现热更新需要修改为:
```js
// 必须要 导出
export function render() {
document.querySelector("#app").innerHTML = `
<h1>Hello Vite!</h1>
<a href="https://vitejs.dev/guide/features.html" target="_blank">Documentation</a>
`;
}
render()
// 可能不存在 hot,只在开发环境起作用,vite build 没有 hot
if (import.meta.hot) {
// 文件可以接受 自己的 热更新
import.meta.hot.accept((newModule) => {
代码语言:txt复制newModule.render()
代码语言:txt复制// 这里使用新 module 的 render。如果直接调用 render,页面不会刷新,调用的还是原来的旧 render,
})
}
代码语言:txt复制## glob import
我们在 `vite` 中使用 `import.meta.xxx` 是因为 `vite` 中使用了 `fast-glob` 第三方包,我们可以目录文件
1. 通过正则方式引入 一组 js文件,不是一个
`src/glob` 文件夹, `a.js`, `b.js`, `a.json`, `b.json`
```js
const globModules = import.meta.glob('./glob/*')
console.log(globModules)
Object.entries(globModules).forEach((k, v) => {
v().then((m) => console.log(k, m.default))
})
代码语言:txt复制![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ce4873b5685e4479a89c0d96551882db~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/35f5d2cbc3884fae8a89a2df316ddaff~tplv-k3u1fbpfcp-zoom-1.image)
在实际工作中例如,多语言支持,需要多个 `js` 配置文件,就可以批量获取文件
功能来自 [fast-glob](https://github.com/mrmlnc/fast-glob)
## 预编译
预编译的目的是把浏览器不识别的文件变为 `esm` 文件,处理三方包的缓存,`vite` 对每个文件都没有做缓存,只要请求了一定是最新的内容。
1. `vite` 第一次使用会稍微慢一些,因为要处理文件变成浏览器能识别的,经过处理的包缓存在 `node_modules/.vite` 中。要处理浏览器不识别的文件例如 `.vue` 文件,`commonjs` 文件转为 esm 文件 [参考](https://juejin.cn/post/7032991450665058311)
2. 如果我们使用 `lodash` 包,可以知道 `lodash` 下包含多个不同文件,文件合并打包到一起,避免分开 `import`,会导致浏览器发送多个请求
3. 我们可以配置 `vite` 的预编译
```js
export default defineConfig({
// 需要预编译的包 可以自己配置
optimizeDeps: {
代码语言:txt复制include: [],
代码语言:txt复制exclude: []
}
})
代码语言:txt复制
本节对 vite
中的常见使用方式做了介绍,下一节会介绍下 rollup
用法,如果有问题欢迎留言,谢谢阅读!