关于 setting-feature-flags-in-storybook
介绍如何在 Storybook 故事中设置功能标志,说明布尔标志和变体值的参数写法,并解释命令式更新为何可能导致视觉回归快照不正确。
主要功能
- 01通过故事参数设置布尔标志
- 02用记录语法固定变体值
- 03在同一记录中混用布尔值与变体
- 04留意参数的浅层替换行为
- 05按需准备其他运行时状态
适用场景
- 01渲染启用布尔标志的故事
- 02对比使用不同实验变体的故事
- 03避免视觉回归快照呈现标志关闭分支
- 04配置依赖额外运行时状态的故事
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ posthog/ posthog --skill setting-feature-flags-in-storybook安装后在 Claude Code 中输入/setting-feature-flags-in-storybook确认已加载。
详细介绍
在 Storybook 中设置功能标志
警告
切勿在 story 中调用
featureFlagLogic.actions.setFeatureFlags(...)。它在视觉回归运行时会静默地变成空操作(渲染标志关闭分支),但在 jest 中却能通过——因此单元测试保持通过,快照却是错误的。请改用featureFlagsstory 参数。
**思维模型:**布尔标志始终有效(它们会合并到始终存在的基线中);变体值则需要一个门控,只有 featureFlags 参数能正确打开这个门控。
如何使用
这是稳定的约定——优先使用它,而不是下文“底层实现”中的任何内容。
布尔标志(标志只需开启)
const meta: Meta = {
title: 'Scenes/MyScene',
parameters: {
featureFlags: [FEATURE_FLAGS.MY_FLAG, FEATURE_FLAGS.OTHER_FLAG],
},
}
数组中的条目是求值结果为 true 的标志。这是最常见的情况。
多变量标志(固定特定变体)
对于值为变体字符串的标志(实验分组、多变量发布),请使用记录形式——数组形式只能表示 true:
// meta-level: applies to every story in the file
parameters: { featureFlags: { [FEATURE_FLAGS.THEME_OVERRIDE]: 'intent_plus' } }
// per-story: a different arm per story
export const ControlArm: Story = {
parameters: { featureFlags: { [FEATURE_FLAGS.THEME_OVERRIDE]: 'control' } },
}
export const TreatmentArm: Story = {
parameters: { featureFlags: { [FEATURE_FLAGS.THEME_OVERRIDE]: 'intent_plus' } },
}
可以在同一条记录中混用布尔值和变体:{ 'some-bool-flag': true, 'my-experiment': 'test_b' }。
重要
story 的
parameters会替换 meta 的parameters(浅合并),因此单个 story 的featureFlags会丢弃 meta 级别设置的所有标志。请重新列出仍需要的所有 meta 标志——静默丢失某个标志会渲染标志关闭分支,而且很容易被忽略。
为什么直观的做法会失败
以命令式方式设置标志(featureFlagLogic.actions.setFeatureFlags)在 jest
(NODE_ENV==='test')中有效,但在构建后的视觉回归 Storybook 中无效。posthog-js 会加载标志,并以空集合触发 onFeatureFlags,继而分发 setFeatureFlags,清除你以命令式方式设置的内容——因此单元测试通过,但快照渲染的是标志关闭分支。featureFlags 参数会将标志写入始终合并的基线(见下文),从而避免空回调覆盖它们。
不要尝试通过禁用 posthog-js 标志来解决此问题(例如
advanced_disable_feature_flags)。 应用外壳(appLogic.showApp)通常会等到receivedFeatureFlags为true,而这个值由同一个onFeatureFlags回调设置——如果抑制该回调,每个Scenes-App/*story 都会卡在 3s 超时之后,并出现不稳定失败。 登录页面是一个有意设置的例外:在/login上没有用户时,showApp无需等待标志即可渲染。登录 story 仍需使用featureFlags参数来确保标志状态确定。
底层实现(实现细节——可能会变化)
这里解释了该参数为何有效,供你了解原理,也供任何扩展测试框架的人参考。 应将上文“如何使用”视为约定,而不是本节内容。
withFeatureFlags → setFeatureFlags(frontend/src/mocks/browser.tsx)会将标志(数组或记录)直接写入
window.POSTHOG_APP_CONTEXT.persisted_feature_flags。
getPersistedFeatureFlags(frontend/src/lib/logic/featureFlagLogic.ts)会将其读取为
featureFlagLogic 的初始值,而 spyOnFeatureFlags 始终会将它合并为基线——因此布尔值和固定的变体都能在空的 onFeatureFlags 回调后保留下来。生产端唯一需要的支持,是让 getPersistedFeatureFlags
除了接受服务端的数组形式之外,也接受记录形式(变体值)。
你不需要修改这里的任何内容。如果要扩展测试框架,这就是需要衔接的位置。
另请参阅
featureFlags 参数只控制标志。如果组件的渲染还依赖其他运行时状态(localStorage、某个 APP_CONTEXT 字段,或会解析条目的 kea logic),也请设置这些状态——通常可以用一个小型包装器,让 story 渲染它;包装器会设置状态,并在渲染组件前挂载逻辑。请将包装器保留在 story 文件中;不要为了让生产组件可渲染而添加仅用于测试的 props。