Storybook SDC 插件
此插件简化了将 Drupal 单一目录组件 (SDC) 集成到 Storybook 的过程,允许将 YAML 配置的组件(例如 *.component.yml
)动态加载为 Storybook 中的故事。
目录
- 概述
- Storybook 实时示例
- 插件特性
- 为何选择 SDC Storybook 而非其他替代方案?
- 快速入门指南
- 配置
- 设置默认值
- 创建实验性故事
- 常规 Storybook
- 配置选项
- 依赖项
- 已知问题
- UI 模式
概述
这个 Storybook 插件使得使用 YAML 配置和 Twig 模板轻松地将 Drupal 单一目录组件 (SDC) 集成到 Storybook 中。它动态加载组件,让您无需太多配置即可快速创建和管理故事。
它仍然是常规的 Storybook,但现在增加了导入和管理 Drupal 单一目录组件 (SDC) 的选项。
Storybook 实时示例
您可以查看一个Storybook 中 SDC 插件的实时示例,该示例托管在 GitHub Pages 上,展示了该仓库中 /components
目录下的组件。
插件特性
SDC Storybook 插件简化了将 Drupal 单一目录组件 (SDC) 集成到 Storybook 的过程,并提供以下几个主要特性:
- Vite 插件集成:利用 vite-plugin-twig-drupal 插件无缝加载和处理 SDC 组件中使用的 Twig 模板。
- 动态路径解析:利用命名空间动态发现项目结构中的组件,无需手动配置。
- 故事生成:根据 SDC 组件的 YAML 配置自动创建故事,简化故事创建过程。
- JSON Schema 支持:支持 props 和 slots 的 JSON Schema,能够为缺失值生成模拟数据并确保数据一致性。
- 嵌入 Drupal 行为:允许您将
Drupal.attachBehaviors()
等 Drupal 行为直接嵌入到 Storybook 预览中,确保组件行为与其在 Drupal 中一致。 - 自定义和外部 Schema 定义:支持自定义和外部 JSON schema 定义,用于根据 Drupal 特定配置(例如 UI 模式、Experience Builder)验证组件。
为何选择 SDC Storybook 而非其他替代方案?
虽然 SDC Styleguide 和 Drupal Storybook 等解决方案很有价值,但 SDC Storybook 插件提供了明显的优势:
1. 组件独立性和模块化
- 遵循 BEM(块、元素、修饰符)方法论,组件应能在不同环境中独立工作。
- 组件的功能不应依赖于 Drupal 版本或当前激活的 Drupal 主题——它应该能移植到任何系统。
2. 无需复杂的 Drupal 设置
- 进行组件开发无需安装或配置 Drupal 依赖项。
- 在 Storybook 中开发前端组件,无需运行繁重的 Drupal 实例,从而提高开发效率。
3. 简化 DevOps 和 CI/CD 流水线
- 由于组件是独立的,测试和部署变得更简单。
- 您可以在 CI 流水线中避免使用 Drupal 特定配置,从而实现更高效和易于维护的工作流程。
4. 结合 Faker.js 和 JSON Schema 提高可伸缩性和灵活性
- 像 Faker.js 这样的工具允许您为组件生成测试数据,而无需真实的网站内容。
- JSON Schema 清晰且一致地定义组件数据,有助于维护数据完整性。
5. 前端开发的行业标准工具
- Storybook 在前端开发中被广泛采用,这使得新开发者入职更容易,即使他们不熟悉 Drupal。
- JSON Schema 使得即使没有深入的 Drupal 知识也能进行组件开发,将项目开放给更广泛的开发者群体。
6. 组件中嵌入 Drupal 特定行为
- 将 Drupal 行为(例如
Drupal.attachBehaviors()
)直接嵌入 Storybook 预览中,确保 Storybook 和生产环境中的组件行为一致。 - 支持
drupalSettings
和once.js
,使得 Storybook 中的组件行为与其在 Drupal 中完全一致。
7. Twig.js 与 Drupal Twig 的对比
虽然使用 Drupal 渲染组件提供了更紧密的集成,但在许多场景下继续使用 Twig.js 具有充分的理由:
- 许多组件不需要完整的 Drupal 逻辑。基本组件(按钮、卡片、列表)依赖于简单的 HTML 和 CSS,而非复杂的模板逻辑。对于这类组件,Twig.js 提供足够的渲染能力,无需完整的 Drupal 预处理。
- Twig.js 非常适用于以前端为中心的用例。
- 样式和行为不一致问题可以在 Drupal 实现阶段单独管理。
快速入门指南
-
在主题或模块目录中,或者只是一个空目录中(如果 package.json 尚不存在):
npm init echo "node_modules/" >> .gitignore
-
安装依赖项:
npm i vite twig storybook-addon-sdc --save-dev
-
初始化 Storybook:
npx storybook@latest init --builder vite --type html --no-dev
-
移除默认的 Storybook 样板故事(可选):
rm -rf ./stories
-
按照配置中的说明进行配置.
-
将组件添加到
components
目录(或者从这个仓库复制)。 -
在 package.json 中设置 type: module
{ "type": "module" }
-
启动 Storybook:
npm run storybook
配置
要配置插件,请更新 .storybook/main.js
,如下所示:
import { join } from 'node:path' // 1. Add dependencies.
import { cwd } from 'node:process'
const config = {
stories: ['../components/**/*.component.yml'], // 2. Set components glob.
addons: [
{
name: 'storybook-addon-sdc', // 3. Configure addon.
options: {
sdcStorybookOptions: {
namespace: 'umami', // Your namespace.
},
vitePluginTwigDrupalOptions: {
// vite-plugin-twig-drupal options.
namespaces: {
umami: join(cwd(), './components'), // Your namespace and path to components.
},
},
jsonSchemaFakerOptions: {}, // json-schema-faker options.
},
},
// Any other addons.
'@storybook/addon-essentials',
'@chromatic-com/storybook',
'@storybook/addon-interactions',
],
framework: {
name: '@storybook/html-vite',
options: {},
},
}
export default config
设置默认值
为了让 json-schema-faker
生成可靠数据,请在 SDC schema 中使用 default
或 examples
。
props:
type: object
properties:
html_tag:
type: string
enum:
- article
- div
default: article
slots:
content:
title: Content
examples:
- Hello! I'm card content
请参阅
创建实验性故事
SDC YAML 文件中的 sdcStorybook
配置提供了一种灵活的方式来为组件定义自定义故事。此功能允许您使用预定义 props、自定义 slots,甚至重用在其他地方定义的故事。其工作原理如下:
配置示例
thirdPartySettings:
sdcStorybook:
stories:
grid:
props:
label: Paragraph with grid
extra_classes:
- m-paragraph--grid
slots:
content:
# 1. Basic Props and Slots
# This card uses only the basic default props and slots defined in the component YAML.
- type: component
component: 'umami:card'
# 2. Predefined Story
# This card references an existing story (e.g., "Preview")
# from the component YAML, which includes predefined props and slots.
- type: component
component: 'umami:card'
story: Preview
# 3. Custom Props and Slots
# This card defines custom props to modify its behavior (e.g., setting
# the HTML tag to 'div') and custom slots to override specific content.
- type: component
component: 'umami:card'
props:
html_tag: 'div' # Custom HTML tag for the card container
slots:
content: 'Hello from third grid card!'
实际工作原理
插件会根据定义动态渲染组件和故事:
- 基本 Args: 使用
umami:card
组件的默认Basic.args
。 - 现有故事: 加载
Preview
故事,确保 Storybook 环境中的一致性。 - 自定义 Slots 和 Props: 用该实例的独特内容覆盖默认 slots 和 props 行为。
为何故事是实验性的?
社区需要决定 YAML 故事应采用何种格式。
常规 Storybook
所有 Storybook 功能照常工作,您可以将 SDC YAML 导入到 .stories.js
中。
import header, {
Preview as HeaderPreview,
} from '../components/header/header.component.yml'
import banner, {
Preview as BannerPreview,
} from '../components/banner/banner.component.yml'
export default {
title: 'Regular Storybook Page',
render: () => {
return `
${header.component({ ...HeaderPreview.args })}
${banner.component({ ...BannerPreview.args })}
`
},
play: async ({ canvasElement }) => {
Drupal.attachBehaviors(canvasElement, window.drupalSettings)
},
}
export const Basic = {}
配置选项
除了标准配置选项外,您还可以指定 customDefs 和 externalDefs 来提供额外的 schema 定义。这些选项是可选的,可用于扩展或覆盖默认定义。
customDefs
customDefs
选项允许您直接在配置中定义自定义 schema 定义。这可以是一个包含自定义定义的对象。
示例
const options = {
sdcStorybookOptions: {
customDefs: {
'json-schema-definitions://experience_builder.module/column-width': {
title: 'Column Width',
type: 'integer',
enum: [25, 33, 50],
},
},
},
}
externalDefs
externalDefs
选项允许您指定一个外部定义文件的路径数组。这些路径可以是 CDN 托管文件的 URL 或本地文件路径。
示例
const options = {
sdcStorybookOptions: {
externalDefs: [
'https://cdn.jsdelivr.net.cn/gh/iberdinsky-skilld/sdc-addon@v0.4.3/drupal-defs/uiPatternsSchema.yml',
'https://example.com/path/to/definitions.yml',
'./local/path/to/definitions.yml',
],
},
}
使用 externalDefs 时,定义将自动获取并注册。
validate
validate
选项使用 JSON Schema 验证器为 SDC 组件启用 schema 验证。默认情况下,验证器会对照位于以下位置的全局 schema 检查组件配置:
$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
工作原理
-
全局 Schema 验证(默认): 插件使用默认的全局 schema 进行验证。此 schema 由 Drupal 提供,确保 SDC 组件符合预期的结构以及正确的数据类型和属性。
-
自定义组件 Schema: 如果某个特定的 SDC 组件包含指向自定义 schema 的
$schema
字段,则验证器将使用该 schema 进行验证,而非全局 schema。这提供了更大的灵活性和组件特定的验证能力,特别是在组件有自定义要求时。 -
验证警告: 验证错误或警告将记录到控制台,帮助开发者识别组件配置中的任何问题。注意: 验证不会中断组件的渲染。即使发生验证错误,组件仍会显示在 Storybook 中,并且警告将被记录供查看。
要启用验证,请设置 validate: schema 的 URL
const config = {
stories: ['../components/**/*.component.yml'],
addons: [
{
name: 'storybook-addon-sdc',
options: {
sdcStorybookOptions: {
validate:
'https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json',
},
},
},
],
}
依赖项
- vite-plugin-twig-drupal:加载带有 Drupal 函数的 Twig。
- json-schema-faker:为缺失的 props 生成模拟数据,以及
- JSON Schema 验证器
已知问题
- 此插件依赖于实验性索引器。
UI 模式
- 部分支持 Variants (问题 #3390712)。
- 不支持自定义 Twig 过滤器和函数 (UI Patterns TwigExtension)。