Show HN 上又冒出一个"够小"的 JS 库。开发者 Marcel Bos 发布的 Mador,主页第一句话就是"80 行代码,让任意 DOM 变得响应式"。翻开仓库数一下,主文件是 90 行物理行,刨掉空行注释也有 83 行有效代码。不是骗人,但也不是"80"这么齐整的数字。
这类几百字节的极简库,每次冒出来都带着一种"这才是本质"的骄傲感。骄傲感和工程可靠性,是两件不同的事。
Mador 是什么
核心 API 是一对函数:r 绑定 DOM,w 写状态。
const [r, w] = mador({ count: 1 });
r(".counter", (el, count) => { el.textContent = count; }, s => s.count);
w(s => { s.count++; });
没有组件,没有模板,没有虚拟 DOM。它靠 Proxy 追踪状态读取路径,只在依赖的字段变化时重跑绑定;写操作会批量处理,同一轮写入合并成一次更新。定位很清楚:给已有的服务端渲染页面加一点交互,不是替代框架。
855 字节的账,没那么好算
耳听为虚,眼见为实。README 写的"855 字节",说明是 minified(压缩后),不是 gzip。这个口径差异,在跟同类库比较时会失真。
petite-vue 的常见说法是约 6KB(压缩方式未详细说明),Alpine.js 未压缩体积约 44.5KB,Solid.js 最小应用是 10.6KB minified、4.2KB gzip。放在一起看,Mador 确实小,但小多少取决于拿什么去比——minified 对 gzip、单文件对完整框架,压根不是同一条起跑线。
依赖追踪:字符串子串匹配的隐藏风险
真正值得停下来看的,不是字节数,是依赖追踪的判定逻辑。源码里核心判断是这样一句:changedPath.includes(dependencyPath) || dependencyPath.includes(changedPath)。
这是字符串子串匹配,不是严格的路径树匹配。如果状态里同时有 count 和 accountCount 两个字段,绑定 accountCount 的路径字符串本身包含 count 这个子串——修改其中一个,可能触发另一个不该被触发的更新。这不是文档里写的 feature,是读源码才能发现的行为。
数组也不会被递归代理,更新时才浅拷贝传给 updater。这些都是"够用但边界模糊"的设计,简洁的代价通常藏在这类细节里,不会写在 README 的第一行。
- 风险.字段命名一旦存在包含关系,依赖追踪可能过度触发或漏触发更新,目前没有独立测试验证这个边界
谁该用它,谁不该
据供应链索引,这个 npm 包是几天前新建的,单人维护,没有生产历史。仓库里也没有基准测试或跑分脚本——"体积小=效率高"目前只有体积这一个数字撑着,性能这半句话还没有人验证。
它适合的场景很窄:服务端渲染出来的页面,想加一点交互又不想引入整套框架。它不适合的场景更明确:需要组件复用、路由、大规模动态列表的项目——虽然作者另做了一个 mador-map.js 处理带 key 的列表渲染,但生态配套仍然很薄。
极简的字节数,解决的是展示欲,不是信任问题
跟 Alpine、petite-vue 站在一起比,Mador 的体积优势建立在功能被削掉之上,不是纯粹的实现效率更高。这是两种不同的产品定位,不是同一赛道的效率竞赛。
- 结论.把"80 行/855 字节"当作 Show HN 展示品欣赏没问题,当作生产选择,先等它熬过几个月、攒出几个 issue 再说
数一数代码行数只是个开始。真正决定这类微库能不能活下来的,是接下来有没有人在真实项目里踩到那道字符串匹配的坑,然后把 issue 提出来。
