@equinor/fusion-framework-plugin-context-navigation

中文文档
1.1.1发布于 2026/11/12TypeScriptES Module零依赖近 30 天下载 6725

基于适应器的合并框架门户上下文与URL调和器

中文使用文档
文档目录21 节
  1. 何时使用
  2. 对于应用程序开发者
  3. 宣布路线战略
  4. 自定义URL形状
  5. 用于门户开发者
  6. 关键概念
  7. 如何运作
  8. 安装
  9. 快速启动
  10. 端口(应用程序开关铅)
  11. 上下文门户( 文本更改铅)
  12. 内建适应器
  13. 注册自定义适配器
  14. 配置
  15. 活动
  16. 跳过原因
  17. 拦截导航
  18. 适配器接口
  19. 出口
  20. 同伴依赖关系
  21. 另见

上下文导航插件( E)@equinor/fusion-framework-plugin-context-navigation(中文(简体) )

Fusion Framework门户网站由事件驱动的上下文到URL调节器插件. 它通过对上下文变化和app开关的反应,将上下文编码入URL,以及可选地防范手动URL编辑来降低上下文来保持活性上下文与浏览器URL同步.

何时使用

当您的插件 门户 需要:

  • 自动反映浏览器 URL 中的活性上下文( 项目、 设施等)
  • 支持多个 URL 编码策略( 路径段、 查询参数, 或 app自定义自定义编码)
  • 在整个应用程序开关和页面重载中保留上下文
  • 通过手动编辑 URL 防止用户意外丢失上下文

[注] 此插件用于 门户主机,而不是个人申请. 应用程序通过应用程序的显示表来声明其首选的路由策略 build.options.contextRouting 字段——门户的上下文导航插件 抓取该声明并自动应用正确的 URL 编码 .

对于应用程序开发者

您不需要安装或配置此插件 。 门户能处理. 你唯一的责任是 声明上下文应如何出现在您的 URL。 。 。 .

宣布路线战略

设定 contextRouting 在你的应用清单 build.options数字 :

// app.manifest.config.ts
export default defineAppManifest((env) => ({
  // ...
  build: {
    options: {
      contextRouting: 'query',  // or 'path', or omit for default path behavior
    },
  },
}));
数值URL 形状何时使用
'path' (或省略)/apps/{appKey}/{contextId}/sub-route默认——没有复杂路由的简单应用程序
'query'/apps/{appKey}/route?$contextId={id}与上下文段相冲突的基于路径的子路由应用程序

有自定义 URL 形状的应用程序应当省略 contextRouting 并登记自定义钩(见下文).

[注] 何时 contextRouting 未设定( 或设定为 null),门户默认为 路径适配器 将上下文编码为应用程序键后的一个路径段. 如果应用程序注册自定义钩( I)setContextPathExtractor 编号 : setContextPathGenerator),自定义适配器优先于路径 路径/默认路由的适配器 。 明确 contextRouting: 'query' 选择 查询适配器,即使已注册自定义路径钩.

自定义URL形状

如果您的应用程序将上下文编码为非标准位置( 例如 ) . /route-a/{contextId} 改为 /{contextId}/route-a),在应用程序上下文中注册自定义钩 配置 :

// app config
builder.setContextPathExtractor((pathname) => {
  // Extract context id from your custom URL position
  const segments = pathname.split('/').filter(Boolean);
  return segments[1]; // e.g. /route-a/{contextId} → contextId
});

builder.setContextPathGenerator((context, pathname) => {
  // Generate a URL with context in your custom position
  const segments = pathname.split('/').filter(Boolean);
  const route = segments[0] ?? '';
  return `/${route}/${context.id}`;
});

当这些钩子注册后, 插件的自定义适配器会将其取出 自动——无显示 contextRouting 需要声明.

应用程序拥有其 URL 形状, 因此 URL 是 URL 守护的真实来源 :

  • 提取器未返回上下文的路由( 例如列表页, 如 /categories)是一条路线 无 上下文。 URL 守护器没有设置 积极的背景 回到它.
  • 提取器返回不活动上下文的路由(例如链接) 从列表页到 /app/{key})在推动和 替换模式,并在无上下文活动时替换.
  • 在无上下文的路由中清除上下文使用户保持在那里. 在有上下文导航到应用根的路径上清除上下文 .
  • 在没有上下文的路由中选择上下文仍然导航到 路径从 generatePathFromContext。 。 。 .

提取值不一定是上下文 ID。 如果这是一把钥匙或一发子弹, uRL 守护器将 URL 视为同步 generatePathFromContext 写入 对当前环境的同样价值。 所以在同一个背景中航行 不会再解决了 返回路径不变的生成器不会 来证明什么,所以守护者从 URL 中解析值. 在不相干的路由片段中重复的密钥不会触发另一个查询.

当 URL 守护从 URL 中解析上下文时, 查找属于此 URL (中文(简体) ). 如果用户在搜索完成前在别处导航, 守卫 取消它:迟到的结果既不改变上下文,也不改变用户的方向. 应用软件解职、应用开关和模块装入也取消了等待检查, 甚至在下一个导航事件之前,或者当目的地没有上下文模块时.

用于门户开发者

本README的其余部分涵盖门户级设置和配置.

关键概念

概念说明
适配器自选URL编码器/解码器. 每个适配器宣布 canHandle() 提供 encode() 编号 : decode() 方法。 。 .
调试器监视上下文+应用程序变化并触发URL出同步后导航的被动循环.
URL 守护如果外部导航将上下文从 URL 掉出, 可选的二次订阅会重新应用上下文编码 .
来源驱动调和器的可观察工厂——决定是应用开关还是上下文变化优先.

如何运作

  1. 观察 ——调节器通过可配置源厂来监视当前应用和当前上下文.
  2. 解析适配器 - 对于每个应用程序,第一个适配器 canHandle() 返回时 true 已选定.
  3. 编码 ——所选适配器将上下文编码为目标URL.
  4. 比较 ——如果目标URL与当前URL不同,则导航会继续.
  5. 调度 - 可取消的 onContextNavigationNavigate 事件火灾。 听者可以打电话 preventDefault() 以中止.
  6. 导航 ——框架导航模块实现URL更新.
  7. 确认 - 一个 onContextNavigationNavigated 导航完成后发生事件起火.

安装

pnpm add @equinor/fusion-framework-plugin-context-navigation

快速启动

端口(应用程序开关铅)

一个应用门户网站一次显示一个应用. 当用户切换应用时, 调节器 取出新应用程序的上下文并将其编码入URL. 这是默认行为.

import { enableContextNavigation } from '@equinor/fusion-framework-plugin-context-navigation';

export const configure = (configurator) => {
  enableContextNavigation(configurator, (builder) => {
    builder.setPortalName('app-portal');
    builder.setDebug(true);
  });
};

默认源厂( E)createAppFirstSource手表( 手表 ) app.current$ 财务报告和审定财务报表 在向调和器发送前先解决应用程序的上下文模块。 当应用程序 切换发生,新应用程序的活性上下文驱动URL更新.

上下文门户( 文本更改铅)

环绕一个共同的环境(例如一个项目)组织一个上下文门户。 当 用户选择上下文,导航立即更新 URL ——无论 该应用程序已激活。 清除上下文可返回门户根 .

import { enableContextNavigation } from '@equinor/fusion-framework-plugin-context-navigation';
import { createContextFirstSource } from '@equinor/fusion-framework-plugin-context-navigation/sources';

export const configure = (configurator) => {
  enableContextNavigation(configurator, (builder) => {
    builder.setPortalName('context-portal');
    builder.setSourceFactory(createContextFirstSource());
    builder.setNullContextUrl('/');
    builder.setDebug(true);
  });
};

与app-portal的关键差异 :

  • createContextFirstSource() ——上下文变化为主触发;应用模块作为依赖解决.
  • setNullContextUrl('/') – 当上下文被清除后, 导航到出入口登陆页面, 而不是授权适配器 .

内建适应器

装有3个适配器的插件船按优先顺序评估:

适配器URL 形状选中时
自定义App 定义( 通过 generatePathFromContext 编号 : extractContextIdFromPath 钩子)App 提供自定义钩子, 不声明 contextRouting: 'query'
查询/apps/{appKey}/route?$contextId={id}应用显示声明 build.options.contextRouting: 'query'
路径/apps/{appKey}/{contextId}/sub-route默认倒计时——匹配 contextRouting 实值 'path', (中文(简体) ), null,或省略

当没有注册自定义适配器时,所有三个内置适配器都可以使用. 第一个 canHandle() 返回时 true 当前应用程序获胜.

注册自定义适配器

您可以为内置集未覆盖的 URL 形状注册自己的适配器 . 这个 canHandle 选择适配器时的上方控件——使用任何信号 备查 AdapterResolutionContext (app key, URL, 上下文提供者, 路由策略).

import type { ContextNavigationAdapter } from '@equinor/fusion-framework-plugin-context-navigation/adapters';

const hashAdapter: ContextNavigationAdapter = {
  id: 'hash',
  // Select this adapter for a specific app that uses hash-based context
  canHandle: ({ appKey }) => appKey === 'my-hash-app',
  encode: ({ context, currentURL }) => {
    const url = new URL(currentURL.href);
    url.hash = context ? `#ctx=${context.id}` : '';
    return url;
  },
  decode: (url) => {
    const match = url.hash.match(/^#ctx=(.+)$/);
    return match?.[1] ?? null;
  },
};

enableContextNavigation(configurator, (builder) => {
  builder.registerAdapter(hashAdapter);
  // NOTE: registering any adapter disables built-in defaults.
  // Register all adapters you need explicitly.
});

配置

构建方法默认说明
registerAdapter(adapter)内置套装登记导航适配器(对象或工厂)。 第一场比赛获胜.
setPortalName(name)'Portal'调试日志输出中使用的名称 .
setOrigin(origin)window.location.origin构建绝对 URL 的出处 .
setUrlGuard(enabled)true如果外部导航从 URL 中掉入, 则重新同步上下文 。 与 replace: false,后向导航从 URL 更新上下文,而不是覆盖上下文。 带有自定义路径钩子的 Apps 总是将 URL 视为真理的来源(参见 自定义URL形状) (中文(简体) ).
setDebug(enabled)false启用动词 console.debug 输出.
setNullContextUrl(urlOrFn)—— 说函数( 或静态字符串) , 将 URL 返回到上下文被清除时的导航 。 接收 { appKey, currentURL }。 。 。 .
setRequireValidContext(enabled)false对照 app 上下文模块验证上下文( )validateContext)通航前. 如果验证失败, 导航会被跳过 .
setNavigationOptions(options){ replace: true }转到 navigation.navigate() uRL更新期间。 设定 { replace: false } 来将历史条目推出 —— 然后从 URL 同步上下文, 而不是重新输入活动上下文 .
setOnTransition(fn)—— 说副作用钩在每次成功导航后呼叫.
setSourceFactory(factory)createAppFirstSource()驱动调和器的可观察源厂.

活动

该插件通过Fusion框架事件系统发送事件. 通过 framework.event.addEventListener()。 。 。 .

活动何时可取消
onContextNavigationNavigate在导航——适配器解决之前,目标 URL 计算对
onContextNavigationNavigated导航完成后没有
onContextNavigationAdapterResolved当为应用程序选择适配器时没有
onContextNavigationSkipped当调节决定不导航时没有

跳过原因

这个 onContextNavigationSkipped 事件包括a reason 字段 :

原因含义
'url-matches'目标 URL 已经匹配当前 URL
'no-context'上下文为 undefined (仍在初始化)
'no-adapter'没有适配器能处理当前应用程序
'invalid-app-context'setRequireValidContext(true) 设置, 且应用程序上下文模块拒绝上下文
'encode-returned-null'适应者 encode() 已返回 null
'canceled'一个听众打电话 preventDefault() 导航事件

拦截导航

framework.event.addEventListener('onContextNavigationNavigate', (event) => {
  console.log('About to navigate:', event.detail.targetURL.pathname);

  // Cancel navigation conditionally
  if (shouldBlock(event.detail)) {
    event.preventDefault();
  }
});

适配器接口

interface ContextNavigationAdapter {
  /** Unique identifier for logging and diagnostics. */
  id: string;
  /** Return `true` if this adapter handles the given app/URL combination. */
  canHandle(ctx: AdapterResolutionContext): boolean;
  /** Encode context into a URL. Return `null` to skip navigation. */
  encode(args: { context: ContextItem | null; currentURL: URL }): URL | null;
  /** Decode a context ID from a URL. Return `null` if not present. */
  decode(url: URL): string | null;
}

interface AdapterResolutionContext {
  appKey: string;
  appContext: IContextProvider;
  routingStrategy?: 'path' | 'query' | null;
  currentURL: URL;
}

出口

指定者说明
@equinor/fusion-framework-plugin-context-navigation插件运行时间、 配置器、 启用助手、 类型、 事件
@equinor/fusion-framework-plugin-context-navigation/adapters内建适配工厂(createPathAdapter, (中文(简体) ), createQueryAdapter, (中文(简体) ), createCustomAdapter(中文(简体) )
@equinor/fusion-framework-plugin-context-navigation/sources来源工厂(createAppFirstSource, (中文(简体) ), createContextFirstSource)和调节器类型
@equinor/fusion-framework-plugin-context-navigation/utilsURL 工具函数

同伴依赖关系

软件包目的
@equinor/fusion-framework-module基本单元合同
@equinor/fusion-framework-module-app应用程序切换和实例加载
@equinor/fusion-framework-module-context国家管理
@equinor/fusion-framework-module-navigationURL 导航
@equinor/fusion-framework-module-event事件发送
rxjs反应流

另见

版本与发布记录

@equinor/fusion-framework-plugin-context-navigation 共发布 17 个版本,首次发布于 2026/08/06;过去 12 个月发布了 17 个版本。

版本发布日期距今
1.1.1latest2026/11/121 天前
1.1.1-next.1next2026/11/112 天前
1.1.1-next.02026/10/2816 天前
1.1.02026/10/2717 天前
1.0.62026/10/1727 天前
1.0.52026/10/1629 天前

其他发布通道:trusted-publishing-20261015 → 1.0.5-trusted-publishing-20261015-9dfe7602cd2a49a8a9df00d62c26e7304a82a85a,next → 1.1.1-next.1。

关于 @equinor/fusion-framework-plugin-context-navigation 的常见问题

@equinor/fusion-framework-plugin-context-navigation 是什么?

基于适应器的合并框架门户上下文与URL调和器

如何安装 @equinor/fusion-framework-plugin-context-navigation?

在项目目录运行 npm install @equinor/fusion-framework-plugin-context-navigation,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:rxjs(^7.8.1)、@equinor/fusion-framework-module(^6.2.0)、@equinor/fusion-framework-module-app(^8.3.0)、@equinor/fusion-framework-module-event(^6.1.4)、@equinor/fusion-framework-module-context(^9.1.0)、@equinor/fusion-framework-module-navigation(^8.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@equinor/fusion-framework-plugin-context-navigation 支持 TypeScript 吗?

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

@equinor/fusion-framework-plugin-context-navigation 支持 ESM 还是 CommonJS?

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

@equinor/fusion-framework-plugin-context-navigation 可以商用吗?

@equinor/fusion-framework-plugin-context-navigation 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@equinor/fusion-framework-plugin-context-navigation 的下载量有多少?

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

@equinor/fusion-framework-plugin-context-navigation 还在维护吗?

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