jsx-template 是一个"用 JSX 写模板"的实践项目:借助 babel 把 JSX 语法编译成可执行的模板方法,服务端或浏览器端动态执行后返回 HTML 字符串。相比字符串拼接模板,JSX 拥有完整的 JavaScript 表达式能力与编译期校验。
新版动态模板流程
- 传入 jsx 入口文件地址。
- 调用 jsx-template-transform 处理入口文件:解析 JSX 并编译为方法字符串。
- 动态执行返回的方法字符串(
new Function/eval一类方式加载编译产物)。 - 生成一个模板方法:接收参数并返回 HTML 字符串。调用方传入数据即可渲染,模板内可自由使用表达式、条件与循环。
这样模板与数据分离:模板方法只依赖传入参数,天然适合多份数据复用同一模板的场景。
旧的 transform 流程(已废弃)
旧实现走的是 babel 标准转换管线:
- 传入要处理的文件地址并读取文件内容 code。
- 在 code 最前面注入
createElement(或 h)辅助函数,让 JSX 编译产物的调用有处可落。 - 使用
@babel/core的 transform API 处理 code。 - 依次应用
@babel/preset-env与@babel/plugin-transform-*系列插件完成语法降级与 JSX 转换。 - 输出最终代码。
该版本已废弃,原因集中在灵活性不足:注入逻辑写死在入口、整个文件作为整体转换,难以按模块精细化控制。
babel 插件 transform-imports 带 loader 版本
为了支持"按 import 来源决定是否转换",实现了一个 babel 插件 + loader 的组合:
- 定义缓存变量,存储反序列化所用到的方法(
unserializeFuncUUIDCache),避免重复解析。 - 插件监听
ImportDeclaration节点,并验证用户传入的LoaderOptions。 - 根据当前 import 的文件,找到满足条件的
matchedLoader:- 存在:对该 import 执行转换(改写导入路径 / 注入运行时方法);
- 不存在:跳过,保留原始 import 不变。
该设计把"是否转换"的判定下放到 import 粒度,配合 webpack loader 在编译期完成,使同一份源码里可以混合"需要模板化的模块"与"保持原样的模块"。
Discussion
留言与讨论
想法、补充和不同意见都欢迎。