」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 了解功能標誌:簡單指南

了解功能標誌:簡單指南

發佈於2024-11-02
瀏覽:559

Understanding Feature Flags: A Simple Guide

构建软件时,快速发布新功能而不破坏任何内容可能很棘手。功能标志使这变得更容易。在阅读了 Vercel 的功能标志 SDK 后,我认为进一步研究功能标志并解释它们是什么、它们如何工作以及如何自己构建一个功能标志会很有帮助。

什么是功能标志?

功能标志(也称为功能切换)允许开发人员打开或关闭功能,而无需更改代码或重新部署应用程序。这意味着您可以:

  • 逐步发布功能:只让部分用户看到新功能,慢慢向所有人推出。
  • 在生产环境中测试新功能:您可以为自己或一小群测试人员启用该功能,而不需要将其提供给所有用户。
  • 快速回滚功能:如果新功能导致问题,您可以禁用它而无需重新部署。

使用功能标志,您可以控制用户何时可以访问功能,与部署代码的时间分开。

为什么要使用功能标志?

  1. 持续交付

    功能标志帮助团队更频繁地发布代码。您可以将未完成的工作合并到主代码库中,将其隐藏在标志后面,然后在不影响用户的情况下进行部署。

  2. A/B 测试

    您可以使用不同的用户组测试某个功能的两个版本,看看哪个版本性能更好。这有助于基于真实数据改善用户体验。

  3. 受控部署

    您可以向一小群用户发布一项功能,监控其性能,然后将其发布给其他所有人。

  4. 快速回滚

    如果出现问题,关闭功能标志比恢复代码更改要快得多,有助于保持应用程序稳定。

将 Next.js 中的功能标志与 Vercel 的 Flags SDK 结合使用

flags.ts(服务器端)

import { unstable_flag as flag } from "@vercel/flags/next";

export const showBanner = flag({
  key: "banner",
  decide: () => false,
});

决定函数确定标志的值,该值可以从各种来源提供,例如:

  • 环境变量
  • 其他功能标志提供商
  • Vercel 的 Edge Config(数据配置存储)
  • 数据库等

app/page.tsx

import { showBanner } from "../flags";

export default async function Page() {
  const banner = await showBanner();
  return (
    
{banner ? : null} {/* other components */}
); }

由于标志是函数,我们可以轻松地更改实现,而无需修改调用方的任何内容。这种灵活性使您的应用程序能够适应新的要求,而无需更改标志逻辑的核心结构。

如何构建您自己的功能标记系统

让我们构建一个简单的功能标记系统,您可以随着时间的推移对其进行改进。

第 1 步:创建用于检索功能标志的自定义挂钩

此步骤涉及创建一个自定义挂钩,该挂钩将允许您动态检索功能标志。您可以轻松地在 React 应用程序的任何部分重用此钩子来检查某个功能是否启用或禁用。

import { useState, useEffect } from 'react';

export const useFeatureFlag = (key: string): boolean => {
  const [isEnabled, setIsEnabled] = useState(false);

  useEffect(() => {
    const fetchFeatureFlag = async () => {
      try {
        const response = await fetch(`http://localhost:3001/api/feature-flags/${key}`);
        if (response.ok) {
          const data = await response.json();
          setIsEnabled(data.is_enabled);
        }
      } catch (error) {
        console.error('Failed to fetch feature flag:', error);
      }
    };

    fetchFeatureFlag();
  }, [key]);

  return isEnabled;
};

第2步:反应组件

接下来,创建一个组件,该组件使用自定义挂钩根据该标志是启用还是禁用来呈现不同的功能。这将使您的应用程序能够在新旧功能之间无缝切换,而不会对用户体验造成任何干扰。

import React from 'react';
import { useFeatureFlag } from './useFeatureFlag';

const FeatureFlaggedComponent: React.FC = () => {
  const isNewFeatureEnabled = useFeatureFlag('new-feature');

  return (
    

Feature Flag Example

{isNewFeatureEnabled ? (

New Feature

This is the new feature enabled by the feature flag.

) : (

Old Feature

This is the old feature displayed when the new feature is disabled.

)}
); }; export default FeatureFlaggedComponent;

市场上的其他功能标记解决方案

构建您自己的功能标记系统对于小型项目很有用,但如果您与更大的团队合作或需要更高级的控制,有几种工具提供功能标记作为服务:

  1. Vercel 功能标志

    Vercel 提供与其平台集成的功能标志,允许实时控制哪些用户看到哪些功能。

  2. 启动Darkly

    LaunchDarkly 是一种用于大规模管理功能标志的流行工具。它支持复杂的部署,根据位置或行为等属性定位用户。

  3. 优化

    优化专注于实验和 A/B 测试,使用功能标志来测试不同的功能并改善用户体验。

  4. Split.io

    Split.io 允许团队在不同功能版本之间划分流量并实时跟踪性能指标。

  5. Hypertune

Hypertune 是功能标记领域的新玩家,专注于高性能实验和功能切换。它使团队能够以最小的延迟运行复杂的实验,确保实时的性能洞察。 Hypertune 的独特方法将功能标记与机器学习模型相集成,从而可以在功能推出和用户定位方面做出更智能的决策。

结论

功能标志是安全发布功能、在生产中测试以及快速更改而无需重新部署代码的绝佳方式。您可以使用 JavaScript 构建一个简单的功能标记系统,或者针对大型项目使用 Vercel、LaunchDarkly 或 Optimizely 等更高级的工具。

使用功能标志将使您的开发过程更加灵活和高效,使您能够更快、更自信地交付新功能。

感谢您的阅读,欢迎留言分享您的意见!

版本聲明 本文轉載於:https://dev.to/ramk777stack/understanding-feature-flags-a-simple-guide-4on6?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 為什麼不````''{margin:0; }`始終刪除CSS中的最高邊距?
    為什麼不````''{margin:0; }`始終刪除CSS中的最高邊距?
    在CSS 問題:不正確的代碼: 全球範圍將所有餘量重置為零,如提供的代碼所建議的,可能會導致意外的副作用。解決特定的保證金問題是更建議的。 例如,在提供的示例中,將以下代碼添加到CSS中,將解決餘量問題: body H1 { 保證金頂:-40px; } 此方法更精確,避免了由全局保證金重置...
    程式設計 發佈於2025-06-09
  • 在程序退出之前,我需要在C ++中明確刪除堆的堆分配嗎?
    在程序退出之前,我需要在C ++中明確刪除堆的堆分配嗎?
    在C中的顯式刪除 在C中的動態內存分配時,開發人員通常會想知道是否需要手動調用“ delete”操作員在heap-exprogal exit exit上。本文深入研究了這個主題。 在C主函數中,使用了動態分配變量(HEAP內存)的指針。當應用程序退出時,此內存是否會自動發布?通常,是。但是,即使在...
    程式設計 發佈於2025-06-09
  • 如何限制動態大小的父元素中元素的滾動範圍?
    如何限制動態大小的父元素中元素的滾動範圍?
    在交互式接口中實現垂直滾動元素的CSS高度限制,控制元素的滾動行為對於確保用戶體驗和可訪問性是必不可少的。一種這樣的方案涉及限制動態大小的父元素中元素的滾動範圍。 問題:考慮一個佈局,其中我們具有與用戶垂直滾動一起移動的可滾動地圖div,同時與固定的固定sidebar保持一致。但是,地圖的滾動無限...
    程式設計 發佈於2025-06-09
  • 可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    程式設計 發佈於2025-06-09
  • 如何同步迭代並從PHP中的兩個等級陣列打印值?
    如何同步迭代並從PHP中的兩個等級陣列打印值?
    同步的迭代和打印值來自相同大小的兩個數組使用兩個數組相等大小的selectbox時,一個包含country代碼的數組,另一個包含鄉村代碼,另一個包含其相應名稱的數組,可能會因不當提供了exply for for for the uncore for the forsion for for ytry...
    程式設計 發佈於2025-06-09
  • 如何檢查對像是否具有Python中的特定屬性?
    如何檢查對像是否具有Python中的特定屬性?
    方法來確定對象屬性存在尋求一種方法來驗證對像中特定屬性的存在。考慮以下示例,其中嘗試訪問不確定屬性會引起錯誤: >>> a = someClass() >>> A.property Trackback(最近的最新電話): 文件“ ”,第1行, AttributeError: SomeClass...
    程式設計 發佈於2025-06-09
  • Android如何向PHP服務器發送POST數據?
    Android如何向PHP服務器發送POST數據?
    在android apache httpclient(已棄用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    程式設計 發佈於2025-06-09
  • 為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    為什麼儘管有效代碼,為什麼在PHP中捕獲輸入?
    在php ;?>" method="post">The intention is to capture the input from the text box and display it when the submit button is clicked.但是,輸出...
    程式設計 發佈於2025-06-09
  • 如何使用替換指令在GO MOD中解析模塊路徑差異?
    如何使用替換指令在GO MOD中解析模塊路徑差異?
    在使用GO MOD時,在GO MOD 中克服模塊路徑差異時,可能會遇到衝突,其中3個Party Package將另一個PAXPANCE帶有導入式套件之間的另一個軟件包,並在導入式套件之間導入另一個軟件包。如迴聲消息所證明的那樣: go.etcd.io/bbolt [&&&&&&&&&&&&&&&&...
    程式設計 發佈於2025-06-09
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-06-09
  • Java的Map.Entry和SimpleEntry如何簡化鍵值對管理?
    Java的Map.Entry和SimpleEntry如何簡化鍵值對管理?
    的綜合集合:在Java中介紹Java的Map.entry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry和SimpleEntry apry and Map。 地圖。它具有兩個通用...
    程式設計 發佈於2025-06-09
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    程式設計 發佈於2025-06-09
  • Go語言垃圾回收如何處理切片內存?
    Go語言垃圾回收如何處理切片內存?
    Garbage Collection in Go Slices: A Detailed AnalysisIn Go, a slice is a dynamic array that references an underlying array.使用切片時,了解垃圾收集行為至關重要,以避免潛在的內存洩...
    程式設計 發佈於2025-06-09
  • 對象擬合:IE和Edge中的封面失敗,如何修復?
    對象擬合:IE和Edge中的封面失敗,如何修復?
    To resolve this issue, we employ a clever CSS solution that solves the problem:position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%)...
    程式設計 發佈於2025-06-09
  • Java中假喚醒真的會發生嗎?
    Java中假喚醒真的會發生嗎?
    在Java中的浪費喚醒:真實性或神話? 在Java同步中偽裝喚醒的概念已經是討論的主題。儘管存在這種行為的潛力,但問題仍然存在:它們實際上是在實踐中發生的嗎? Linux的喚醒機制根據Wikipedia關於偽造喚醒的文章,linux實現了pthread_cond_wait()功能的Linux實現,...
    程式設計 發佈於2025-06-09

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3