Vite 0.1.6重磅更新:智能导入+路由安全

版本:0.1.6 | 协议:MIT | 依赖:Vite >=5.0.0 <8.0.0


写在前面

v0.1.6 的主题是:让自动导入更智能,让路由导航更安全,让工具层更实用

v0.1.5 引入的 autoImport 插件需要逐一列举要导入的 API 名称------vue: ['ref', 'reactive', 'computed', ...],列表一长就容易遗漏或多余。v0.1.6 带来的通配符 '*'

支持,让你一行配置就能导入模块的全部命名导出。同时,generateRouter 新增了路由类型声明生成,为 @meng-xi/uni-router 扩展 RouteNameMap

接口,实现类型安全的路由导航。此外,Common 工具模块新增了 5 个通用函数,插件代码也完成了规范化重构。

本版重点

能力 一句话说明 你需要做什么
autoImport 通配符导入 vue: ['*'] 自动导入模块所有命名导出 更新配置
autoImport Vue SFC 注入 import 语句注入到 <script setup> 块内部 无需操作
generateRouter 类型声明 生成 router.d.ts,扩展 RouteNameMap 接口 新增配置
Common 工具模块增强 新增 parseTemplate、formatDate、writeFileSyncSafely 等 按需导入
插件代码规范化重构 各插件非核心逻辑提取到 common/ 子目录 无需操作

升级方式 :修改 devDependencies 中版本号为 ^0.1.6。无 Breaking Changes,完全向后兼容。


一、5 分钟快速上手

1.1 安装与最小配置

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

export default defineConfig({
	plugins: [
		autoImport({
			imports: { vue: ['*'] },
			dts: true,
			vueTemplate: true
		}),
		generateRouter({ dts: true })
	]
})

1.2 立刻看到效果

之前:逐一列举要导入的 API

typescript 复制代码
autoImport({
	imports: {
		vue: ['ref', 'reactive', 'computed', 'watch', 'watchEffect', 'onMounted', 'onUnmounted', 'nextTick', 'toRef', 'toRefs', ...]
	}
})

之后:一行搞定

typescript 复制代码
autoImport({
	imports: { vue: ['*'] }
})

插件会自动从 vue.d.ts 类型声明文件中提取所有命名导出,无需手动维护列表。

1.3 路由类型安全

之前:路由名称是普通字符串,拼错不会报错

typescript 复制代码
uni.navigateTo({ name: 'pagesIndexIndx' }) // 拼错了,运行时才发现

之后 :启用 dts: true 后,路由名称有类型检查

typescript 复制代码
uni.navigateTo({ name: 'pagesIndexIndx' }) // TS 报错:类型 '"pagesIndexIndx"' 不能分配给类型 '"pagesIndexIndex" | ...'

二、核心能力一:autoImport 通配符导入

2.1 通配符解析策略

imports 配置中使用 '*' 时,插件会自动解析模块的所有命名导出:

复制代码
imports: { vue: ['*'] }
         ↓
  1. 优先从 .d.ts 类型声明文件解析(最准确)
     ↓ 失败
  2. 尝试作为本地文件路径解析
     ↓ 失败
  3. 尝试从 node_modules 解析运行时入口
     ↓ 失败
  4. 返回空数组

为什么优先使用 .d.ts bundler 格式的运行时入口文件(如 vue.runtime.esm-bundler.js)通常只包含 export { compile } 等极少导出,而完整的 API 通过动态方式导出,静态正则无法匹配。.d.ts

文件包含完整的静态类型声明,能准确反映模块的所有导出。

2.2 使用方式

typescript 复制代码
// 简写格式
autoImport({
	imports: {
		vue: ['*'], // 自动导入 vue 的所有命名导出
		'vue-router': ['*'], // 自动导入 vue-router 的所有命名导出
		pinia: ['defineStore', 'storeToRefs'] // 也可以混合使用
	}
})

// 完整格式
autoImport({
	imports: [
		{ module: 'vue', names: ['*'] },
		{ module: 'lodash', names: ['debounce'], defaultImport: false }
	]
})

2.3 Vue SFC 注入

v0.1.6 修复了 autoImport 与 uni-app 插件的协同问题。此前 transform 钩子使用 enforce: 'post',导致裸模块标识符无法被 Vite 正确解析。现在改回 enforce: 'pre',并新增 injectIntoScriptSetup

函数,将 import 语句注入到 <script setup> 块内部:

vue 复制代码
<!-- 处理前 -->
<script setup lang="ts">
const count = ref(0)
const double = computed(() => count.value * 2)
</script>

<!-- 处理后 -->
<script setup lang="ts">
import { ref, computed } from 'vue'
const count = ref(0)
const double = computed(() => count.value * 2)
</script>

2.4 修复列表

问题 原因 修复
vue: ['*'] 只解析出 compile resolveWildcardExports 走了运行时入口 优先从 .d.ts 解析
node_modules 文件被错误处理 默认 fileFilter 未排除 node_modules 正则改为 ^(?!.*node_modules)
裸模块标识符无法解析 enforce: 'post' 时 Vite 已完成模块解析 改回 enforce: 'pre'
makeCallback 语法错误 匿名函数作为函数声明调用 改用 IIFE 形式

2.5 配置选项变更

选项 变更前默认值 变更后默认值 说明
imports - - 新增支持 '*' 通配符格式
fileFilter `/.(vue jsx tsx

三、核心能力二:generateRouter 路由类型声明

3.1 类型声明生成

新增 dts 选项,为 @meng-xi/uni-router 模块扩展 RouteNameMap 接口:

typescript 复制代码
generateRouter({ dts: true })

生成的 src/router.d.ts

typescript 复制代码
import '@meng-xi/uni-router'

declare module '@meng-xi/uni-router' {
	interface RouteNameMap {
		/** 首页 */
		pagesIndexIndex: { path: '/pages/index/index'; meta: { title: string; isTab: true } }
		/** 个人中心 */
		pagesUserProfile: { path: '/pages/user/profile'; meta: { title: string; requireAuth: true } }
	}
}

3.2 dts 选项

行为
false 不生成类型声明文件(默认)
true 使用默认路径 src/router.d.ts
string 在指定路径生成类型声明文件

3.3 类型声明特性

  • TSDoc 注释:每条路由自动生成页面标题注释
  • 完整元信息映射meta 中的字符串字段类型为 string,布尔 true 字段类型为字面量 true
  • 增量写入:仅在内容发生变化时才写入文件,减少不必要的文件 IO

四、Common 工具模块增强

v0.1.6 为 Common 工具模块新增了 5 个通用函数:

4.1 common/format

parseTemplate --- 替换模板字符串中的 {``{key}} 占位符:

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

parseTemplate('Hello {{name}}!', { name: 'World' })
// 'Hello World!'

parseTemplate('{{YYYY}}-{{MM}}-{{DD}}', getDateFormatParams())
// '2026-06-07'

键名中的正则特殊字符会被自动转义,值中的 $ 也会被安全处理。

formatDate --- 使用 {YYYY}{MM} 等占位符格式化日期字符串:

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

formatDate(new Date(), '{YYYY}-{MM}-{DD}T{HH}:{mm}:{ss}')
// '2026-06-07T15:30:00'

4.2 common/fs

writeFileSyncSafely --- 同步写入文件,自动创建不存在的目录:

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

// 目录不存在时自动递归创建,适用于 transform 等同步钩子
writeFileSyncSafely('/project/src/auto-imports.d.ts', 'declare global { ... }')

shouldUpdateFileContent --- 对比文件内容是否需要更新:

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

if (shouldUpdateFileContent('/project/src/router.d.ts', newContent)) {
	writeFileSyncSafely('/project/src/router.d.ts', newContent)
}

4.3 common/html

escapeHtmlAttr --- 转义 HTML 属性值中的特殊字符:

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

escapeHtmlAttr('hello "world" & <friends>')
// 'hello &quot;world&quot; &amp; &lt;friends&gt;'

转义 &"'<> 五种字符,防止属性注入攻击。


五、插件代码规范化重构

按照 autoImport/common 目录规范,将各插件中不属于插件核心逻辑的函数、常量等提取到 common/ 子目录,通过 common/index.ts 聚合导出:

插件 提取内容
buildProgress/common 常量和工具函数
generateRouter/common 路由工具函数和类型声明生成逻辑(dts.ts
envGuard/common 运行时守卫、模板生成、校验逻辑
faviconManager/common 类型定义
htmlInject/common 代码生成器和校验器
loadingManager/common 常量、函数体生成器、代码生成器和校验器
versionUpdateChecker/common 代码生成器和校验器

重构原则 :插件主文件只保留生命周期钩子和核心流程,工具函数和类型定义移入 common/,保持代码结构清晰、职责单一。


六、实战场景

6.1 Vue 3 + uni-app 全家桶

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

export default defineConfig({
	plugins: [
		uni(),
		autoImport({
			imports: {
				vue: ['*'],
				'@dcloudio/uni-app': ['onLaunch', 'onShow', 'onHide', 'onLoad']
			},
			dts: true,
			vueTemplate: true
		}),
		generateRouter({ dts: true })
	]
})

6.2 纯 Vite 项目

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

export default defineConfig({
	plugins: [
		autoImport({
			imports: {
				vue: ['*'],
				'vue-router': ['*'],
				pinia: ['defineStore', 'storeToRefs']
			},
			dirs: ['src/composables'],
			dts: 'src/auto-imports.d.ts',
			vueTemplate: true
		}),
		buildProgress({ format: 'bar' }),
		envGuard({
			required: {
				VITE_API_URL: { type: 'url', required: true }
			}
		})
	]
})

6.3 使用 Common 工具函数构建自定义插件

typescript 复制代码
import { writeFileSyncSafely, shouldUpdateFileContent } from '@meng-xi/vite-plugin/common/fs'
import { formatDate } from '@meng-xi/vite-plugin/common/format'
import { escapeHtmlAttr } from '@meng-xi/vite-plugin/common/html'

// 在 transform 钩子中同步写入类型声明文件
function generateAndWriteDts(filePath: string, content: string): void {
	if (shouldUpdateFileContent(filePath, content)) {
		writeFileSyncSafely(filePath, content)
	}
}

// 格式化版本号
const version = formatDate(new Date(), '{YYYY}.{MM}.{DD}')

// 安全地注入 HTML 属性
const safeAttr = escapeHtmlAttr(userInput)

七、子路径导出变更

子路径 变更 内容
@meng-xi/vite-plugin/common/format 新增导出 parseTemplateformatDate
@meng-xi/vite-plugin/common/fs 新增导出 writeFileSyncSafelyshouldUpdateFileContent
@meng-xi/vite-plugin/common/html 新增导出 escapeHtmlAttr

八、迁移指南

从 v0.1.5 升级到 v0.1.6

1. 使用通配符简化配置(可选)
typescript 复制代码
// 之前
autoImport({
	imports: {
		vue: ['ref', 'reactive', 'computed', 'watch', 'onMounted', 'onUnmounted', 'nextTick']
	}
})

// 之后
autoImport({
	imports: { vue: ['*'] }
})
2. 启用路由类型声明(可选)
typescript 复制代码
generateRouter({ dts: true })
// 或自定义路径
generateRouter({ dts: 'src/types/router.d.ts' })
3. 使用新增的 Common 工具函数(可选)
typescript 复制代码
import { parseTemplate, formatDate } from '@meng-xi/vite-plugin/common/format'
import { writeFileSyncSafely, shouldUpdateFileContent } from '@meng-xi/vite-plugin/common/fs'
import { escapeHtmlAttr } from '@meng-xi/vite-plugin/common/html'

本文基于 @meng-xi/vite-plugin@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
前端·人工智能·程序员
京东云开发者3 小时前
京东Taro Native框架静态布局直渲提速
前端