SuperAPI AI 工具集

sfnext-extensions

前端与建站

查看项目

更新于 10-16 06:04

技能介绍

用途

该技能面向 Storefront Next 的扩展系统,用于构建可插拔的模块化功能。扩展是自包含的功能模块,能够向 Storefront Next 店面添加组件、路由、翻译和上下文提供者,而无需修改核心代码。

主要能力

  • 通过 target-config.json 声明扩展如何集成,包括组件和上下文提供者。
  • 使用目标点(target points)作为店面布局中的命名插入槽位,扩展通过 targetId 在这些位置插入组件。
  • 扩展路由:routes/ 目录中的文件会自动注册为路由。
  • 扩展翻译:翻译会根据目录名自动以 extPascalCase 形式命名空间化。
  • 集成标记:在核心代码中标记扩展集成点,支持单行标记和块标记。
  • 扩展可用性在 src/extensions/config.json 中管理,每个扩展以 SFDC_EXT_* 标记为键。

使用方式

构建前的决策门(先审计基础代码)

扩展适用于添加店面尚未渲染的内容。在搭建扩展前,需确认确实需要它——重复的区块会在每次页面加载、每次测试和每次设计同步中产生成本。

在编写任何扩展代码前运行此门:

  1. 找到基础。打开 src/routes/ 中的相关路由,追踪它渲染的每个组件。
  2. 检查你打算添加的每个区块。基础是否已在该位置渲染了等效内容(描述、手风琴、徽章、横幅、标题……)?
    • 是 → 不要创建并行组件。通过 token/品牌层(CVA 变体或 brand.css 值)重新样式化,或注入到现有内容的 UITarget 槽位。添加重复区块是 bug,不是功能。
    • 否 → 扩展是合理的。继续下面的结构,并在正确的 targetId 注册它。
  3. 决定缺失内容所属的层:
    • 变更是否纯粹是视觉的(颜色、字体、间距)?
      • 是 → Token / CVA 变更(brand.css 或组件变体)。无需扩展。
      • 否 → 新结构是否仅被一个店面/垂直领域需要?
        • 是 → 在 UITarget 槽位使用扩展(本技能)。永远不要编辑核心。
        • 否 → 它是共享模式——改为向基础组件添加槽位/render-prop,让每个消费者填充它。

经验法则:扩展添加缺失的内容;它们从不重建已存在的内容。如有疑问,优先选择 UITarget 槽位或 token 覆盖,而非新组件。

扩展结构

src/extensions/my-extension/
├── target-config.json    # 目标配置(组件/提供者)
├── components/           # 扩展组件
├── routes/              # 扩展路由(自动注册)
├── locales/             # 扩展翻译(自动命名空间化)
└── providers/           # 扩展上下文提供者

目标配置

target-config.json 文件声明扩展如何集成:

{
  "components": [
    {
      "targetId": "header.before.cart",
      "path": "extensions/my-extension/components/badge.tsx",
      "order": 0
    }
  ],
  "contextProviders": [
    {
      "path": "extensions/my-extension/providers/my-provider.tsx",
      "order": 0
    }
  ]
}

目标点

目标点是店面布局中的命名插入槽位(例如 header.before.cart)。扩展通过 targetId 在这些点插入组件。

扩展可用性在 src/extensions/config.json 中管理,每个扩展以 SFDC_EXT_* 标记为键。

扩展路由

routes/ 目录中的文件会自动注册为路由:

// src/extensions/my-extension/routes/my-route.tsx
export function loader() {
    return { message: 'Hello' };
}

export default function MyRoute() {
    const { message } = useLoaderData();
    return <div>{message}</div>;
}

扩展翻译

翻译会根据目录名自动以 extPascalCase 形式命名空间化:

src/extensions/my-extension/locales/
├── en-US/translations.json
└── it-IT/translations.json
const {t} = useTranslation('extMyExtension');
t('welcome');

集成标记

在核心代码中标记扩展集成点:

// 单行标记
/** @sfdc-extension-line SFDC_EXT_MY_FEATURE */
import myFeature from '@extensions/my-feature';

// 块标记
{/* @sfdc-extension-block-start SFDC_EXT_MY_FEATURE */}
<Link to="/my-feature">My Feature</Link>
{/* @sfdc-extension-block-end SFDC_EXT_MY_FEATURE */}

适用场景

  • 需要向 Storefront Next 店面添加基础代码尚未渲染的模块化功能时。
  • 新结构仅被一个店面或垂直领域需要,且不应修改核心代码时。
  • 需要通过目标点在店面布局的特定位置插入组件时。
  • 需要为扩展添加独立路由和翻译命名空间时。

限制

  • 扩展不应重建已存在的内容;重复区块被视为 bug。
  • 纯粹视觉变更(颜色、字体、间距)应通过 token/CVA 变更实现,而非扩展。
  • 被多个消费者共享的模式应添加到基础组件的槽位/render-prop,而非扩展。
  • 永远不要编辑核心代码。

最佳实践

  • 自包含——每个扩展应独立。
  • 使用目标点——通过 target-config.json 插入 UI,而非编辑核心文件。
  • 命名空间翻译——自动命名空间化可防止冲突。
  • 顺序很重要——使用 target-config.json 中的 order 控制渲染顺序。

相关技能

  • storefront-next:sfnext-i18n - 翻译模式和命名空间用法
  • storefront-next:sfnext-routing - 扩展路由如何与路由器集成
  • storefront-next:sfnext-components - 扩展中使用的组件模式

参考文档

  • Base Audit Reference - 决策门(扩展 vs token/变体 vs 基础槽位)的示例
  • Extension Examples Reference - 完整的扩展示例