2022年,一位前端工程师在Eleventy博客里塞了个插件,三年后他亲手把它埋了——因为那个方案只能活在一个框架里,而框架会死。
现在他用4KB客户端脚本做到了CodePen和CodeSandbox用几MB才能实现的事:纯本地、零外链、可交互的代码沙盒。没有iframe跳转到第三方,没有构建时依赖,写进HTML就能跑。
从"框架囚徒"到"框架自由"
作者最初的问题很具体:想在Markdown里放可运行的代码演示,但讨厌每次改demo都要跳去CodePen后台。更烦的是那些外链iframe拖慢页面,加载一堆用不到的JavaScript。
他2022年的解法是给Eleventy写了个短代码插件(eleventy-plugin-code-demo)。原理不复杂:把Markdown代码块里的HTML/CSS/JS拼成字符串,塞进iframe的srcdoc属性。构建时生成,运行时隔离。
但短代码语法长这样:
{% codeDemo "My iframe's title" %}```html
hello world!
```cssp { color: red; }```jsconsole.log("test");{% endcodeDemo %}
作者自己承认:"语法很别扭"。更致命的是Eleventy专属——万一哪天Eleventy不维护了,所有demo变砖。他吃过太多次这种亏:"永远不要过度依赖框架语义"。
srcdoc:被低估的iframe后门
整个方案的核心是iframe的srcdoc属性。普通iframe用src指向外部URL,srcdoc却允许你直接往里塞HTML字符串。就像给iframe喂了一整份网页当外卖,不用出门取餐。
作者最早是从Maciej Mionskowski的文章里偷到这个思路。但Mionskowski的方案是给Hugo用的,作者把它移植到了Eleventy,现在又把它从Eleventy里拔了出来。
新方案叫local-iframe,彻底抛弃构建时魔法。用法变成纯HTML标签:
Click me!
template标签里的内容被提取、组装成完整HTML文档,塞进srcdoc。浏览器渲染时,这段代码在一个完全隔离的iframe里运行,和主页面互不干扰。
4KB vs 几MB:代价是什么
CodePen和CodeSandbox的嵌入方案要加载整个在线IDE的runtime:代码编辑器、预览引擎、打包工具、可能还有React/Vue的dev server。local-iframe不碰这些——它假设你已经写好了代码,只需要一个地方让它跑起来。
这很像从"带厨房的餐厅"降级到"微波炉"。如果你要现场炒菜,CodePen依然是唯一选择;但如果你只是热个便当,4KB的微波炉显然更省电。
作者的原话是:"那些服务很棒,我天天用它们分享demo"——他没打算取代CodePen,只是解决一个特定场景:博客里的代码示例需要可交互,但不需要可编辑。
这个区分很关键。开发者文档里80%的代码块是"看这里会动"而不是"你来改改看"。local-iframe瞄准的就是这80%。
技术债的反向操作
作者提到"吃过太多次亏",指的是前端生态的框架轮回。jQuery插件、Grunt任务、Gulp流水线、Webpack配置——每代工具都承诺永恒,每代都被下一代埋葬。
eleventy-plugin-code-demo的问题不是技术,是契约:你和Eleventy绑定了。local-iframe的契约只和浏览器有关,而浏览器的iframe API比任何框架都长寿。
这是一种"技术债的反向操作":不是借新还旧,而是直接不借。代价是功能天花板——你永远得不到CodePen的实时协作、版本历史、社区生态。收益是确定性——十年后这段代码大概率还能跑。
作者把local-iframe发到了npm。没有构建步骤,没有配置项,script标签引入就能用。这种"反现代前端"的朴素感,本身就是个态度。
最后一个细节:作者在演示代码里埋了个小心思——那个点击事件冒泡的demo,button、body、html、window四层监听,点击一次控制台打印四条。这是DOM事件机制的经典面试题,被他做成了4KB的教具。
你会为这种确定性放弃在线编辑的便利吗?
热门跟贴