@equinor/fusion-framework-module-feature-flag

中文文档
2.2.0发布于 2026/11/12ISCTypeScriptES Module近 30 天下载 5092
原始使用文档
文档目录27 节
  1. Features
  2. Installation
  3. Usage
  4. Register the module
  5. Read flags at runtime
  6. Toggle flags programmatically
  7. Fetch flags from an API
  8. API Reference
  9. Main exports ( @equinor/fusion-framework-module-feature-fla…
  10. Plugin exports ( @equinor/fusion-framework-module-feature-f…
  11. Selector exports ( @equinor/fusion-framework-module-feature…
  12. Mock exports ( @equinor/fusion-framework-module-feature-fla…
  13. Operational telemetry
  14. Testing
  15. Defaults
  16. Configuration
  17. Plugin lifecycle
  18. Local Storage
  19. Url
  20. Custom
  21. Selectors
  22. Filter features
  23. Find feature
  24. Events
  25. onFeatureFlagToggle
  26. onFeatureFlagsToggled
  27. Usage

@equinor/fusion-framework-module-feature-flag

Fusion Framework module for managing feature flags in applications. Provides a plugin-based architecture for defining, persisting, and toggling feature flags from multiple sources such as local storage, URL query parameters, or a remote API.

Features

  • Plugin architecture — compose multiple flag sources (local storage, URL, API) into one provider.
  • Local-storage persistence — toggled flags survive page reloads via createLocalStoragePlugin.
  • URL toggle — enable or disable flags through query parameters with createUrlPlugin.
  • Remote API — fetch flags from an HTTP endpoint using createApiPlugin.
  • Observable state — subscribe to flag changes via RxJS observables.
  • Framework events — emits onFeatureFlagToggle (cancelable) and onFeatureFlagsToggled when the event module is present.
  • Typed values — flags can carry a generic typed payload (IFeatureFlag<T>).

Installation

pnpm add @equinor/fusion-framework-module-feature-flag

Usage

Register the module

import { enableFeatureFlagging } from '@equinor/fusion-framework-module-feature-flag';
import {
  createLocalStoragePlugin,
  createUrlPlugin,
} from '@equinor/fusion-framework-module-feature-flag/plugins';

export const configure = (configurator) => {
  enableFeatureFlagging(configurator, (builder) => {
    // Persist toggled state in localStorage
    builder.addPlugin(
      createLocalStoragePlugin([
        { key: 'dark-mode', title: 'Dark mode' },
        { key: 'beta-search', title: 'Beta search', enabled: false },
      ]),
    );
    // Allow toggling via URL: ?beta-search=true
    builder.addPlugin(createUrlPlugin(['beta-search']));
  });
};

Read flags at runtime

const featureFlags = modules.featureFlag;

// Check a single flag
if (featureFlags.getFeature('dark-mode')?.enabled) {
  applyDarkTheme();
}

// Observe changes
featureFlags.features$.subscribe((features) => {
  console.log('Current flags:', features);
});

Toggle flags programmatically

await featureFlags.toggleFeature({ key: 'dark-mode', enabled: true });

Fetch flags from an API

import { createApiPlugin } from '@equinor/fusion-framework-module-feature-flag/plugins';

builder.addPlugin(
  createApiPlugin({
    httpClientName: 'my-api',
    path: '/feature-flags',
  }),
);

API Reference

Main exports (@equinor/fusion-framework-module-feature-flag)

ExportDescription
enableFeatureFlaggingRegisters the module on a configurator with an optional builder callback.
featureFlagModule / defaultModule descriptor for manual registration.
FeatureFlagProviderManages flag state, toggling, and subscriptions.
FeatureFlagConfiguratorBuilder for registering plugins during configuration.
IFeatureFlag<T>Interface describing a single feature flag.
FeatureFlagPluginInterface for plugins that supply and persist flags.

Plugin exports (@equinor/fusion-framework-module-feature-flag/plugins)

ExportDescription
createLocalStoragePluginPersists flag state in localStorage (or sessionStorage).
createUrlPluginReads flag state from URL query parameters on navigation.
createApiPluginFetches flags from a remote HTTP endpoint.

Selector exports (@equinor/fusion-framework-module-feature-flag/selectors)

ExportDescription
filterFeaturesRxJS operator that filters an observable feature map by a selector function.
findFeatureRxJS operator that emits a single flag matching a key or predicate.

Mock exports (@equinor/fusion-framework-module-feature-flag/mock)

ExportDescription
enableFeatureFlagMockRegisters the module with an in-memory FeatureFlagMockConfigurator instead of a real plugin.
featureFlagMockModuleModule descriptor for manual registration.
FeatureFlagMockConfiguratorBuilder with addFeature/setFeatures for seeding flags in-memory.

Operational telemetry

IFeatureFlagProvider extends TelemetryConnectable. The provider uses telemetry.scope('feature-flag'), with a lazy factory fallback for older custom providers; closing the handle cancels pending toggles once and prevents late reporting. Toggle summaries remain specific to this module.

When the host registers telemetry, each toggleFeature/toggleFeatures call reports one fusion.feature-flag.toggle.duration outcome with requested, applied, rejected (unregistered or read-only) and cancelled (listener veto or superseded listener work) counts. Bulk toggles retain their existing latest-only application behavior; superseded listeners count as cancelled before the call's outcome is exported. A call whose applicable flags were all vetoed is cancelled; a toggle still awaiting listeners when the module is disposed is cancelled with reason disposed. The module now disposes its provider at host teardown, which also releases plugin connections. Reads such as hasFeature are never recorded, and feature keys and values are never exported. See Operational telemetry.

Testing

Import from @equinor/fusion-framework-module-feature-flag/mock to seed flags in-memory instead of depending on localStorage or the URL. The real FeatureFlagProvider, toggling, and subscriptions still run — only the flag source is substituted.

import { enableFeatureFlagMock } from '@equinor/fusion-framework-module-feature-flag/mock';

enableFeatureFlagMock(configurator, (mock) => {
  mock.addFeature({ key: 'my-flag', enabled: true });
});

Defaults

No flags are assumed by default. A test that seeds nothing gets an empty features object, matching the real module's zero-plugin behavior. setFeatures seeds several flags and addFeature adds or replaces one flag by key. Toggling still runs through the real FeatureFlagProvider; the mock substitutes only the initial flag source.

Configuration

The module is configured through enableFeatureFlagging(configurator, callback). Inside the callback you receive an IFeatureFlagConfigurator builder with the following methods:

MethodDescription
addPlugin(handler)Registers a custom plugin factory.
enableLocalFeatures(...args)Shortcut for createLocalStoragePlugin (deprecated).
enableUrlToggle(...args)Shortcut for createUrlPlugin.

Plugin lifecycle

  1. During configuration each plugin factory is registered via addPlugin.
  2. At module initialisation every factory is called with ConfigBuilderCallbackArgs.
  3. Each plugin returns its initial() flags and an optional connect() hook.
  4. The provider merges all initial flags and invokes connect() so plugins can subscribe to toggle events (e.g. to persist changes).
  5. the configurator return an instance of the config
  6. the module create a provider instance
  7. the provider connects the plugins
  8. the provider subscribes to toggle actions and connects plugin toggle handlers
  9. the module returns the feature flag module to the framework
export interface FeatureFlagPlugin {
    /**
     * connect the plugin to the provider
     */
    connect: (args: { provider: IFeatureFlagProvider }) => VoidFunction | Subscription;

    /**
     * generate initial value for the provider
     */
    initial?: () => ObservableInput<Array<IFeatureFlag>>;
}

Local Storage

import { createLocalStoragePlugin } from '@equinor/fusion-framework-module-feature-flag/plugins';

plugin for allowing to store the toggled state of a feature flag

Url

import { createUrlPlugin } from '@equinor/fusion-framework-module-feature-flag/plugins';

plugin for toggling features threw url search params

Custom

initial

async callback function which returns the initial feature flags of the plugin

connect

async callback which allows the plugin to connect to the feature flag provider

import { 
  enableFeatureFlagging, 
  type FeatureFlagPluginConfigCallback 
} from '@equinor/fusion-framework-module-feature-flag';

const customPlugin: FeatureFlagPluginConfigCallback = async (args) => {
  const myModule = await args.requireModule('my-module');
  return {
    initial: () => fetch('/api/features')
      .then(res => res.json())
      .then(features => features.map(feature => feature.source = 'my-source')),
    connect: ({provider}) => {
      /** subscribe to changes of feature flags */
      provider.onFeatureToggle: async({flags}) => {
        await fetch(
          '/api/me/features', 
          { 
            method: 'PATCH', 
            body: flags.filter(feature => feature.source === 'my-source')
          }
        )
      }
      /** update feature flags */
      signalR.received(data => {
        provider.setFeatures(data.map(feature => feature.source = 'my-source'));
      });
    },
  }
}

// ...configuration
enableFeatureFlagging(builder => {
  builder.addPlugin(customPlugin);
})

Selectors

Filter features

Operator function for filtering out specific features

import { filterFeatures } from '@equinor/fusion-framework-module-feature-flag/selectors';
const features$ = modules.featureFlag.feature$.pipe(
  filterFeatures(x => x.enabled = true);
);

Find feature

Operator for selecting a specific feature

[!IMPORTANT] The operator will not re-emit unless value or selector changes

import { findFeature } from '@equinor/fusion-framework-module-feature-flag/selectors';
const feature$ = modules.featureFlag.feature$.pipe('my-key');

Events

onFeatureFlagToggle

Event fired before a feature is toggled

onFeatureFlagsToggled

Event fired after features are toggled (state updated)

Usage

// my-code.ts
const provider = modules.featureFlag;
const fooEnabled = provider.getFeatures('foo').enabled;
console.log('feature foo is ', fooEnabled ? 'enabled' : 'disabled');

版本与发布记录

@equinor/fusion-framework-module-feature-flag 共发布 77 个版本,首次发布于 2024/01/12;过去 12 个月发布了 20 个版本。

版本发布日期距今
2.2.0latest2026/11/121 天前
2.2.0-next.1next2026/11/112 天前
2.2.0-next.02026/10/2816 天前
2.1.32026/10/1727 天前
2.1.3-trusted-publishing-20261015-9dfe7602cd2a49a8a9df00d62c26e7304a82a85atrusted-publishing-202610152026/10/1629 天前
2.1.22026/10/121 个月前

其他发布通道:apploader → 1.1.19-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9,cli-search-index → 1.1.27-cli-search-index.0,msal-v5 → 1.1.28-msal-v5.0,trusted-publishing-20261015 → 2.1.3-trusted-publishing-20261015-9dfe7602cd2a49a8a9df00d62c26e7304a82a85a,next → 2.2.0-next.1。

关于 @equinor/fusion-framework-module-feature-flag 的常见问题

如何安装 @equinor/fusion-framework-module-feature-flag?

在项目目录运行 npm install @equinor/fusion-framework-module-feature-flag,或使用 pnpm add / yarn add / bun add。

@equinor/fusion-framework-module-feature-flag 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@equinor/fusion-framework-module-feature-flag 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@equinor/fusion-framework-module-feature-flag 可以商用吗?

@equinor/fusion-framework-module-feature-flag 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@equinor/fusion-framework-module-feature-flag 的下载量有多少?

根据 npm 官方下载统计,@equinor/fusion-framework-module-feature-flag 在 2026/10/14 – 2026/11/12 这 30 天内被下载 5,092 次,日均约 170 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@equinor/fusion-framework-module-feature-flag 还在维护吗?

最新版本 2.2.0 发布于 2026/11/12(1 天前);至今共发布 77 个版本,其中过去 12 个月发布了 20 个;首次发布于 2024/01/12。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。