@aligov/remote-component

加载开放平台的模块应用并渲染成组件

Usage no npm install needed!

<script type="module">
  import aligovRemoteComponent from 'https://cdn.skypack.dev/@aligov/remote-component';
</script>

README

@aligov/remote-component

加载React组件并渲染

安装

tnpm install @aligov/remote-component -S

使用场景

在应用中加载远程React组件。这个组件可以是umd格式、common.js格式,推荐使用umd格式

核心能力

  1. 支持js、css同时加载, 比如: ['a.js', 'a.css']
  2. 相比如Load.js会在页面的header中插入一段script(link)来加载js(css)资源,remoteComponent会通过fetch来加载js(css)资源,避免了因为插入script而引起的安全问题
  3. 提供资源缓存优化。当a.js加载完后,会缓存在内存中,下次无须重复加载
  4. 支持Hooks调用
  5. 依赖处理。目前remote component支持externals掉react、react-dom、biz-charts,后续会使用runtime来支持运行时声明组件

入参

interface IModule {
   url?: string; // 组件的url
   appId?: string | number; // 组件id
   name: string;   // 组件名
   // 其它属性(扩展使用)
   props?: {
     // 可指定预发或者线上请求url。预发:https://pre-mapi.zjzwfw.gov.cn;线上:https://mapi.zjzwfw.gov.cn
     host?: string; 
     appTypeCode?: string;  // 组件类型code
   }; 
}

入参中url和appId必传一个,若两者都传则只使用appId

基本用法

  1. 项目根目录下新建remote-component.config.js,用来声明远程组件所需要的依赖
/**
 * 声明远程组件所需要的依赖
 */
module.exports = {
  resolve: {
    React: window.React,
    ReactDOM: window.ReactDOM,
    BizCharts: window.BizCharts,
    Next: window.Next,
  },
};
  1. 新建src/RemoteComponent.js,用来生成具体的RemoteComponent组件
// src/RemoteComponent.js
import React from 'react';
import {
  createRemoteComponent,
  createRequires,
} from '@aligov/remote-component';
// 依赖remote-component.config.js
import { resolve } from '../../../remote-component.config.js';  

const requires = createRequires(resolve);

export const RemoteComponent = createRemoteComponent({ requires });

说明: 这块本应该是组件提供者应提供的功能,但应实现中遇到问题,理想用法先不提供,附上理想用法:

import React from 'react';
import { RemoteComponent } from '@aligov/remote-component';
// 使用RemoteComponent加载
const HelloWorld = ({ name }) => <RemoteComponent url={url} name={name} />;
  1. 接下来使用RemoteComponent来加载远程组件
import React from 'react';
import ReactDOM from 'react-dom';

import { RemoteComponent } from '@/RemoteComponent' // 这是前面定义的RemoteComponent

const appId = 'recept_component_2';
const componentName = 'custom_notice';

const HelloWorld = ({ name }) => <RemoteComponent appId={appId} name={name} />;

ReactDOM.render(<HelloWorld name={componentName} />, documnet.getElementById('root'));

注意事项

  1. 依赖会被external两次,一次是远程组件,另一次是加载组件的APP.这可能会有些未知问题
  2. external掉的依赖版本需一致,比如组件A排除了react 16但是应用中引入的cdn是react 15,这就会有问题