解耦组件库 CLI 与模板:一种基于 Markdown 的务实插件化实践

43 阅读4分钟

前言

上一篇文章中,我们确定了组件库的样式技术栈。但随之而来的问题是:这些组件模板该如何管理?

很多脚手架会将模板(.tsx.scss)硬编码在 CLI 源码里。但在长期维护组件库的过程中,我发现这种做法极其僵化。为了让模板既能享受完美的开发体验,又能实现自由定制,我探索出了一套基于 Markdown 的插件化方案。

这套方案不是为了炫技,而是源于我在工程实践中对“可读性”和“解耦”的真实需求。


一、 为什么我坚持使用 Markdown 存储模板?

在尝试过各种模板载体后,我一直坚持使用 Markdown(MD)来编写组件模板。这并不是一个拍脑袋的决定,而是基于以下两个极其务实的理由:

  1. 解决“模板占位符”与“语法检查”的冲突

如果你直接写一个 .ts 模板文件,里面的变量占位符(如 <%= componentName %>)会导致编辑器疯狂报错,TSLint 也会飘红。
但将代码包裹在 Markdown 的代码块中,这些占位符就变成了纯文本。不仅编辑器不再报错,你还能天然享受到 Markdown 对不同语言(TS/SCSS/Vue)的代码高亮支持。

  1. 文档即模板,可读性至上

组件模板不应是冷冰冰的字符串。在 MD 文件中,我可以在代码块之外书写逻辑说明、设计规范甚至 Todo List。对于插件开发者来说,打开 MD 文件就像在读一份技术文档,这种直观性是 .ejs 或 .txt 无法比拟的。


二、 从“内置模板”到“插件化解耦”

虽然 MD 解决了模板的开发体验,但如果模板依然耦合在 CLI 工具中,当我想切换样式方案(如从 Sass 换到 Less)时,依然要动 CLI 的核心代码。

于是,我借鉴了插件化的思想,将 MD 模板从 CLI 中剥离,变成了独立可配置的插件包

  1. 核心调度层:轻量化的 CLI

CLI 不再关心模板长什么样,它只负责三件事:

  • 读取配置:  识别用户安装了哪个模板插件。
  • 动态加载:  从 node_modules 中搜索并 import 对应的插件。
  • 执行渲染:  调用插件提供的协议,将字符串写入磁盘。
  1. 模板内容层:独立的 NPM 插件

每个插件包都是一个独立的生态。你可以发布 @my-ui/plugin-sass,也可以发布 @my-ui/plugin-less。插件内部包含了对应的 MD 模板文件和一个简单的映射配置文件。


三、 技术实现:避开 AST 的过度设计

关于如何解析 MD 并生成组件,我并没有选择复杂的 AST(抽象语法树)方案,因为对于“查找-替换”这种需求,AST 属于典型的过度设计。

  • 字符串切片:  CLI 采用极简的逻辑,通过识别 Markdown 的代码块标识符(```)来提取内容。
  • Lodash Template:  提取出的字符串直接交给 lodash.template 处理。它稳定、轻量,能完美处理组件名替换、条件渲染等逻辑。

这种“MD 存储 + 字符串解析”的组合,保证了系统在拥有强大扩展性的同时,依然保持了极低的维护门槛。


四、 插件化协议的闭环

我定义了一套极其精简的协议,确保 CLI 能顺畅地与插件通信。一个插件包只需包含:

  1. Markdown 模板:  存放带变量的代码块。
  2. 入口配置文件:  告知 CLI 每个代码块应映射到哪个目标文件路径。

这种设计让组件库的扩展变得极其简单:如果你想尝试一种新的样式方案,只需新写一个 MD 模板插件并修改配置文件,无需触碰一行 CLI 逻辑。


结语

这一套架构的核心在于: “尊重开发者的感官(可读性),同时保持工程的边界(解耦)。”

通过 Markdown,我解决了模板编写时的语法冲突;通过插件系统,我解决了工具链的灵活度。至此,我们的组件库脚手架已经变成了一个 “样式可插拔、模板可视化” 的工程底座。

那么,在实际编写这些插件时,有哪些具体的体验优化?如何处理复杂的变量计算?在专栏的最后一篇中,我们将深入实战,聊聊插件开发的细节以及我对“零学习成本”工程化的终极追求。

下篇预告:  《模板开发的体验革命:为什么 Markdown 是插件化的最后一公里》