# 简介

该项目用于子模块/子应用定义、注册、加载、数据共享。对于子应用,该组件为非必要组件。

# 安装

npm i @jmodule/client

# 工作流程

  1. 注册子应用
JModule.registerModules([
    key: 'childAppKey', // 子应用 ID
    url: '', // 子应用的加载地址
    type: 'app', // 由宿主应用自己定义。在 @jmodule/helper/host 中提供了常用的默认类型定义。
    resourceLoadStrategy: ResourceLoadStrategy.Fetch, // 可选,默认为 Element,子应用的资源加载策略,通过 script 脚本直接加载或通过fetch方式加载。
]);

TIP

  1. 当使用 @jmodule/plugin-webpack 进行开发时,会自动从配置文件注入注册子应用的脚本,所以在 demo 中并没有使用这部分代码,但生产环境仍需要手动注册子应用。
  2. @jmodule/helper 中封装了常用的子应用类型定义,参考 Demo: host-vue2/src/jmodule/index.js。
  1. 加载子应用
const module = JModule.getModule('childAppKey');
module.load();

// 等待加载完成
await module.hooks.complete;

2.1 加载子应用脚本

根据指定的不同加载策略,会通过script脚本加载子应用脚本 或 通过fetch获取资源后执行。

2.2 执行子应用代码 JModule.define 完成初始化

load() 完成后,子应用中的 JModule.define 函数将会执行,该函数将向宿主应用提供必要的信息:挂载/卸载的具体实现(或 routes 等信息)、共享组件、依赖关系声明等。

TIP

如果子应用不想额外下载 @jmodule/client,使用全局的 JModuleManager.define 也可以等价替换。对于常用的 JModule.require 也提供了等价的 JModuleManager.require 使用。

  1. 将子应用挂载到页面上
JModule.mount('childAppKey').activate(wrapperElement);
  1. 将子应用从页面上卸载
JModule.mount('childAppKey').deactivate();

# 主要部件

# JModule

import { JModule } from '@jmodule/client';

用于注册子应用、加载子应用、挂载子应用、卸载子应用、共享宿主/子应用组件等操作。

# JModuleManager

const manager = window.JModuleManager;

全局函数,且唯一。用于 JModule 的管理,并提供了一系列便捷的接口。其主要作用是,当主子应用都安装了 @jmodule/client 组件、或者出现多层应用嵌套时,能对引入的不同 JModule 进行管理。

# Resource

import { Resource } from '@jmodule/client';

用于加载子应用资源。资源入口文件类型可以是 json/js, 后续考虑提供扩展接口以支持更多类型的入口文件类型。

# ResourceLoadStrategy

import { ResourceLoadStrategy } from '@jmodule/client';

资源加载策略, 在执行 registerModules 时为每个应用指定,默认为 Element。 提供了 Element 和 Fetch 两种策略。

如何选择:

-- Element Fetch
跨域 支持良好 需要额外配置
sourceMap 支持良好 不支持 sourceMapUrl, 可以内嵌(开发模式)
样式隔离 仅支持动态 link 标签的移除 link + style
js沙箱 无法提供可靠支持 可以通过 Hook 扩展
对子应用代码的侵入性 较高
子应用运行环境可控性
建议适用场景 常规应用或开发模式 复杂应用

# ModuleHook

import { ModuleHook } from '@jmodule/client';

封装了同步/异步执行流程。Resource/JModule 都继承自 ModuleHook,用以扩展 JModule/Resource 的功能。

具体参考:宿主应用开发者