# API 设计模式 ## Options 模式 面向用户的选项及其内部解析后的版本: ```typescript export interface Options { verbose?: boolean include?: string[] exclude?: string[] } export interface ResolvedOptions extends Required { root: string } function resolveOptions(options: Options = {}): ResolvedOptions { return { verbose: options.verbose ?? false, include: options.include ?? ['**/*'], exclude: options.exclude ?? ['node_modules'], root: process.cwd(), } } ``` ## 工厂函数 创建配置好的实例: ```typescript export function createContext(options: Options = {}) { const resolved = resolveOptions(options) const filter = createFilter(resolved.include, resolved.exclude) return { options: resolved, filter, transform(code: string, id: string) { /* ... */ }, async scanDirs() { /* ... */ }, } } // 用法 const ctx = createContext({ verbose: true }) await ctx.scanDirs() ``` ## Builder 模式 支持类型累积的可链式调用 API: ```typescript export function createBuilder() { return { context(): Builder { return this as any }, input(schema: T): Builder { return this as any }, output(schema: T): Builder { return this as any }, build(): Procedure { /* ... */ }, } } // 用法 - 类型在链中传递 const procedure = createBuilder() .context<{ user: User }>() .input(z.object({ id: z.string() })) .build() ``` ## 插件模式(unplugin) 从单一实现生成通用插件: ```typescript import { createUnplugin } from 'unplugin' export default createUnplugin((options) => { const ctx = createContext(options) return { name: 'my-plugin', enforce: 'pre', transformInclude(id) { return ctx.filter(id) }, transform(code, id) { return ctx.transform(code, id) }, // 特定于打包工具的钩子 vite: { configResolved(config) { /* Vite 特有 */ }, }, webpack(compiler) { compiler.hooks.watchRun.tap('my-plugin', () => { /* ... */ }) }, } }) ``` 按打包工具分别导出入口: ```typescript // src/vite.ts import unplugin from '.' export default unplugin.vite // src/webpack.ts import unplugin from '.' export default unplugin.webpack ``` ## 惰性 Getter(Tree-shaking) 将特定于打包工具的代码延迟到被访问时才加载: ```typescript export function createPlugin(factory: PluginFactory) { return { get vite() { return getVitePlugin(factory) }, get webpack() { return getWebpackPlugin(factory) }, get rollup() { return getRollupPlugin(factory) }, } } ``` 只有被访问的 getter 会执行,其余部分被 tree-shaking 移除。 ## 智能默认值 检测环境而非要求配置: ```typescript import { isPackageExists } from 'local-pkg' function resolveOptions(options: Options) { return { vue: options.vue ?? isPackageExists('vue'), react: options.react ?? isPackageExists('react'), typescript: options.typescript ?? isPackageExists('typescript'), } } ``` ## Resolver 模式 通过函数或对象实现灵活解析: ```typescript export type Resolver = ResolverFunction | ResolverObject export type ResolverFunction = (name: string) => ResolveResult | undefined export interface ResolverObject { type: 'component' | 'directive' resolve: ResolverFunction } export function ElementPlusResolver(): Resolver[] { return [ { type: 'component', resolve: (name) => resolveComponent(name) }, { type: 'directive', resolve: (name) => resolveDirective(name) }, ] } ``` ## Fluent API(验证) 通过克隆实现不可变性的方法链: ```typescript class Schema { private _def: SchemaDef min(value: number): Schema { return new Schema({ ...this._def, min: value }) } max(value: number): Schema { return new Schema({ ...this._def, max: value }) } optional(): Schema { return new Schema({ ...this._def, optional: true }) } } // 用法 const schema = z.string().min(5).max(10).optional() ``` ## Barrel 导出 简洁的公开 API: ```typescript // src/index.ts export * from './config' export * from './types' export { createContext } from './context' export { default } from './plugin' ```