Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • TypeScript
    • CSS
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《JavaScript教程》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • TypeScript
    • CSS
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • vite从入门到精通
  • vite插件
  • vite自动导入api插件
    • 🎯 最终效果示例(插件做到什么)
    • 🧠 插件核心原理(非常简单)
      • ① 扫描代码:找出哪些 API 被使用
      • ② 判断这些 API 来自哪个库(vue/react/vueuse 等)
      • ③ 自动生成 import 语句 + prepend 在文件最前面
    • 🚀 Step 1:创建插件文件
    • 🚀 Step 2:写一个最简自动导入插件(可运行)
    • 🚀 Step 3:在 Vite 中使用插件
    • ✨ 现在,你已经拥有了一个真正能工作的自动导入插件!
    • 🧠 Step 4:处理 Vue SFC(只编译 <script> 内容)
    • 🧠 Step 5:避免重复导入(真正专业)
    • 🧠 Step 6:通过 AST 提升精确度(真正“专业级”插件要用)
    • 🧠 Step 7:构建完整插件(高级版)
  • Vite 开发服务器核心原理讲解
  • Vite HMR源码级讲解
  • Vite虚拟模块插件
  • 模拟 Vite 内置env
  • vite一体化虚拟模块插件
  • vite可发布npm的虚拟插件
  • 《Vite》学习笔记
mamingjuan
2024-07-23
目录

vite自动导入api插件

从 0 实现“自动导入 API”功能的 Vite 插件,核心思想与 unplugin-auto-import 一样,但足够简单让你完全看懂,并且可以扩展。

本教程将从“最基础版本”到“高级增强版”一步步带你做出来。


# 🎯 最终效果示例(插件做到什么)

例如你在 Vue 或 React 项目里写代码:

const state = ref(0)
watch(state, () => {})
onMounted(() => {})
1
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

# 🧠 插件核心原理(非常简单)

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

# 🚀 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

# ✨ 现在,你已经拥有了一个真正能工作的自动导入插件!

继续我们进入进阶增强版本。


# 🧠 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

# 🧠 Step 5:避免重复导入(真正专业)

如果用户已经手动写了:

import { ref } from 'vue'
1

我们要避免重复添加。

只需检查代码里是否已有该 import:

if (code.includes(`from '${pkg}'`) && code.includes(api)) {
  return
}
1
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

然后检测:

traverse.default(ast, {
  Identifier(path) {
    const name = path.node.name
    usedApis.add(name)
  }
})
1
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

核心 index.js 会负责:

  • 读取用户配置
  • 分析源码
  • 使用 AST 找 used identifiers
  • 自动生成 import
  • 支持 Vue 文件
  • 支持多包映射
  • 支持 dts(自动生成声明文件)

如:

// auto-import.d.ts
declare const ref: typeof import('vue')['ref']
1
2

你完全可以继续扩展。


上次更新: 2025/12/09, 03:15:37
vite插件
Vite 开发服务器核心原理讲解

← vite插件 Vite 开发服务器核心原理讲解→

Copyright © 2015-2025 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式