@meng-xi/vite-plugin v0.1.5:告别手动 import,精简工具层

版本:0.1.5 | 协议:MIT | 依赖:Vite ^5.0.0 || ^6.0.0 || ^7.0.0


写在前面

v0.1.5 的主题是:让 import 语句自动生成,让工具层只保留真正的复用逻辑。

每次写 Vue 组件都要手动 import { ref, reactive, computed } from 'vue',每次用 useRouter 都要 import { useRouter } from 'vue-router'------这些重复的导入语句既繁琐又容易遗漏。v0.1.5 带来的 autoImport

插件,让你彻底告别手动 import。同时,我们对 Common 工具模块进行了精简,移除了使用不足的模块,只保留真正在多处复用的核心工具。

本版重点:

能力 一句话说明 你需要做什么
autoImport 插件 自动检测标识符并注入 import 语句 新增配置
Common 工具模块精简 移除 compress/object/path,保留 6 个核心模块 检查依赖

升级方式 :修改 devDependencies 中版本号为 ^0.1.5。注意:common/compress、common/object、common/path 三个子路径已移除,如有使用请迁移。


一、5 分钟快速上手

1.1 安装与最小配置

json 复制代码
{
	"devDependencies": {
		"@meng-xi/vite-plugin": "^0.1.5"
	}
}
typescript 复制代码
import { autoImport } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [
		autoImport({
			imports: {
				vue: ['ref', 'reactive', 'computed', 'watch', 'onMounted']
			}
		})
	]
})

1.2 立刻看到效果

之前:每个组件都要手动导入

vue 复制代码
<script setup lang="ts">
import { ref, reactive, computed, watch, onMounted } from 'vue'

const count = ref(0)
const state = reactive({ name: 'app' })
const double = computed(() => count.value * 2)

onMounted(() => {
	console.log('mounted')
})
</script>

之后:直接使用,无需导入

vue 复制代码
<script setup lang="ts">
const count = ref(0)
const state = reactive({ name: 'app' })
const double = computed(() => count.value * 2)

onMounted(() => {
	console.log('mounted')
})
</script>

插件会自动检测代码中使用的 ref、reactive、computed 等标识符,并在文件顶部注入对应的 import 语句。

1.3 它解决了什么

typescript 复制代码
// ❌ 没有 autoImport 的日常
import { ref, reactive, computed, watch, onMounted, onUnmounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { storeToRefs } from 'pinia'
// ... 每个文件都要写一遍

// ✅ 有 autoImport:配置一次,全局生效
autoImport({
	imports: {
		vue: ['ref', 'reactive', 'computed', 'watch', 'onMounted', 'onUnmounted'],
		'vue-router': ['useRouter', 'useRoute'],
		pinia: ['storeToRefs']
	}
})

二、核心能力:autoImport 四大特性

autoImport 从四个维度提供自动导入能力:

复制代码
预设映射 ──→ 目录扫描 ──→ Vue 模板 ──→ 类型声明
 (配置)      (自动)       (增强)       (开发体验)

2.1 预设映射:声明式配置导入规则

简写格式

最常用的方式,键为模块路径,值为导入名称数组:

typescript 复制代码
autoImport({
	imports: {
		vue: ['ref', 'reactive', 'computed', 'watch', 'onMounted'],
		'vue-router': ['useRouter', 'useRoute'],
		pinia: ['defineStore', 'storeToRefs']
	}
})
完整格式

支持默认导入配置:

typescript 复制代码
autoImport({
	imports: [
		{ module: 'lodash', names: ['debounce', 'throttle'], defaultImport: false },
		{ module: 'dayjs', names: ['dayjs'], defaultImport: true }
		// 生成: import dayjs from 'dayjs'
	]
})
混合格式

两种格式可以在数组中混合使用:

typescript 复制代码
autoImport({
	imports: [{ vue: ['ref', 'reactive', 'computed'] }, { module: 'lodash', names: ['debounce'], defaultImport: false }, { 'vue-router': ['useRouter', 'useRoute'] }]
})

2.2 目录扫描:自动发现模块导出

配置 dirs 后,插件会自动扫描指定目录下的 .ts/.js/.mts/.mjs 文件,将导出的函数、变量、类注册为可自动导入的标识符:

typescript 复制代码
autoImport({
	dirs: ['src/composables', 'src/stores', 'src/utils']
})

扫描规则:

规则 说明
递归扫描 自动遍历子目录
跳过 node_modules 忽略依赖目录
跳过隐藏目录 忽略以 . 开头的目录
跳过 .d.ts 忽略类型声明文件
支持的扩展名 .ts、.js、.mts、.mjs

目录结构示例:

复制代码
src/composables/
  ├── useAuth.ts        → export function useAuth() {}
  ├── useFetch.ts       → export function useFetch() {}
  └── useTheme.ts       → export const useTheme = () => {}

配置 dirs: ['src/composables'] 后,useAuth、useFetch、useTheme 均可自动导入。

2.3 Vue 模板支持:template 中也能自动导入

开启 vueTemplate 后,Vue SFC <template> 中使用的 API 也会被自动导入:

typescript 复制代码
autoImport({
	imports: { vue: ['ref', 'computed'] },
	vueTemplate: true
})
vue 复制代码
<template>
	<!-- ref 和 computed 无需在 script 中导入即可在模板中使用 -->
	<p>{{ count }}</p>
	<p>{{ double }}</p>
</template>

<script setup lang="ts">
const count = ref(0)
const double = computed(() => count.value * 2)
</script>

检测范围:

位置 示例
插值表达式 {``{ count }}
指令绑定 v-if="isVisible"
属性绑定 :class="activeClass"
事件绑定 @click="handleClick"

2.4 类型声明生成:IDE 智能提示

开启 dts 后,插件自动生成 .d.ts 类型声明文件,让 IDE 识别全局可用的标识符:

typescript 复制代码
autoImport({
	imports: { vue: ['ref', 'reactive', 'computed'] },
	dts: 'src/auto-imports.d.ts'
})

生成的 src/auto-imports.d.ts:

typescript 复制代码
// 由 @meng-xi/vite-plugin/autoImport 自动生成
// 请勿手动修改

declare const ref: (typeof import('vue'))['ref']
declare const reactive: (typeof import('vue'))['reactive']
declare const computed: (typeof import('vue'))['computed']

dts 选项:

值 行为
'path' 在指定路径生成类型声明文件
true 使用默认路径 auto-imports.d.ts
false 不生成类型声明文件

三、精细控制

3.1 忽略标识符

某些标识符可能已通过其他方式全局注册,不需要自动导入:

typescript 复制代码
autoImport({
	imports: { vue: ['ref', 'reactive'] },
	ignore: ['React'] // React 已通过 CDN 全局注入
})

3.2 文件过滤

控制哪些文件需要被 transform 钩子处理:

typescript 复制代码
autoImport({
	fileFilter: /\.(vue|tsx|ts)$/ // 只处理 .vue、.tsx、.ts 文件
})

3.3 注入位置

控制 import 语句在文件中的插入位置:

typescript 复制代码
autoImport({
	injectAtPosition: 'after-last-import' // 注入到最后一个 import 之后
})
位置 行为
'top' 注入到文件有效代码最顶部(默认)
'after-last-import' 注入到最后一个已有 import 之后,无则回退顶部

四、Common 工具模块精简

v0.1.5 对 Common 工具模块进行了严格审查,移除了使用次数不足 2 次的模块和函数,只保留在多处被复用的核心工具。

4.1 移除的模块

模块 移除原因 迁移方式
common/compress calculateGzipSize 仅在 bundleAnalyzer 使用 已内联到 bundleAnalyzer 插件
common/object deepMerge 仅在 loadingManager 使用 已内联到 loadingManager 插件
common/path isNodeModule 仅在 bundleAnalyzer 使用 已内联到 bundleAnalyzer 插件

4.2 移除的函数

以下函数因仅在单处使用,已从 common 中移除并内联到各自的消费者中:

函数 原所属模块 当前位置
padNumber common/format buildProgress 插件内部
generateRandomHash common/format generateVersion 插件内部
formatDate common/format generateVersion 插件内部
parseTemplate common/format htmlInject 插件内部
toCamelCase common/format autoImport 插件内部
toPascalCase common/format autoImport 插件内部
stripJsonComments common/format autoImport 插件内部
escapeHtmlAttr common/format htmlInject 插件内部
getExtension common/format bundleAnalyzer 插件内部
SPINNER_FRAMES common/ui buildProgress 插件内部
stripAnsi common/ui buildProgress 插件内部

4.3 保留的 6 个核心模块

模块 描述 导出内容
common/format 格式化工具 getDateFormatParams、formatFileSize、DateFormatOptions
common/fs 文件系统工具 checkSourceExists、copySourceToTarget、writeFileContent、scanDirectory、writeJsonReport 及相关类型
common/html HTML 注入工具 injectBeforeTag、injectHeadAndBody、sanitizeContent 及相关类型
common/script 脚本生成工具 makeCallback
common/ui 终端 UI 工具 ANSI
common/validation 参数验证工具 Validator、validateGlobalName、validateNoScriptInTemplate、validateCallbackFields

精简原则:只有被 ≥2 个模块使用的逻辑才保留在 common 中。单一消费者内部的工具函数应内联到消费者中,避免 common 成为"万能垃圾桶"。


五、实战场景

5.1 Vue 3 + Vue Router + Pinia 全家桶

typescript 复制代码
import { defineConfig } from 'vite'
import { autoImport, buildProgress, envGuard } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [
		autoImport({
			imports: {
				vue: ['ref', 'reactive', 'computed', 'watch', 'watchEffect', 'onMounted', 'onUnmounted', 'nextTick'],
				'vue-router': ['useRouter', 'useRoute', 'onBeforeRouteLeave'],
				pinia: ['defineStore', 'storeToRefs']
			},
			dts: 'src/auto-imports.d.ts',
			vueTemplate: true
		}),

		buildProgress({ format: 'bar' }),

		envGuard({
			required: {
				VITE_API_URL: { type: 'url', required: true }
			}
		})
	]
})

5.2 自动扫描 composables 目录

typescript 复制代码
import { autoImport } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [
		autoImport({
			imports: {
				vue: ['ref', 'reactive', 'computed', 'onMounted']
			},
			dirs: ['src/composables', 'src/stores'],
			dts: 'src/auto-imports.d.ts',
			vueTemplate: true
		})
	]
})

5.3 uni-app 项目(仅 H5 平台)

typescript 复制代码
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import { autoImport } from './uni_modules/vite-plugin/js_sdk/index.mjs'

export default defineConfig({
	plugins: [
		uni(),
		autoImport({
			imports: {
				vue: ['ref', 'reactive', 'computed', 'watch', 'onMounted', 'onUnmounted']
			},
			dts: 'auto-imports.d.ts',
			vueTemplate: true,
			enabled: process.env.UNI_PLATFORM === 'h5'
		})
	]
})

六、autoImport 完整配置参考

选项 类型 默认值 描述
imports Record<string, string[]> | ImportMapping[] | Array<...> {} 导入映射配置
dirs string[] [] 需要扫描的目录列表
dts string | boolean 'auto-imports.d.ts' 类型声明文件输出路径,false 不生成
vueTemplate boolean false 是否为 Vue 模板启用自动导入
ignore string[] [] 需要忽略的标识符列表
fileFilter RegExp `/.(vue jsx
injectAtPosition 'top' | 'after-last-import' 'top' import 语句注入位置

ImportMapping 类型:

属性 类型 默认值 描述
module string --- 模块路径
names string[] --- 要导入的名称列表
defaultImport boolean false 是否为默认导入

ResolvedImport 类型:

属性 类型 描述
module string 模块路径
name string 导入标识符名称
isDefault boolean 是否为默认导入

ScannedModule 类型:

属性 类型 描述
filePath string 模块文件的绝对路径
exports string[] 命名导出名称列表
defaultExport string | null 默认导出名称,无则为 null

TransformResult 类型:

属性 类型 描述
code string 转换后的代码字符串
map any Source map 信息(可选)

七、迁移指南

从 v0.1.4 升级到 v0.1.5

1. 检查 common 子路径导入

如果项目中使用了以下子路径,需要移除或替换:

typescript 复制代码
// ❌ 已移除
import { calculateGzipSize } from '@meng-xi/vite-plugin/common/compress'
import { deepMerge } from '@meng-xi/vite-plugin/common/object'
import { isNodeModule } from '@meng-xi/vite-plugin/common/path'

// ✅ 这些功能已内联到对应插件中,如需使用请直接调用插件内部逻辑
// 或自行实现等价函数
2. 检查 common barrel 导入

以下函数已从 @meng-xi/vite-plugin/common 中移除:

typescript 复制代码
// ❌ 已移除的导出
import {
	calculateGzipSize, // → 内联到 bundleAnalyzer
	deepMerge, // → 内联到 loadingManager
	isNodeModule, // → 内联到 bundleAnalyzer
	SPINNER_FRAMES, // → 内联到 buildProgress
	stripAnsi, // → 内联到 buildProgress
	escapeHtmlAttr, // → 内联到 htmlInject
	getExtension, // → 内联到 bundleAnalyzer
	padNumber, // → 内联到 buildProgress
	generateRandomHash, // → 内联到 generateVersion
	formatDate, // → 内联到 generateVersion
	parseTemplate, // → 内联到 htmlInject
	toCamelCase, // → 内联到 autoImport
	toPascalCase, // → 内联到 autoImport
	stripJsonComments // → 内联到 autoImport
} from '@meng-xi/vite-plugin/common'
3. 新增 autoImport 插件(可选)
typescript 复制代码
import { autoImport } from '@meng-xi/vite-plugin'

export default defineConfig({
	plugins: [
		autoImport({
			imports: { vue: ['ref', 'reactive', 'computed'] },
			dts: 'src/auto-imports.d.ts',
			vueTemplate: true
		})
	]
})

本文基于 @meng-xi/vite-plugin@0.1.5 版本撰写,所有代码示例均来自实际源码。

相关推荐
2603_965896627 分钟前
Grid 网格布局|CSS 二维页面排版体系
前端·css
有味道的男人23 分钟前
搜好货平台关键词商品搜索接口:分页容错与商品数据轻量化提取方案
服务器·前端·javascript
lovingsoft1 小时前
Chrome Lighthouse 详解
前端·chrome
Qlly1 小时前
全栈工程师怎么接需求?从一句「加个功能」聊到能开发、能验收
前端·后端
马可家的菠萝1 小时前
你的微信“文件传输助手”,是不是已经成了第二个网盘?
前端·后端·架构
略略略啦1 小时前
Vibe Coding 基于Spec DD和TDD的实践指南
前端
shmily麻瓜小菜鸡2 小时前
前端实现图片与PDF文字识别敏感信息打码方案
前端·pdf·状态模式
打工仔折腾 AI2 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
汉堡大王95272 小时前
单次输出拉到100万Token:拆完 Gemini 4 Argon 的续写协议,才看懂谷歌这7个月在憋什么
前端·人工智能·后端
看浪的路人2 小时前
第9讲:大模型应用监控与可观测性——OpenTelemetry + Prometheus + Grafana 全链路追踪
java·前端·spring