{T}

组件库 Vite 插件配置导出:setupDirectives 补链、auto-import 封装与 components resolver 生成

概述

这一节做了两件容易被混在一起的事:先补了宿主遗漏的 setupDirectives(app) 调用链路,再把原本写在宿主 vite.config.ts 里的 auto-import 和 components 配置,抽成组件库自己导出的公共方法。宿主项目虽已能消费组件库包,但接入成本仍偏高——要自己写 resolver、维护 hooks 列表,内容一更新宿主配置也要跟着改。解决的实质是:让组件库不仅导出运行时代码,还导出“如何接入这个组件库”的构建期配置。

学习目标

  • 理解 setupDirectives(app) 没被宿主调用时指令页面会失效
  • 理解宿主手写 resolver / imports 会随组件库演进漂移,应由组件库统一导出
  • 用脚本读取 package.json.name 作为单一事实来源
  • 导出 VPAutoImports 配置片段(非执行逻辑)
  • 导出 VPComponentsResolver 解析函数
  • 理解脚本现在生成 vite-plugin.ts 构建期辅助模块
  • 注意 components.d.ts / auto-imports.d.ts 重新生成

一、setupDirectives 没调用时指令页面看起来像组件库坏了

某些指令相关页面失效,原因不是组件库构建错了,而是宿主项目没有把导出的 setupDirectives 用起来。指令系统不属于组件自动注册逻辑,宿主必须明确接入。宿主页面异常时,要先区分是组件问题、hooks 问题,还是 directives 根本没挂上。

ts
import { setupDirectives } from 'el-admin-components'

setupDirectives(app)

二、宿主手写 resolver / imports 会随演进漂移

宿主侧手写配置大致两块:Components({ resolvers: [...] })AutoImport({ imports: [...] })。最容易漂移的地方是:组件前缀变了 resolver 要改、新的 useXxx hooks 增加了 imports 列表也要改。最合理的收敛方式,是让组件库自己导出当前包名、公开 hooks 列表、组件名前缀解析规则。这一步消除的是“宿主配置和组件库版本不同步”的风险。

text
宿主项目不再手写:
  包名 / hooks 列表 / 组件名前缀规则

而是直接从组件库导入这些配置

三、脚本读取 package.json.name 作为单一事实来源

在脚本顶部 require('../package.json')pkg.name,日后组件库改包名,不需要再手工去改 resolver 输出、auto-import 配置、宿主文档,因为脚本生成的内容会自动跟着 package.json.name 对齐。这正是“单一事实来源”的典型用法,让组件库未来重命名的成本显著下降。

js
const pkg = require('../package.json')
const pkgName = pkg.name

四、VPAutoImports 导出的是配置片段而非执行逻辑

VPAutoImports 本质不是函数,也不是立即生效逻辑,而是一份结构化配置:宿主拿到它,再传给 unplugin-auto-import。好处是宿主仍掌握自己 vite.config.ts 的最终结构,但组件库负责维护“我有哪些 hooks 应该自动导入”。这种可组合设计比直接帮宿主调用插件更灵活,也更容易被覆盖或扩展。

ts
export const VPAutoImports = {
  'el-admin-components': ['useForm', 'useMenu', 'useAudioPlayer'],
}

五、VPComponentsResolver 导出的是解析函数

VPComponentsResolver 职责很纯粹:接受 componentName,判断是否以 VP 打头,若是就返回 { name, from }。它更像一个“解析规则函数”,而不是完整插件。前提仍然是上一节已把组件名统一成 VP* 模式。组件库不必把整个 Components() 插件都包起来,导出 resolver 已经足够灵活。

ts
export const VPComponentsResolver = (componentName: string) => {
  if (componentName.startsWith('VP')) {
    return {
      name: componentName,
      from: 'el-admin-components',
    }
  }
}

六、脚本扩展生成 vite-plugin.ts 构建期辅助模块

自动化脚本新加了一个目标文件 src/vite-plugin.ts,说明脚本输出从“运行时代码入口生成”扩展到了“构建期接入配置生成”。这是一个重要的演进信号:组件库对外提供的已不只是 JS 运行时产物,还包括宿主如何更省心地接入它。组件库越成熟,就越不该只交付运行时代码,这一步是在提供“官方接入姿势”。

text
脚本输出两类文件
  1. main.ts        -> 运行时公共入口
  2. vite-plugin.ts  -> 宿主构建期接入辅助入口

七、d.ts 重新生成仍是必须关注的副产品

一旦 hooks 自动导入规则变了、组件 resolver 来源变了,对应自动生成的 auto-imports.d.tscomponents.d.ts 也必须重新生成,否则常见现象是页面能跑、编辑器全红、提示仍指向旧路径。自动导入的运行时和类型时是两条链路,二者都要同步。宿主改造 Vite 配置后,最好顺手让这两个 d.ts 重新生成。

八、让组件库与宿主形成稳定的接入协议

这一节真正推动的,不只是“少写点宿主配置”,而是把三件事绑定在一起:

  • package.json.name:组件库包名的单一事实来源
  • VP* 组件前缀:所有公共组件的统一识别模式
  • use* hooks 导出列表:自动导入要覆盖的 composables

当这三者都由脚本统一收敛并导出时,宿主接入组件库就不再是东抄一点配置、西记一点包名、手工维护一堆列表。

相反,它进入更成熟的状态:组件库负责定义协议,宿主负责消费协议。

组件库和宿主项目之间最怕“靠记忆同步”。一旦形成稳定协议,未来组件库演进成本会明显下降。

这节的价值在长期维护中会越来越明显,它把接入方式从“手工配置”升级成了“稳定协议”。


常见问题

问题原因解决方案
指令页面依旧失效只接了组件和 hooks 自动导入,没调用 setupDirectives(app)在宿主入口显式调用组件库导出的 setupDirectives
组件库新增 useXxx 就要手动改 Vite 配置hooks 列表由宿主人工维护在组件库脚本生成 VPAutoImports 并对外导出
自定义 resolver 包名写死,组件库改名就崩包名不是单一来源从脚本读取 package.json.name 统一生成 resolver 配置
组件自动导入没生效没把 VPComponentsResolver 接进 Components(),或组件前缀不统一保证组件统一为 VP*,并在宿主使用导出的 resolver
页面能跑但 IDE 仍报错auto-imports.d.ts / components.d.ts 没重新生成或 tsconfig 没感知重建声明文件,并确保 tsconfig include 包含它们

延伸阅读