@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/compresscommon/objectcommon/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>

插件会自动检测代码中使用的 refreactivecomputed 等标识符,并在文件顶部注入对应的 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'] 后,useAuthuseFetchuseTheme 均可自动导入。

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 格式化工具 getDateFormatParamsformatFileSizeDateFormatOptions
common/fs 文件系统工具 checkSourceExistscopySourceToTargetwriteFileContentscanDirectorywriteJsonReport 及相关类型
common/html HTML 注入工具 injectBeforeTaginjectHeadAndBodysanitizeContent 及相关类型
common/script 脚本生成工具 makeCallback
common/ui 终端 UI 工具 ANSI
common/validation 参数验证工具 ValidatorvalidateGlobalNamevalidateNoScriptInTemplatevalidateCallbackFields

精简原则:只有被 ≥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 版本撰写,所有代码示例均来自实际源码。

相关推荐
梦曦i1 小时前
Vite 0.1.6重磅更新:智能导入+路由安全
前端
gxf5203088069882 小时前
Flutter 裁剪图片
前端·app
ITMan彪叔2 小时前
赋能UE运行态编辑平台: 网络图片下载的插件改造与复盘
前端
RANxy2 小时前
🚀 Umi Max 项目从0到1:企业级 React 脚手架实战
前端·前端框架
拾年2752 小时前
深入理解 V8 引擎:从代码执行到垃圾回收的完整链路
前端·javascript·v8
Master_Azur2 小时前
javaScript进阶
前端
markfeng82 小时前
React入门教学
前端·react.js
ze_juejin3 小时前
Object.defineProperty vs Proxy 对比总结
前端
wing983 小时前
我的AI编程体验:从白嫖到付费,我为什么最终留下了Codex
前端·人工智能·程序员