feature-flags
작성자: facebook
React 기능 플래그를 채널 전반에 걸쳐 관리하고, 조건부로 게이트 테스트를 수행하며, 플래그별 테스트 실패를 디버깅합니다. 네 개의 플래그 파일이 기본값과 채널별 오버라이드(canary, www, React Native, test renderer)를 제어하며, __VARIANT__ 플래그는 두 상태 모두에서 테스트되는 게이트키퍼를 시뮬레이션합니다. @gate flagName 프래그마를 사용하여 플래그를 사용할 수 없을 때 테스트를 완전히 건너뛰거나, 동작이 다를 때 인라인 gate()를 사용하여 어설션을 분기합니다. 새 플래그를 추가하려면 메인 파일과 모든 포크 파일에 항목을 입력해야 합니다.
npx skills add https://github.com/facebook/react --skill feature-flagsReact Feature Flags
Flag Files
| File | Purpose |
|---|---|
packages/shared/ReactFeatureFlags.js | Default flags (canary), __EXPERIMENTAL__ overrides |
packages/shared/forks/ReactFeatureFlags.www.js | www channel, __VARIANT__ overrides |
packages/shared/forks/ReactFeatureFlags.native-fb.js | React Native, __VARIANT__ overrides |
packages/shared/forks/ReactFeatureFlags.test-renderer.js | Test renderer |
Gating Tests
@gate pragma (test-level)
Use when the feature is completely unavailable without the flag:
// @gate enableViewTransition
it('supports view transitions', () => {
// This test only runs when enableViewTransition is true
// and is SKIPPED (not failed) when false
});
gate() inline (assertion-level)
Use when the feature exists but behavior differs based on flag:
it('renders component', async () => {
await act(() => root.render(<App />));
if (gate(flags => flags.enableNewBehavior)) {
expect(container.textContent).toBe('new output');
} else {
expect(container.textContent).toBe('legacy output');
}
});
Adding a New Flag
- Add to
ReactFeatureFlags.jswith default value - Add to each fork file (
*.www.js,*.native-fb.js, etc.) - If it should vary in www/RN, set to
__VARIANT__in the fork file - Gate tests with
@gate flagNameor inlinegate()
Checking Flag States
Use /flags to view states across channels. See the flags skill for full command options.
__VARIANT__ Flags (GKs)
Flags set to __VARIANT__ simulate gatekeepers - tested twice (true and false):
/test www <pattern> # __VARIANT__ = true
/test www variant false <pattern> # __VARIANT__ = false
Debugging Channel-Specific Failures
- Run
/flags --diff <channel1> <channel2>to compare values - Check
@gateconditions - test may be gated to specific channels - Run
/test <channel> <pattern>to isolate the failure - Verify flag exists in all fork files if newly added
Common Mistakes
- Forgetting both variants - Always test
wwwANDwww variant falsefor__VARIANT__flags - Using @gate for behavior differences - Use inline
gate()if both paths should run - Missing fork files - New flags must be added to ALL fork files, not just the main one
- Wrong gate syntax - It's
gate(flags => flags.name), notgate('name')