关于 vtex-io-app-contract
面向 VTEX IO 开发者的编码技能,帮助确定应用的职责及如何在 `manifest.json` 中声明契约。内容涵盖 builder 归属、依赖关系、应用边界,以及可发布的身份和版本管理。
主要功能
- 01在 `manifest.json` 中声明应用能力
- 02按应用职责选择 builder
- 03区分 dependencies 与 peerDependencies
- 04保持应用身份和版本可发布
- 05处理大版本变更中的内容迁移
适用场景
- 01定义新的 VTEX IO 应用契约
- 02排查清单导致的链接或发布失败
- 03判断是否应拆分无关应用能力
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ vtex/ skills --skill vtex-io-app-contract安装后在 Claude Code 中输入/vtex-io-app-contract确认已加载。
详细介绍
App 契约与 Builder 边界
适用场景
当主要决策涉及 VTEX IO 应用是什么、声明了哪些能力,以及通过 manifest.json 发布哪些集成边界时,请使用此技能。
- 创建新的 VTEX IO 应用并定义其初始契约
- 添加或移除 Builder,以匹配应用能力
- 在
dependencies和peerDependencies之间做出选择 - 决定某项能力属于当前应用,还是应移至其他应用
- 排查由清单级契约问题导致的链接或发布失败
以下情况请勿使用此技能:
service.json、内存、工作进程或路由公开等服务运行时行为- HTTP 处理程序实现、中间件组合或事件处理
- GraphQL 架构、解析器或数据获取实现
- 店面、管理端或渲染运行时前端行为
- 策略建模和安全边界实施
决策规则
- 将
manifest.json视为应用契约。它声明身份、Builder、依赖项、对等依赖项,以及其他应用或平台所依赖的高级能力。 - 仅当应用确实拥有某项能力时,才添加对应的 Builder。Builder 不是为未来工作预留的占位符。
- 保持契约精简。如果清单开始涵盖互不相关的事项,应将这些事项拆分到不同应用,而不是创建一个包罗万象的应用。
- 仅对可作为当前应用契约的一部分安全自动安装的应用使用
dependencies。对于必须已存在于环境中、由外部管理,或声明了billingOptions的应用,使用peerDependencies。 - 确保命名和版本信息可以发布:
vendor、name和version必须构成稳定的身份,以便安全地链接、发布和使用。 - 确保
billingOptions与应用的商业契约一致。如果应用涉及计费,应在清单中明确声明,而不是让定价行为保持隐式。 - 声明了
billingOptions的应用不能通过dependencies使用。如果当前应用需要一个付费应用,应使用peerDependencies表示这种关系,并要求账户或版本所有者手动安装。 - 版本应用是应用契约的组合,并非例外。应保持每个底层应用契约明确、精简且符合 semver 规则,以确保组合在不同宿主环境中具有可预测性。
manifest.json还可以声明应用级权限和配置界面,但详细的策略建模属于安全相关技能,详细的settingsSchema设计则属于应用设置相关技能。
这并非 Builder 的完整列表;完整目录请参阅官方 Builders 文档。
Builder 归属参考:
| Builder | 当应用契约包含以下内容时,由此应用拥有该 Builder |
|---|---|
node | 由此应用拥有的后端运行时能力 |
graphql | 由此应用拥有的 GraphQL 架构公开能力 |
react | 由此应用拥有的 React 包 |
admin | 由此应用拥有的管理界面 |
store | 由此应用拥有的 Store Framework 区块注册 |
messages | 由此应用拥有的本地化消息包 |
pixel | 由此应用拥有的店面像素注入 |
masterdata | 由此应用拥有的 Master Data 架构资源 |
契约边界判断准则:
- 如果某项能力随此应用一同交付、版本化并维护,则在此处声明其 Builder。
- 如果此应用只是使用其他应用提供的能力,则声明依赖项,而不是重复声明 Builder。
- 如果某项能力引入了独立的运行时、安全模型或发布周期,请考虑将其拆分为另一个应用。
硬性限制
约束:所有已发布的功能都必须在清单契约中声明
如果应用发布了可处理的 VTEX IO 功能,manifest.json 就必须声明对应的 builder。不要仅凭文件夹是否存在来判断,也不要假设 VTEX IO 会根据仓库结构推断功能。
同样,不要为此应用实际上未发布的功能声明 builder。
为什么这很重要
VTEX IO 根据已声明的 builder 编译和链接应用,而不是根据意图。如果缺少 builder,平台就会忽略该功能,导致应用契约具有误导性。应用可能会部分链接,但预期功能却不存在。
检测
如果你看到有维护的 /node、/react、/graphql、/admin、/store、/messages、/pixel 或 /masterdata 目录,请停止并确认 manifest.json 中存在匹配的 builder。如果 builder 存在,但对应功能并不存在,请停止并移除 builder,或将该功能移回范围内。
正确
{
"vendor": "acme",
"name": "reviews-platform",
"version": "0.4.0",
"builders": {
"node": "7.x",
"graphql": "1.x",
"messages": "1.x"
}
}
错误
{
"vendor": "acme",
"name": "reviews-platform",
"version": "0.4.0",
"builders": {
"messages": "1.x"
}
}
该应用发布了后端和 GraphQL 功能,却只声明了 messages,因此运行时契约不完整,平台会忽略缺少声明的 builder。
约束:应用身份和版本号必须符合发布要求且遵循 semver
vendor、name 和 version 字段必须标识有效的 VTEX IO 应用契约。应用名称使用 kebab-case,确保 vendor 与所有权一致,并使用完整的语义化版本号。
为什么这很重要
消费者、工作区和发布流程都依赖稳定的应用身份。无效名称或不完整的版本号会导致链接和发布失败,而身份信息的变动则会造成不安全的升级和难以调试的依赖不匹配问题。
检测
如果发现大写字符、下划线、非 semver 版本号,或与无关工作混在一起的 vendor/name 更改,请停止并确认这些更改是否符合预期且可安全发布。
正确
{
"vendor": "acme",
"name": "order-status-dashboard",
"version": "2.1.0"
}
错误
{
"vendor": "AcmeTeam",
"name": "Order_Status_Dashboard",
"version": "2.1"
}
此身份信息无法安全发布,因为名称不是 kebab-case,且版本号不是有效的 semver。
约束:对持有内容的应用进行主版本号升级会导致已存储内容失效
如果应用发布了 store/blocks.json、store/routes.json、store/templates/ 或 store/contentSchemas.json 中的任何一项(也就是说,从 Store Framework 的角度来看,它是一个持有内容的应用),则必须将 version 字段视为面向商家的版本号。对该应用执行 vtex release major 会更改 vtex.pages-graphql 用于查找每一项 Site Editor 编辑内容、每条自定义路由和每份模板渲染缓存的键前缀。
为什么这很重要
vtex.pages-graphql 使用 [email protected]:template 作为商家内容的键。补丁版本和次版本升级会保留该键,主版本升级则会更改它。主版本升级后,解析器无法在当前主版本键下找到之前创建的任何内容,店面会回退到默认的 vtex.store-theme 内容。官方恢复流程是在安装新主版本后、推广之前,于带有生产标记的开发工作区中执行 [email protected] 的 updateThemeIds mutation;该操作会将所有 Site Editor 编辑内容、Pages 和 Redirects 的键从旧主版本更改为新主版本。
检测
在批准对 builders 中声明了 "store" 的应用(或发布了 store/ 下任何文件的应用)执行 vtex release major 之前,请停止并要求提供明确的 updateThemeIds 迁移计划,且该计划必须在带有生产标记的开发工作区中执行。在生产账户上安装此类应用的任何新主版本之前,同样适用此规则。
正确
# patch and minor preserve content keys; safe for content-holding apps
vtex release patch
vtex release minor
错误
# major bump on a content-holding app installed straight to master:
# every Site Editor edit becomes invisible to the resolver and the
# storefront falls back to default vtex.store-theme content. The fix
# is to install the new major in a production-flag dev workspace and
# run updateThemeIds in [email protected] before promote.
vtex release major
vtex publish
vtex install [email protected]
请参阅 vtex-io-storefront-theme-versioning,了解持有内容的应用的安全安装、updateThemeIds 迁移、冒烟测试、推广和回滚流程。
约束:dependencies 和 peerDependencies 必须正确表达安装意图
仅当本应用应根据其契约安装某个应用,且该应用可以安全地自动安装时,才使用 dependencies。如果某个应用必须已存在于环境中、应由外部管理,或声明了 billingOptions,则使用 peerDependencies。
为什么这很重要
这是你的应用与 VTEX IO 工作区其余部分之间的核心契约边界。错误分类某种关系会导致安装失败、隐藏的耦合,以及仅在 link 或 publish 后才会出现的环境特定行为。特别是,builder-hub 会拒绝依赖声明了 billingOptions 的应用。
检测
如果应用在所有环境中都需要另一个应用才能运行,请 STOP 并确认它应归入 dependencies 还是 peerDependencies。如果目标应用声明了 billingOptions,请 STOP 并将其移入 peerDependencies。如果应用仅集成平台功能、宿主应用、由 edition 管理的应用或付费应用,且这些应用应由账户手动管理,请 STOP 并确保它不在 dependencies 中。
正确
{
"dependencies": {
"vtex.search-graphql": "0.x"
},
"peerDependencies": {
"vtex.store": "2.x",
"vtex.paid-app-example": "1.x"
}
}
错误
{
"dependencies": {
"vtex.store": "2.x",
"vtex.paid-app-example": "1.x"
},
"peerDependencies": {}
}
此契约会强制安装通常应由外部管理的宿主应用,并尝试自动安装需要付费的应用,而 builder-hub 会拒绝这种做法。
推荐模式
先确定该应用最精简且有用的契约,然后只声明该契约所需的标识和 builders。
适用于专注型服务加 GraphQL 应用的推荐清单:
{
"vendor": "acme",
"name": "reviews-platform",
"version": "0.1.0",
"title": "Reviews Platform",
"description": "VTEX IO app that owns review APIs and review GraphQL exposure",
"builders": {
"node": "7.x",
"graphql": "1.x",
"messages": "1.x"
},
"billingOptions": {
"type": "free"
},
"dependencies": {
"vtex.search-graphql": "0.x"
},
"peerDependencies": {
"vtex.store": "2.x"
}
}
推荐的契约拆分方式:
reviews-platform/
├── manifest.json # identity, builders, dependencies, peerDependencies
├── node/ # backend capability owned by this app
├── graphql/ # GraphQL capability owned by this app
└── messages/ # app-owned translations
reviews-storefront/
├── manifest.json # separate release surface for storefront concerns
├── react/
└── store/
当后端/API 契约与店面契约的所有权、发布周期或集成边界不同时,使用这种拆分方式。
常见故障模式
- 为尚未由应用负责的设想功能声明 builders,导致契约范围大于实际实现。
- 使用一个庞大的清单来表示后端运行时、前端渲染、设置、策略和集成相关事项,而这些内容本应拆分到多个技能或应用中。
- 将宿主级应用放在
dependencies中,而它们本应保留在peerDependencies中。 - 固定依赖的具体版本,而不使用
0.x、1.x或3.x等主版本范围。 - 将
manifest.json当作运行时或安全细节的存放处,而这些内容应归入更具体的技能。 - 在此处建模
settingsSchema,而不是仅通过此技能判断应用级配置是否应纳入契约。
审查清单
- 清单是否仅描述此应用实际负责并交付的功能?
- 每项交付的功能是否都有对应的 builder 声明?
- 应用标识是否可发布:
vendor有效、name使用 kebab-case,且version为完整 semver? - 如果应用涉及计费,
billingOptions是否明确且符合应用契约? -
dependencies和peerDependencies是否按安装意图区分? - 将契约拆分成两个应用,是否能减少无关事项或发布耦合?
- 是否已将运行时、路由、GraphQL 实现、前端和安全细节排除在此技能之外?
- 如果应用交付了
store/下的任何文件,是否已审查计划中的任何主版本升级对商家的影响?
相关技能
vtex-io-storefront-theme-versioning— 当应用声明了storebuilder,且版本变更必须保留或迁移 Site Editor 内容时使用。vtex-io-storefront-theme-app— 当问题涉及主题应用的store/文件应由谁负责时使用。