12年前100行代码开一家店,如今AI逼着Shopify把JSON模板改回了Liquid  

12年前我打开Timber模板时,100行代码就搞定了整家店;现在打开Horizon模板,1万行代码里绕了8个文件夹还找不到购物车按钮在哪儿,这算进步吗?

Shopify正在把主题结构搬回可读代码里,这波操作直接掀翻了从2016年延续至今的JSON模板传统。AI代码助手、Liquid模板语言、主题开发架构、在线商店编辑器、声明式编程、部分更新机制、标准化事件与操作,所有这些概念正被一股脑卷进这场技术复古运动里。本文带你拆解为什么那个曾被抛弃的纯代码时代,在AI手里又杀回来了。

模板变成JSON那天起开发体验就开始崩了

2016年是个分水岭。那年Shopify上线了Sections功能,从此不会写代码的商家也能像拼乐高一样搭页面了。之前你只能改改全局颜色、字体大小,现在你能把首页拆成好几个独立区域,每个区域都能单独调整内容。商家乐坏了,但开发者开始头疼了。

为了把Sections和Blocks存下来,Shopify选了个序列化格式,就是JSON。看起来挺合理对吧,页面结构存成数据文件,系统照着渲染就行。但代价来了,你打开一个模板文件,里面只剩一堆JSON键值对,真正的HTML代码躲进了好几个层级的文件夹深处。

想搞清楚一个页面怎么工作的,你得同时打开JSON文件看结构、Liquid文件找数据逻辑、schema文件查配置选项、settings文件翻全局变量,还得在各个section文件夹和block文件夹之间来回跳转。这还不算完,有些逻辑藏在snippet里,有些样式写在asset里,整个就像在玩拼图游戏,缺一块你都看不全。

更狠的是官方后来直接警告开发者别手改JSON文件,说那是自动保存的输出结果,不是给人写的。这就相当于告诉你厨房里的菜已经切好了你别动,但你作为厨子居然不能碰食材,只能调调料。模板从那一刻起就变成了黑盒子,你往里填内容,它往外吐页面,中间那层逻辑对你关上了门。

商家爽了但代码可读性被牺牲得太惨

JSON模板时代带来了一个核心矛盾,灵活性和可读性你只能选一个。商家获得了前所未有的控制权,想怎么摆页面就怎么摆,点几下鼠标就能调换区块顺序、增减内容区域。但代价是开发者手里的代码变得支离破碎,一份完整的模板被拆成无数个小碎片,散落在各个目录里。

假设你接到个需求改产品详情页的布局,搁2013年你直接打开product.liquid,看个100行就全明白了。现在你得先找templates目录下的product.json,看它引用了哪些sections,再挨个打开那些section文件,每个文件里还有自己的schema配置,schema里又可能嵌套了blocks。一圈绕下来,时间花了半小时,代码改了五行。

有人会说这不就是现代前端开发的常态吗,组件化拆分啊。但问题是Shopify的主题开发不是React项目,没有路由器没有状态管理没有HMR热更新,它就是套模板渲染系统。硬把组件化思维塞进来,结果就是拆得稀碎却没有任何工具链辅助你理解这个碎片之间的关联。

而且JSON本身就不是给人手写的东西,它没注释功能,没法解释设计意图,也没法标注逻辑依赖。你看到一串配置对象,根本不知道它为什么长这样,当初设计的人想解决什么问题。代码不只是给机器执行的,更是给人读的,这句老话在JSON模板时代被彻底抛弃了。

AI代码助手成了压垮旧架构的最后一根稻草

Sidekick上线后商家用自然语言改主题的操作次数已经冲到2500万次了,五个商家里就有一个在拿AI改主题。同时开发者那边的AI编程工具也用得越来越猛,两个趋势撞到一起,Shopify不得不重新思考一件事,AI怎么理解主题代码。

旧架构的问题在AI面前被放大了无数倍。JSON配置、Liquid逻辑、HTML结构三样东西混在一起,还分了好几个文件夹,AI模型读起来token消耗巨大,理解成本极高。更麻烦的是AI会幻觉,它猜出来的API名字看着挺像那么回事,跑起来全报错。

为了给AI指路,Shopify往主题里塞了个.agents目录,里面放AGENTS.md和DESIGN.md这类说明文件,告诉代码助手你家的代码风格是什么、设计规范长啥样。还扩展了{% doc %}标签,给代码块加上类型标注和示例代码,让AI能查参数、看范例、学写法。

但这些都是打补丁,治标不治本。根本问题在于JSON作为配置语言词汇量太有限了,你没法在里面表达复杂的逻辑关系、布局意图、交互行为。AI能读懂HTML因为它训练数据里全是这东西,但你让它凭空猜一个Shopify自定义的JSON配置结构,它只能靠蒙。

于是Shopify团队问了个狠问题,如果从零设计一套给AI和人类都能顺畅阅读的主题架构,它该长什么样。答案是把页面结构搬回Liquid文件里,让模板重新变得可读。

HTML加Liquid组合拳把配置黑盒打碎了

新主题打开templates目录,你看到的是清一色的.liquid文件,不再是.json。集合页模板的长度回到了Timber时代那100行左右的水准,整个主题的代码量比Horizon少了93%。这组数字背后是架构思路的彻底翻转,能硬编码的绝不配置化。

新引入的{% block %}标签可以直接在Liquid模板里干活,接受命名参数,能嵌套内容,参数还能通过{% doc %}做类型标注。想加个按钮,直接HTML写一个,想再加一个并列的,wrap个div就完事。在旧架构里你得等开发者预先在配置里挖好坑位,商家才能往里面填东西,现在不需要了。

这套设计最大的优点是局部化理解,打开一个文件从上往下读,所有逻辑都在眼前。你要改某个区块,不用在八个文件夹里来回找引用关系。HTML负责结构,Liquid负责数据,清晰得像初代Timber模板。

做过React开发的人看到{% block %}的写法会感觉很亲切,参数像props,嵌套内容像children。但它的底层还是Liquid,没有额外的抽象层,没有复杂的生命周期,就是纯模板渲染。学习曲线几乎为零,会HTML和Liquid就能上手。

而且这轮改动有个很鸡贼的地方,它没有强制重写旧主题。现有主题永远能跑,Liquid本身也是永久API。想用新架构就新建主题,不想用就继续用旧的,两条路并行,谁也别逼谁。

Partials让页面更新不再整个重刷

之前开发者想实现局部刷新得用Section Rendering API,那玩意儿本来是设计用来渲染整个section的,被大家硬生生玩成了局部更新工具。就像拿消防水龙头浇花,水压大但不好控制,每次都得整段section重新渲染再替换,浪费服务器资源不说,响应速度也不够快。

新方案是加了个叫partials的基元,把你想要单独刷新的区域用{% partial %}标签包起来,前端通过JavaScript的partials.fetch和partials.apply两个方法拉取最新HTML并替换掉旧内容。几行代码搞定购物车数量更新、库存状态刷新这类操作,不用动整个section。

Horizon主题里有几千行代码是专门处理各种刷新逻辑的,用partials这套机制可以砍掉绝大部分。它就像给Liquid装了微操引擎,哪里变了刷哪里,页面其他部分纹丝不动。而且因为是服务器端渲染再替换,SEO友好,首屏性能也不受影响。

这玩意儿还有个好处,逻辑边界特别清晰。你看到{% partial %}就知道这块内容是动态可刷新的,维护起来不需要翻整个模板找JS事件绑定在哪儿。对AI来说也是一样,看到这个标签就明白这块的逻辑范围,改起来不会误伤旁边的静态内容。

Standard Events和Actions让前端交互有了统一字典

不同开发者写前端交互的习惯千差万别,有人用jQuery写事件绑定,有人用原生JS,有人用框架的响应式数据。Shopfiy这次搞了套Standard Actions,把更新购物车、切换商品选项这类常见操作包装成统一接口,调用方式一模一样,返回格式也一模一样。

text
const { cart } = await Shopify.actions.updateCart({
  lines: [{
    merchandiseId: variant.id,
    quantity: 1,
  }],
});

这段代码在所有Shopify商店里跑起来行为完全一致。主题开发者不用再猜某个按钮点击后该怎么更新数据,直接调标准方法就行。App开发者集成的时候也省心,不用为每个主题适配不同的交互逻辑。

Standard Events则是反过来,主题和App通过同一套事件词汇通信。用户点了个什么按钮、发生了什么状态变化,都按标准格式广播出去,谁爱听谁听。这套机制对AI尤其友好,因为语义路径清晰,浏览器agent能直接理解当前页面能做什么操作,不需要解析各种非标准的事件命名。

WebMCP支持让浏览器agent有了语义化的浏览和加购路径,storefront能响应这些交互而不只是被动输出页面。换个角度理解,之前AI看店铺是个文档,现在AI看店铺是个可交互的应用,两者之间的沟通成本大幅降低。

Liquid语法升级让条件判断终于不那么反人类了

以前写Liquid条件判断得用and、or这类英文单词连缀,而且不支持括号改变优先级,更不支持数组和对象的字面量写法。想判断一加一等于几,你写{{ 1 | plus: 1 }},看起来像在调用过滤器而不是在做数学运算。

这次升级带来了布尔表达式、带优先级的infix操作符,以及数组和对象的字面量语法。{{ 1 + 1 }}终于能用了,{{ false && false || true }}也能按预期逻辑执行了,assign products = [shirt, hat, shoes]这种数组赋值也成了合法代码。

语法升级背后有段曲折历史。Liquid早年用的解析器对很多不规范的写法睁一只眼闭一只眼,明明语法有歧义但它硬着头皮解析了。这就导致你没法往里加新语法,因为不知道会破坏多少老店的主题。团队花了大功夫把所有线上主题迁移到严格解析器上,才给这次升级腾出了空间。

新语法对AI的好处显而易见,模型本来就熟悉JavaScript和Python那套表达式体系,用同样风格写Liquid,它犯错的概率直线下降。对开发者来说更直观,不用在脑子里做语法转换,想怎么写就怎么写。

Tailwind进主题让AI和开发者共用一套设计词典

Tailwind进Liquid主题这个事很有意思,本身不算技术大爆炸,但放在整个AI主题架构里看,它补齐了样式语言这块拼图。AI模型训练数据里Tailwind的类名出现频率极高,开发者社区也早就会用了,风格统一这件事对两边都划算。

更关键的是Tailwind基于设计令牌体系,颜色、间距、字体大小都有语义化命名。AI理解text-red-500比理解#EF4444轻松得多,前者包含了颜色属性和色阶信息,后者只是个十六进制值。有了统一命名,AI给出的样式修改建议准确率会高很多。

而且Shopify这次没有强行塞一套复杂构建工具进来,Tailwind在Liquid里的用法就是直接写类名,不需要跑npm build,不需要配postcss。想用就用,不想用就写普通CSS,两套方案并行不冲突。

整场技术复古运动真正的底牌是让代码重新可读

从JSON退回Liquid,从配置化退回路程码,表面看是技术栈倒退了十二年,实质上是把被灵活性牺牲掉的可读性重新抢回来。Timber时代开发者打开一个文件就理解整页逻辑,那个体验在追求配置化灵活性的过程中丢失了。现在AI入场了,机器和人都需要可读的代码,两条需求合流逼着架构做出调整。

新架构的所有组件围着同一个目标转,让页面结构能用眼睛从头扫到尾看懂,让AI能用最小的token消耗理解模板意图,让修改行为精准发生而不触发连带改动。{% block %}直接怼进HTML里、{% partial %}精准刷新局部、Standard Actions统一操作路径、Liquid语法变回正常人写法,这四件事绑在一起做,整个主题开发体验就被拎回了直线逻辑时代。

值得玩味的是,这个方案没有推翻Liquid本身,反而把它推到了更中心的位置。配置曾经试图替代代码的表达力,结果失败了,因为配置的词汇量永远追不上代码。现在Liquid重新拿回页面结构的主导权,HTML补足表现层,两者配合的默契程度比十二年前更高,因为加入了类型、文档、校验这些辅助理解的信息层。

用时间换来的教训就摆在这儿,抽象一旦脱离了可读性,就会变成负担。技术演进的方向不一定永远是加东西,有时候往回看,把丢掉的好东西捡回来,才是真正的往前跑。

4000行JSON配置改个按钮要翻五个文件,100行Liquid一眼看到底改完收工,你选哪个。