# 介绍

@jmodule/helper 是一个快速接入 JModule 的工具,通常它适用于绝大部分的应用。

# 背景

如果想通过 @jmodule/client 来创建一个宿主应用, 可能并不是一件容易的事,你会发现:

  1. 它没有约定子应用采用什么方式挂载,有可能子应用只提供一些组件用于插件系统的实现
  2. 它没有约定子应用应该如何定义 mount/unmount,或者可能根本需要这些,比如基于动态路由的挂载
  3. 它没内置的流程去处理应用的挂载、卸载等一系列操作
  4. 它没有约定子应用何时被激活

这意味着宿主应用需要自己约定与子应用之间的交互协议并实现相关代码,成本较高,一般适用于需要足够自由度的场景。

为了降低 jmodule 的使用成本,@jmodule/helper 组件提供了一组简单协议的实现,以及不同框架子应用接入代码的实现,通常它足够满足绝大部分场景了。

# 安装

npm i @jmodule/helper

# 目录区分

宿主应用使用:@jmodule/helper/host/xxx

子应用使用:@jmodule/helper/app/xxx

# 扩展应用类型

接口:JModule.defineType

# app类型

TIP

独立子应用:宿主应用/子应用框架无关,子应用通过 mount/unmount 接口挂载/卸载

import { JModule } from '@jmodule/client';
import AppType from '@jmodule/helper/host/type.app';

// 此类型特定: 与宿主应用/子应用框架无关,子应用通过 mount/unmount 接口挂载/卸载
// 第一个参数与 registerModules 参数中的 type 一致
JModule.defineType('app', AppType);

# route类型

TIP

  1. 动态路由子应用,通常也称微模块,一般用于将一个大的应用拆成几个子应用,通过动态路由的方式加载进来,性能较好,表现稳定,但要求子应用与宿主应用采用相同的框架。
  2. 目前仅提供了 vue2 框架的实现,可以类比扩展其它框架。
import { JModule } from '@jmodule/client';
import RoutesVue2Type from '@jmodule/helper/host/type.routes.vue2';

// 此类型特定: 与宿主应用/子应用框架无关,子应用通过 mount/unmount 接口挂载/卸载
// 第一个参数与 registerModules 参数中的 type 一致
JModule.defineType('routes', RoutesVue2Type);

# 纯插件类型

不需要特殊的类型声明,可以直接使用。与其它扩展类型兼容,即子应用为其它扩展类型时,可以同时输出插件组件。

// 子应用
JModuleManager.define('child', {
  exports: { somePlugin },
})

# 扩展资源类型

用于扩展入口资源类型

接口:Resource.defineType

默认内置了 json/js/auto 两种入口资源类型。helper 额外提供了 html 类型

# 增加对html资源的支持

@jmdouel/client@v4.7.0以上版本默认支持, 不需要引入这部分代码

在宿主应用中:

import { Resource } from '@jmodule/client';
import ResourceHtml from '@jmodule/helper/host/resource.html';

// 此类型特定: 与宿主应用/子应用框架无关,子应用通过 mount/unmount 接口挂载/卸载
// 第一个参数与 registerModules 参数中的 type 一致
Resource.defineType('html', ResourceHtml);

JModule 实例初始化:

// 注册子应用时指定 resourceType: html
new JModule({ key: ..., url: ..., resourceType: 'html' });

# 子应用接入

建议作为实现参考即可, 没有必要再增加对 @jmodule/helper 的依赖

# vue2

import { JModule } from '@jmodule/client';
import Vue2AppDefine from '@jmodule/helper/app/app.vue2';

// 与上述 type: app 类型约定的协议一致,内部封装了 mount/unmount 接口
Vue2AppDefine(
  'childAppVue2',
  router => new Vue({ router, render: h => h(App) }),
  base => initRouter(base, true),
);

# vue3

Vue3 类似。

helper 的引用包改为:

import Vue3AppDefine from '@jmodule/helper/app/app.vue3';

接口与 app.vue2 一致,具体使用方式同 vue2。