vite自动导入api插件
从 0 实现“自动导入 API”功能的 Vite 插件,核心思想与 unplugin-auto-import 一样,但足够简单让你完全看懂,并且可以扩展。
本教程将从“最基础版本”到“高级增强版”一步步带你做出来。
# 🎯 最终效果示例(插件做到什么)
例如你在 Vue 或 React 项目里写代码:
const state = ref(0)
watch(state, () => {})
onMounted(() => {})
1
2
3
2
3
即使你没有写:
import { ref, watch, onMounted } from 'vue'
1
插件也会在编译阶段自动帮你加上。
最终编译变成:
import { ref, watch, onMounted } from 'vue'
const state = ref(0)
watch(state, () => {})
onMounted(() => {})
1
2
3
4
5
2
3
4
5
# 🧠 插件核心原理(非常简单)
Vite 的 transform() hook 能拿到文件源码:
transform(code, id)
1
我们做三件事:
# ① 扫描代码:找出哪些 API 被使用
例如 ref / computed / watch 等
# ② 判断这些 API 来自哪个库(vue/react/vueuse 等)
# ③ 自动生成 import 语句 + prepend 在文件最前面
# 🚀 Step 1:创建插件文件
创建 plugins/auto-import.js
# 🚀 Step 2:写一个最简自动导入插件(可运行)
下面是一个 可运行、核心版、支持 Vue 的自动导入插件:
export default function autoImport(options = {}) {
const imports = options.imports || {
vue: ['ref', 'reactive', 'computed', 'watch', 'onMounted']
}
return {
name: 'vite-plugin-auto-import',
transform(code, id) {
// 只处理 JS/TS/Vue 的 script 部分
if (!/\.(js|ts|vue)$/.test(id)) return
const importStatements = []
const usedApis = new Set()
// 遍历 imports 配置
for (const pkg in imports) {
const apis = imports[pkg]
apis.forEach(api => {
if (code.includes(api)) {
usedApis.add(api)
}
})
}
if (usedApis.size === 0) return
// 根据使用的 API 生成 import 语句
for (const pkg in imports) {
const apis = imports[pkg].filter(api => usedApis.has(api))
if (apis.length > 0) {
importStatements.push(
`import { ${apis.join(', ')} } from '${pkg}';`
)
}
}
const importCode = importStatements.join('\n')
// 将 import 代码插入到文件顶部
return {
code: importCode + '\n' + code,
map: null,
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 🚀 Step 3:在 Vite 中使用插件
vite.config.js:
import AutoImport from './plugins/auto-import.js'
export default {
plugins: [
AutoImport({
imports: {
vue: ['ref', 'reactive', 'computed', 'watch', 'onMounted'],
'vue-router': ['useRoute', 'useRouter']
}
})
]
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# ✨ 现在,你已经拥有了一个真正能工作的自动导入插件!
继续我们进入进阶增强版本。
# 🧠 Step 4:处理 Vue SFC(只编译 <script> 内容)
vue 单文件组件可能还有 <template> 等。
我们只想处理 <script>:
if (id.endsWith('.vue')) {
const script = code.match(/<script[^>]*>([\s\S]*)<\/script>/)
if (!script) return
code = script[1]
}
1
2
3
4
5
2
3
4
5
# 🧠 Step 5:避免重复导入(真正专业)
如果用户已经手动写了:
import { ref } from 'vue'
1
我们要避免重复添加。
只需检查代码里是否已有该 import:
if (code.includes(`from '${pkg}'`) && code.includes(api)) {
return
}
1
2
3
2
3
增强版本(示例):
const alreadyImported = code.includes(`import {`)
1
可做更强的 AST 检测(高级版)。
# 🧠 Step 6:通过 AST 提升精确度(真正“专业级”插件要用)
使用 @babel/parser 解析抽象语法树:
npm i @babel/parser @babel/traverse
1
示例:
import parser from '@babel/parser'
import traverse from '@babel/traverse'
const ast = parser.parse(code, { sourceType: 'module' })
1
2
3
4
2
3
4
然后检测:
traverse.default(ast, {
Identifier(path) {
const name = path.node.name
usedApis.add(name)
}
})
1
2
3
4
5
6
2
3
4
5
6
这样就不会误判字符串内容。
# 🧠 Step 7:构建完整插件(高级版)
以下是一个 专业级、可扩展、精确识别 API、带 AST 的自动导入插件 结构:
auto-import/
├─ index.js
├─ utils/scan.js
├─ utils/generate.js
├─ package.json
1
2
3
4
5
2
3
4
5
核心 index.js 会负责:
- 读取用户配置
- 分析源码
- 使用 AST 找 used identifiers
- 自动生成 import
- 支持 Vue 文件
- 支持多包映射
- 支持 dts(自动生成声明文件)
如:
// auto-import.d.ts
declare const ref: typeof import('vue')['ref']
1
2
2
你完全可以继续扩展。
上次更新: 2025/12/09, 03:15:37