解耦组件库 CLI 与模板:一种基于 Markdown 的务实插件化实践
前言
在上一篇文章中,我们确定了组件库的样式技术栈。但随之而来的问题是:这些组件模板该如何管理?
很多脚手架会将模板(.tsx, .scss)硬编码在 CLI 源码里。但在长期维护组件库的过程中,我发现这种做法极其僵化。为了让模板既能享受完美的开发体验,又能实现自由定制,我探索出了一套基于 Markdown 的插件化方案。
这套方案不是为了炫技,而是源于我在工程实践中对“可读性”和“解耦”的真实需求。
一、 为什么我坚持使用 Markdown 存储模板?
在尝试过各种模板载体后,我一直坚持使用 Markdown(MD)来编写组件模板。这并不是一个拍脑袋的决定,而是基于以下两个极其务实的理由:
- 解决“模板占位符”与“语法检查”的冲突
如果你直接写一个 .ts 模板文件,里面的变量占位符(如 <%= componentName %>)会导致编辑器疯狂报错,TSLint 也会飘红。
但将代码包裹在 Markdown 的代码块中,这些占位符就变成了纯文本。不仅编辑器不再报错,你还能天然享受到 Markdown 对不同语言(TS/SCSS/Vue)的代码高亮支持。
- 文档即模板,可读性至上
组件模板不应是冷冰冰的字符串。在 MD 文件中,我可以在代码块之外书写逻辑说明、设计规范甚至 Todo List。对于插件开发者来说,打开 MD 文件就像在读一份技术文档,这种直观性是 .ejs 或 .txt 无法比拟的。
二、 从“内置模板”到“插件化解耦”
虽然 MD 解决了模板的开发体验,但如果模板依然耦合在 CLI 工具中,当我想切换样式方案(如从 Sass 换到 Less)时,依然要动 CLI 的核心代码。
于是,我借鉴了插件化的思想,将 MD 模板从 CLI 中剥离,变成了独立可配置的插件包。
- 核心调度层:轻量化的 CLI
CLI 不再关心模板长什么样,它只负责三件事:
- 读取配置: 识别用户安装了哪个模板插件。
-
动态加载: 从
node_modules中搜索并import对应的插件。 - 执行渲染: 调用插件提供的协议,将字符串写入磁盘。
- 模板内容层:独立的 NPM 插件
每个插件包都是一个独立的生态。你可以发布 @my-ui/plugin-sass,也可以发布 @my-ui/plugin-less。插件内部包含了对应的 MD 模板文件和一个简单的映射配置文件。
三、 技术实现:避开 AST 的过度设计
关于如何解析 MD 并生成组件,我并没有选择复杂的 AST(抽象语法树)方案,因为对于“查找-替换”这种需求,AST 属于典型的过度设计。
- 字符串切片: CLI 采用极简的逻辑,通过识别 Markdown 的代码块标识符(```)来提取内容。
-
Lodash Template: 提取出的字符串直接交给
lodash.template处理。它稳定、轻量,能完美处理组件名替换、条件渲染等逻辑。
这种“MD 存储 + 字符串解析”的组合,保证了系统在拥有强大扩展性的同时,依然保持了极低的维护门槛。
四、 插件化协议的闭环
我定义了一套极其精简的协议,确保 CLI 能顺畅地与插件通信。一个插件包只需包含:
- Markdown 模板: 存放带变量的代码块。
- 入口配置文件: 告知 CLI 每个代码块应映射到哪个目标文件路径。
这种设计让组件库的扩展变得极其简单:如果你想尝试一种新的样式方案,只需新写一个 MD 模板插件并修改配置文件,无需触碰一行 CLI 逻辑。
结语
这一套架构的核心在于: “尊重开发者的感官(可读性),同时保持工程的边界(解耦)。”
通过 Markdown,我解决了模板编写时的语法冲突;通过插件系统,我解决了工具链的灵活度。至此,我们的组件库脚手架已经变成了一个 “样式可插拔、模板可视化” 的工程底座。
那么,在实际编写这些插件时,有哪些具体的体验优化?如何处理复杂的变量计算?在专栏的最后一篇中,我们将深入实战,聊聊插件开发的细节以及我对“零学习成本”工程化的终极追求。
下篇预告: 《模板开发的体验革命:为什么 Markdown 是插件化的最后一公里》