@equinor/fusion-framework-module

中文文档
6.2.0发布于 2026/11/12ISCTypeScriptES Module近 30 天下载 1.7万
原始使用文档
文档目录18 节
  1. Key Concepts
  2. Module
  3. ModulesConfigurator
  4. BaseConfigBuilder
  5. BaseModuleProvider
  6. Documentation
  7. Installation
  8. Quick Start — Defining a Module
  9. Exports
  10. Main Entry Point ( @equinor/fusion-framework-module )
  11. Configurator Sub-path ( @equinor/fusion-framework-module/co…
  12. Plugins Sub-path ( @equinor/fusion-framework-module/plugins…
  13. Provider Sub-path ( @equinor/fusion-framework-module/provid…
  14. Module Lifecycle
  15. Cross-module dependencies with requireInstance
  16. postInitialize and the full modules map
  17. Plugins and host-level side effects
  18. Related Packages

@equinor/fusion-framework-module

Core module system for Fusion Framework. This package defines the contracts, base classes, and orchestration logic that every Fusion Framework module relies on.

Use this package when you are authoring a new module or need to understand how the module lifecycle works. Application developers typically consume modules through higher-level packages such as @equinor/fusion-framework-react.

Key Concepts

Module

A Module is a plain object that declares a name, an optional configuration factory, an initialize method, and optional lifecycle hooks (postConfigure, postInitialize, dispose). Modules are the building blocks of a Fusion application.

ModulesConfigurator

ModulesConfigurator orchestrates the full module lifecycle:

  1. Configure – each module's configure() factory creates a config builder; registered callbacks mutate it; postConfigure() hooks run.
  2. Initialize – modules are initialized concurrently; cross-module dependencies are resolved through requireInstance().
  3. Post-initialize – postInitialize() hooks and onInitialized callbacks run.
  4. Plugins – registered plugins connect host-level side effects after every module is ready.

The result is a sealed ModulesInstance whose property names match the module keys and whose values are the initialized providers.

BaseConfigBuilder

An abstract class for building module configuration declaratively. Subclasses expose typed setter methods (e.g. setBaseUrl) that register callbacks. During initialization the framework collects all registered callbacks, resolves them, and merges the results into a single configuration object.

BaseModuleProvider

Abstract base class for module providers (the runtime instances returned by initialize()). It manages a Subscription container for automatic teardown and exposes a SemanticVersion for compatibility checks.

Documentation

TopicDescription
ConceptsModule system overview, roles, and mental model
LifecycleConfigure → initialize → post-initialize → dispose phase sequence
ConfigurationHow to register modules and use addConfig / configure
Cross-Module DependenciesrequireInstance pattern for inter-module dependencies
PluginsregisterPlugin, createPlugin, plugin teardown, and host-level side effects
Eventsevent$ observable and event naming conventions
Authoring ModulesStep-by-step guide for creating a custom module
Common MistakesFAQ-style pitfalls and how to avoid them

Installation

pnpm add @equinor/fusion-framework-module

Quick Start — Defining a Module

import {
  type Module,
  BaseConfigBuilder,
  type ConfigBuilderCallback,
} from '@equinor/fusion-framework-module';
import { BaseModuleProvider } from '@equinor/fusion-framework-module/provider';

// 1. Define the configuration shape
interface GreeterConfig {
  greeting: string;
}

// 2. Create a config builder
class GreeterConfigurator extends BaseConfigBuilder<GreeterConfig> {
  setGreeting(cb: ConfigBuilderCallback<string>) {
    this._set('greeting', cb);
  }
}

// 3. Create a provider
class GreeterProvider extends BaseModuleProvider<GreeterConfig> {
  #config: GreeterConfig;

  greet(name: string): string {
    return `${this.#config.greeting}, ${name}!`;
  }

  constructor(args: { version: string; config: GreeterConfig }) {
    super(args);
    this.#config = args.config;
  }
}

// 4. Define the module
export const greeterModule: Module<'greeter', GreeterProvider, GreeterConfigurator> = {
  name: 'greeter',
  configure: () => new GreeterConfigurator(),
  initialize: async ({ config }) => {
    const resolved = await config.createConfigAsync({
      config: {},
      hasModule: () => false,
      requireInstance: () => Promise.reject('no modules'),
    });
    return new GreeterProvider({ version: '1.0.0', config: resolved });
  },
};

Exports

Main Entry Point (@equinor/fusion-framework-module)

ExportKindDescription
ModuletypeInterface describing a module's structure and lifecycle hooks
ModulesConfiguratorclassOrchestrates configure → initialize → plugin → dispose for a set of modules
IModulesConfiguratorinterfacePublic contract for the modules configurator
IModuleConfiguratorinterfaceDescriptor for registering a single module with lifecycle hooks
BaseConfigBuilderclassAbstract config builder with dot-path targeting and observable pipelines
ConfigBuilderCallbacktypeCallback signature used by config builder setters
ConfigBuilderCallbackArgstypeArguments passed to config builder callbacks
ModuleConfigBuilderclassDeprecated – use BaseConfigBuilder instead
initializeModulesfunctionConvenience wrapper around configurator.initialize()
SemanticVersionclassExtended SemVer with a satisfies() method
ModuleConsoleLoggerclassStyled console logger with module-name formatting
IModuleConsoleLoggerinterfaceLogger interface with formatModuleName
DotPath, DotPathType, DotPathUniontypesRecursive dot-notation path utilities

Configurator Sub-path (@equinor/fusion-framework-module/configurator)

ExportKindDescription
ModuleConfiguratorEventBaseNameconstShared ModuleConfigurator base segment for configurator lifecycle event names
ModuleConfiguratorEventNameobjectMap of ModuleConfigurator.{name}.{state} event names for filtering event$ without hard-coded strings

Plugins Sub-path (@equinor/fusion-framework-module/plugins)

ExportKindDescription
createPluginfunctionCreates a named plugin callback for stable lifecycle diagnostics
FrameworkPluginArgstypeArguments passed to inline plugin callbacks: initialized modules and optional ref
FrameworkPluginCallbacktypeCallback accepted by IModulesConfigurator.registerPlugin
FrameworkPluginTeardowntypeCleanup callback or disposable object returned by a plugin
FrameworkPluginRegistrationtypePlugin return type: teardown or undefined
FrameworkPlugininterfaceNamed plugin callback returned by createPlugin
FrameworkPluginInitializertypeDeveloper-facing callback signature used by createPlugin

Provider Sub-path (@equinor/fusion-framework-module/provider)

ExportKindDescription
IModuleProviderinterfaceContract every module provider must satisfy
BaseModuleProviderclassAbstract base with version, subscription management, and dispose
BaseModuleProviderCtorArgstypeConstructor arguments for BaseModuleProvider

Module Lifecycle

┌─────────────────────────────────────────────────────┐
│                  ModulesConfigurator                 │
├──────────┬──────────────────────────┬────────────────┤
│ Phase    │ Module Hook              │ Consumer Hook  │
├──────────┼──────────────────────────┼────────────────┤
│ Configure│ module.configure()       │ addConfig()    │
│          │ module.postConfigure()   │ onConfigured() │
├──────────┼──────────────────────────┼────────────────┤
│ Init     │ module.initialize()      │                │
│          │ module.postInitialize()  │ onInitialized()│
├──────────┼──────────────────────────┼────────────────┤
│ Plugin   │                          │ registerPlugin │
├──────────┼──────────────────────────┼────────────────┤
│ Dispose  │ module.dispose()         │ instance.      │
│          │                          │  dispose()     │
└──────────┴──────────────────────────┴────────────────┘

Cross-module dependencies with requireInstance

Modules initialize concurrently. Use requireInstance(name, timeout?) inside initialize to wait for a dependency:

initialize: async ({ config, requireInstance, hasModule }) => {
  // Wait for the event module (with optional timeout in ms)
  const event = await requireInstance('event', 5000);
  return new MyProvider(config, event);
},

requireInstance returns a promise that resolves when the requested module finishes initializing. If the module is not registered, the promise rejects.

postInitialize and the full modules map

postInitialize runs after all modules are initialized. It receives the full modules map, making it the right place for cross-module wiring that depends on every module being ready:

postInitialize: async ({ instance, modules }) => {
  // All modules are available here
  modules.event.addEventListener('onContextChanged', (e) => {
    instance.handleContextChange(e.detail);
  });
},

configure and initialize are the two required hooks. postConfigure, postInitialize, and dispose are optional.

Plugins and host-level side effects

Use registerPlugin for application-owned wiring that needs the complete module instance before render. Plugins run after postInitialize and onInitialized, but before initialize() resolves. Return a teardown callback to clean up subscriptions, global listeners, timers, or telemetry bindings during dispose.

import { createPlugin } from '@equinor/fusion-framework-module/plugins';

const contextTelemetryPlugin = createPlugin<[typeof eventModule, typeof telemetryModule]>(
  'contextTelemetry',
  (modules) => modules.event.addEventListener('context:changed', (event) => {
    modules.telemetry.track('context.changed', event.detail);
  }),
);

configurator.registerPlugin(contextTelemetryPlugin);

See Plugins for teardown rules, failure behavior, and API reference.

Events are emitted on configurator.event$ throughout the lifecycle for telemetry and debugging.

  • @equinor/fusion-framework-react – React bindings and hooks for consuming modules
  • @equinor/fusion-framework-module-http – HTTP client module built on this system
  • @equinor/fusion-framework-module-service-discovery – Service discovery module

版本与发布记录

@equinor/fusion-framework-module 共发布 136 个版本,首次发布于 2022/01/14;过去 12 个月发布了 17 个版本。

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

其他发布通道:apploader → 4.4.3-apploader-be21a6b60eb13eee8bf869e75002d8634e9c50a9,cli-search-index → 5.0.6-cli-search-index.0,msal-v5 → 5.0.6-msal-v5.0,trusted-publishing-20261015 → 6.1.6-trusted-publishing-20261015-9dfe7602cd2a49a8a9df00d62c26e7304a82a85a,next → 6.2.0-next.1。

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

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

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

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

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

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

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

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

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

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

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

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

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