Communitygithub.com

featurevisor/featurevisor

撰寫、測試、查詢並整合 Featurevisor 功能開關、A/B 實驗與遠端設定。適用於 Featurevisor 專案 (featurevisor.config.js) 中的功能、區隔、屬性、全域變數與組合、條件、逐步發布、測試規格與情境、資料檔、目標對象、集合與推廣、目錄與 CLI,以及解釋為何某個脈絡會取得某個值。也適用於 JavaScript、React、Vue 及其他語言的 Featurevisor SDK、OpenFeature 提供者、CLI 外掛,以及從 v2 或 v3 升級。單獨在 Featurevisor 專案外發出一個通用的功能開關請求是不夠的。

featurevisor 是什麼?

這個技能涵蓋了 Featurevisor 的兩個核心面向:專案端與應用端。在專案端,使用者可以透過 YAML 或 JSON 檔案來定義功能開關、區隔、屬性與全域變數,並使用 CLI 進行 lint、測試與建置靜態資料檔。在應用端,SDK 會載入這些資料檔並在本地端評估,無需每次都向後端發送請求,從而實現高效且穩定的功能管理。 這個技能對於處理 Featurevisor 專案中的定義與查詢至關重要,特別是在處理複雜的條件邏輯、逐步發布規則以及 A/B 測試情境時。它支援多種框架與語言的 SDK,包括 JavaScript、React 與 Vue,並提供 OpenFeature 提供者以實現與其他工具鏈的整合。此技能也詳細說明了從 v2 或 v3 升級的注意事項,確保使用者能順利遷移至最新版本。 使用此技能時,開發者需先確認專案版本與形狀(如是否使用環境或集合),並遵循「定義完成」的循環:每次修改後執行 lint 與測試,以確保變更正確且不影響現有用戶體驗。技能內建了「危險變更」的警示機制,例如重新命名規則鍵或調整區隔百分比時,會明確告知使用者哪些用戶可能受到影響,避免無預警的變動。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/featurevisor/featurevisor/tree/HEAD/skills/featurevisor

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

featurevisor 是做什麼的?

您正在協助使用者使用 Featurevisor,一個透過 Git 進行功能管理的工具。Featurevisor 專案是一個存放 YAML(預設)或 JSON 定義的儲存庫。CLI 會對這些定義進行 lint 與測試,並建置靜態 JSON 資料檔,應用程式再透過 SDK 在本地端進行評估。每個任務都屬於以下兩側之一:

  • 專案端:撰寫與查詢定義(功能、區隔、屬性、全域變數、測試),並執行 featurevisor CLI。
  • 應用端:載入資料檔並透過 SDK(@featurevisor/sdk、React、Vue 或其他語言)進行評估。

此技能涵蓋兩者,適用於 Featurevisor v4。文件索引位於 https://featurevisor.com/llms.txt,完整文本位於 https://featurevisor.com/llms-full.txt。當下列參考資料未涵蓋某個主題時,請擷取這些文件。

了解您的受眾

工程師、產品經理、行銷人員,以及那些能描述需求但不熟悉 YAML 語法的人,都會使用 Featurevisor。請調整您的應對方式:

  • 轉譯意圖。「為 10% 的荷蘭使用者啟用橫幅」是一個逐步發布規則。請自行進行對應,然後以他們的語言回報結果:改變了什麼、影響了誰、以及接下來會發生什麼事。
  • 例行變更: 提高百分比、在通用規則之上新增規則、新增功能、為 QA 強制啟用功能。請自信地執行這些操作。
  • 危險變更: 重新命名規則鍵、更改 bucketBy、更改變體權重、降低百分比、封存仍被參考的項目。這些操作會將使用者在不同結果之間移動。請明確告知(「部分使用者會在中途中斷功能」),並在繼續之前進行確認。
  • 完成循環。 變更後,用一兩句話說明上線後的影響。例如:「一旦此合併請求合併且 CI 部署了資料檔,約 10% 的荷蘭使用者會看到橫幅,其他所有人都看不到任何東西。」
  • 提供目錄 給任何想以視覺化方式檢視專案而非閱讀 YAML 的人(透過目錄進行視覺化審查)。

首先進行導航

此技能中的範例使用預設支架,該支架沒有環境。當專案設定了環境時,請在 evaluate、benchmark、assess-distribution 和 build --print 指令中加入 --environment=<名稱>。一般的檔案建置會涵蓋所有環境。

還沒有專案?先訪談,再初始化

如果工作目錄中沒有 featurevisor.config.js,就表示沒有 Featurevisor 專案。如果使用者在一個應用程式儲存庫中,這屬於 SDK 的工作:請參閱應用程式整合 (SDK),並在專案儲存庫中撰寫定義,而不是在這裡。如果他們想要一個新專案,請先詢問以下問題,因為之後撰寫的每個檔案都取決於這些答案:

  1. 環境? 預設沒有環境,規則是直接列表。--example=with-environments 會提供明確的 staging 和 production。
  2. 集合? 預設為否。僅在需要獨立審查的樹狀結構時才提供集合:例如從開發環境推廣到測試環境再到正式環境的發布管道,或是互不相關的介面(例如商店前台和後台管理)。請先閱讀 sets-promotions.md。
  3. 消費者? 單一應用程式可以使用預設的 all 目標,該目標沒有選擇器,並包含所有作用中的定義。多個介面通常會使用標籤(例如 web、ios 和 android),並為每個介面設定一個目標。
  4. 檔案格式? YAML(預設)或 JSON。
  5. 如何識別使用者? userId、deviceId,或兩者皆用(bucketBy: { or: [userId, deviceId] })。Lint 要求每個功能都必須有 bucketBy,因此這決定了每個功能宣告的內容以及屬性的優先順序。

在一個空目錄、獨立的儲存庫中進行初始化,與應用程式程式碼分開:

npx @featurevisor/cli@latest init
npm install

--example=with-environments 會提供環境鍵控規則,--example=environments 會將集合作為發布管道,而 --example=sets 則會提供獨立的介面。CLI 設定表格 列出了所有範例。然後根據訪談的答案調整 featurevisor.config.js。templates/example-project/ 是一個完整的 v4 專案,可通過 lint 和測試,可作為了解各部分如何組合的參考。

已有專案?在接觸任何內容之前先偵測版本與形狀

確認專案在其套件資訊清單和鎖定檔中已安裝 @featurevisor/cli,並透過 npm ls @featurevisor/cli 確認。然後從專案中執行已安裝的 CLI:

npx featurevisor --version

它必須解析專案自己的二進位檔。如果遺失或 npx 提供下載套件的選項,請停止並詢問如何還原專案的鎖定依賴項。不要為了偵測版本而安裝遠端 CLI 或升級依賴項。

  • 4.x:此技能中的所有內容都適用。
  • 3.x:v3 語法不同。它在規則中使用 segments 和 requiredFeatures 而不是統一的 conditions,並且缺少變數條件、組合、continue、測試 checks、情境和多個運算子。不要在 v3 專案中寫入 v4 語法。請保持在 upgrading-to-v4.md 列出的 v3 語法範圍內,並在請求需要 v4 時提供升級。
  • 2.x:形狀如 scopes:、environments/ 目錄或應用程式程式碼中的 createInstance。請先提供 upgrading-to-v3.md。

消費者決定您可以發布什麼。 v4 資料檔需要 v4 SDK:v3 SDK 無法理解統一的 conditions,因此規則會停止匹配。資料檔的 schemaVersion 僅供參考,不會讓舊版 SDK 拒絕該檔案。在引入執行時期功能(例如累積覆寫或較新的運算子)之前,請確認每個消費該資料檔的應用程式的 SDK 版本。如果不確定,請詢問使用者。請根據 SDK 相容性矩陣 檢查每個版本。原生版本號碼不同,因此不要假設每個相容的 SDK 都是 4.x 版。CLI lint 成功並不能保證執行時期支援。測試檢查和情境需要相容的 CLI 執行器,這是一個與消費者支援什麼分開的問題。

然後讀取設定:

npx featurevisor config --json --pretty
npx featurevisor info

四個值會改變您撰寫的所有內容的形狀:

  • sets:當為 true 時,每個定義都位於 sets/<set>/ 下,並且指令會帶入 --set。請先閱讀 sets-promotions.md。
  • environments:當宣告時,功能的 rules、force 和 expose,以及全域變數的 overrides,是按環境鍵控的映射。如果沒有,它們就是直接的列表,而 expose 是布林值或標籤列表。
  • parser:對於 "json" 使用 JSON,對於 "yml"(預設)使用 YAML,或使用已設定的自訂格式 (custom-parsers.md)。
  • namespaceCharacter:用於子目錄的鍵分隔符。預設為 .,因此 features/checkout/promo.yml 是 checkout.promo。有些專案使用 /。每個參考都必須使用專案的分隔符。請使用 npx featurevisor list --segments --json 對真實鍵進行確認。

另外請注意 tags(您使用的每個標籤都必須被宣告)、disallowOperators、allowedConditions,以及目錄覆寫(例如 featuresDirectoryPath)。然後在新增新定義之前,先閱讀一兩個現有的定義以符合本地風格。

Featurevisor 如何組合

定義路徑用途
屬性 (Attribute)attributes/<key>.yml宣告一個脈絡鍵及其型別。永不命名空間化。
區隔 (Segment)segments/<key>.yml透過 conditions 為一個受眾命名。
功能 (Feature)features/<key>.yml一個開關、可選的變體和功能變數,包含逐步發布規則。會進行分桶。
全域變數 (Global variable)variables/<key>.yml一個帶有排序覆寫的型別值,或是一個由其他值 compose 而成的值。永不進行分桶。
架構 (Schema)schemas/<key>.yml一個可重複使用的變數形狀。
目標 (Target)targets/<key>.yml哪些定義會進入資料檔。
測試規格 (Test spec)tests/**/*.spec.yml功能、區隔和變數的斷言,以及獨立的情境。

條件 (Conditions) 是一種在定義選擇或閘控的任何地方都使用的語法:區隔、規則、強制項目、根閘控和覆寫。一個葉節點比較一個屬性、用一個裸字串命名一個區隔、要求一個功能,或比較一個變數的值。列表代表 AND,而 and、or 和 not 群組可以巢狀。'*' 匹配所有人,但僅限於整個表達式。

conditions:
  - attribute: country
    operator: equals
    value: nl
  - payingAccounts # 一個裸字串始終是一個區隔鍵
  - feature: liveChat # 要求 liveChat 已啟用
  - variable: maintenanceMode
    operator: equals
    value: false

評估順序。 一個功能的開關會檢查一個黏性值,然後檢查該功能是否在資料檔中,接著是第一個匹配的強制項目,然後是根 conditions,然後是第一個條件匹配的規則,最後是該規則相對於使用者分桶的百分比。未命中百分比不會回退到下一個規則。一個全域變數會檢查一個黏性值,然後是根 conditions,然後是組合來源(如果有的話),然後是第一個匹配的覆寫(以及後續的覆寫,如果一個覆寫設定了 continue: true),最後是其預設值。詳細資訊:features.md 和 global-variables.md。

核心撰寫規則

參考資料會增加深度,但它們永遠不會覆蓋這些規則。

1. 分桶與規則鍵是契約

  • bucketBy 在百分比變更時保持每個使用者的結果穩定。選擇一次後就不要默默更改。
  • 已登入的介面按 userId 分桶,匿名的按 deviceId 分桶,混合的按 { or: [userId, deviceId] } 分桶。屬性名稱在不同專案之間有所不同:請讀取 attributes/,並在不明確時詢問該使用哪個。切勿發明屬性名稱。
  • 規則鍵在每個列表中必須是唯一的(當設定環境時,每個環境內),並且在為使用者分桶後不得更改。狀態檔案會根據鍵儲存每個規則的變體範圍,因此重新命名會重新分配它們。請新增一個新規則,而不是重新命名。

2. 第一個匹配的規則獲勝

規則從上到下執行。將狹義的規則(例如某個國家 100%)放在通用規則 conditions: '*' 之上。一旦規則匹配,其百分比決定結果,而未達到百分比的使用者不會回退到後續的規則。

3. 僅參考已存在的內容

確認您參考的每個屬性、區隔、功能和變數都已存在,或者建立它。也要檢查 featurevisor.config.js 中的 allowedConditions:它可以限制每個位置接受哪些類型的條件,例如只允許命名區隔的規則 (conditions.md)。Lint 會拒絕未知的參考。如果一個被封存的定義被一個未被封存的定義或規格所參考,它也會拒絕 archived_reference。一個被封存的定義會從資料檔中移除,因此對它的參考會默默地停止匹配,而在 not 下則會匹配所有人。Lint 只會檢查被封存定義的形狀,因此它們使用的內容之後可以更改或消失。對一個已棄用定義的參考是一個 deprecated_reference 警告。在封存、重新命名或刪除任何東西之前,請執行 npx featurevisor find-usage,並優先選擇封存而非刪除:被封存的檔案保留了該鍵。

4. 變體權重總和為 100

每個值都是唯一的。control 和 treatment 只是慣例。如果權重總和不為 100,Lint 會拒絕。在 CLI 4.0.0 中它不會,因此在該版本中請自行檢查總和:一個短時間的分割可以建置一次,但之後每次建置都會失敗,並出現 Invalid saved variation allocation。對於互斥的實驗,請參閱 mutual-exclusion.md。

5. 條件在不同 SDK 之間保持可攜帶性

每個 SDK 都評估相同的資料檔,因此 lint 強制執行一個可攜帶的子集:

  • 日期 (before、after) 採用完整的 ISO 8601 時間戳記,包含時區,並用引號括起來:'2026-11-27T00:00:00Z'。僅日期和無時區的值會導致 lint 失敗。兩個運算子都是嚴格的。
  • 版本 (semver*) 是帶引號的字串,例如 '5.5' 或 '5.5.0',因此 YAML 會將它們保留為文字。
  • 正規表達式 (matches、notMatches) 只允許 g、i、m 和 s 標誌,並拒絕所有 (? 結構,包括非捕獲群組 (?:…),以及反向參考和佔有量詞。
  • 運算子會根據宣告的型別進行檢查。一個 type: string 且 format: date-time 的屬性只能接受 before、after 和存在性運算子,而 in 接受一個字串列表。

詳細資訊和 lint 訊息:operators.md。

6. 符合專案的形狀

環境、集合、解析器和命名空間分隔符會改變相同請求的撰寫方式。範本使用沒有環境的預設形狀。在一個有環境的專案中,請將每個 rules、force 或全域 overrides 列表放在其環境鍵下,並將 environment 加入測試中。

完成的定義

每次變更後都要執行這個循環。這是你證明變更達成了使用者要求的方式,也為你提供了回報的證據。

  1. Lint。 npx featurevisor lint 必須通過。使用 --json 時,每個錯誤都包含 filePath、path、message 和 code,因此你可以修復確切的欄位。修復後重新執行:有些錯誤只有在修正了前面較高層級的錯誤後才會出現。
  2. 測試。 npx featurevisor test 必須通過。確認每個宣告的新行為都有對應的測試。如果改變了一個百分比或規則,請更新受影響的功能的測試,並調整期望的百分比。
  3. 如果專案使用目錄: 檢查 npx featurevisor validate-catalog 的輸出。目錄可以包含定義中未提及的資訊,因此你必須手動檢查。
  4. 建置資料檔。 npx featurevisor build。這是最終的輸出。
  5. 評估(可選但有幫助)。 npx featurevisor evaluate --feature <key> --context <json>。用於驗證一個給定的脈絡會得到預期的值。--environment 用於環境專案。
  6. 回報。 總結變更內容:建置是否成功、是否對分桶有所變動,以及使用者下一步會體驗到什麼。

快速參考

CLI 常用指令

指令用途
npx featurevisor lint檢查所有定義的語法與引用完整性
npx featurevisor test執行測試規格與情境
npx featurevisor build建置最終的 JSON 資料檔
npx featurevisor evaluate --feature <key> --context <json>為特定脈絡評估功能的值
npx featurevisor find-usage <key>找出某個定義在哪些地方被參考
npx featurevisor config --json --pretty以 JSON 格式顯示專案設定
npx featurevisor info顯示專案統計資訊

延伸閱讀

相關技能