React远程组件

什么是远程组件?

远程组件指的是从远程服务器动态加载的组件,这些组件可以是React、Vue等框架的组件。

为什么需要远程组件

本质上就是为了解决复用问题,那引出新的问题有几种公共项目代码复用方式?

Git仓库

将公共代码单独抽到一个仓库去维护
优点如下

版本控制: 可以精确控制每个子模块的版本,避免不同项目使用不同版本的共同代码。

独立性: 子模块可以独立于主项目进行开发和发布。

清晰结构: 项目结构清晰,易于管理和理解。
缺点如下

管理复杂: 每次都需要手动更新。

npm包

发布到仓库中,需要的项目npm install

缺点:每次更新版本都需要重新publish

Monorepo

优点

统一管理: 所有相关项目都在同一个仓库中,便于统一管理和版本控制。

原子提交: 可以进行跨项目的原子提交,确保所有相关更改都是一致的。

代码共享: 共享代码可以直接引用,无需额外的包管理或子模块配置。
缺点

仓库大小: 单个仓库可能会变得非常大,影响克隆和拉取的速度。

复杂性: 需要更复杂的工具和流程来管理大型仓库,如 Lerna、Nx 等。

权限管理: 需要更细致的权限管理,确保不同团队成员只能访问他们需要的部分。

使用场景

有些公共组件会频繁的根据需求变更,对于多个项目共用的组件库来说,修改组件其影响范围是不可控的。此外,每次修改公共代码后需要更新版本,有时候可能只是个很小的更新没必要更新整个代码库版本。

因此对于某个经常需要迭代的公共代码/组件可以单独打包放到CDN上动态加载。

优点

1、方便的版本控制 。多个项目依赖不同版本,可以打包多分放到CDN上,对应项目加载即可;

2、高效率 。通过动态加载,可以在不重新构建和部署整个应用的情况下,更新和扩展前端功能 ,用户体验也好,可保证用户体验到最新的代码;

3、代码复用,多个项目使用可以有加载;

缺点

1、需要请求对应文件,如果组件太大,加载速度就会慢;

2、如果组件服务崩溃,可能导致组件加载错误,从而使整个业务不可用;

简陋版代码展示

要远程加载的组件源码,写完后建议打包成umd格式。

typescript 复制代码
import { Button, Form } from 'antd/es';
import React from 'react';

const YuButton = (props:{
  p_click?:()=>void
  m_click?:()=>void
})=>{
  const style = { marginRight: 5 };
  return (
    <>
      <Button type="primary" onClick={props.p_click} style={style}>
        主要按钮
      </Button>
      <Button type="primary" onClick={props.m_click} style={style} loading>
        主要按钮
      </Button>
      <Button type="primary" style={style} disabled>
        禁用
      </Button>
    </>
  );
}
const YuText = (props:{
  Items:{label: string, content:string}[]
})=>{
return props?.Items?.length > 0 ? (
  <Form
  name="basic"
  labelCol={{ span: 8 }}
  wrapperCol={{ span: 16 }}

  autoComplete="off"
  >
    {props.Items.map((item)=>{
      return <Form.Item  label={item.label}>
        {item.content}
      </Form.Item>
    })}
  </Form>
) : <div>暂无数据</div>
}



export default {
  YuButton,
  YuText
}
typescript 复制代码
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <RemoteComponent  name='YuButton'>Click Me</RemoteComponent>
        <RemoteComponent  name='YuText' Items={[{label:'label', content:"12312"}]}>Click Me</RemoteComponent>
        <RemoteComponent  name='YuText1' Items={[{label:'label', content:"12312"}]}>Click Me</RemoteComponent>
      </header>
    </div>
  );
}
typescript 复制代码
const RemoteComponent = ({name, children, ...props}) => {
  const Component = useMemo(() => {
    return React.lazy(() => fetchComponent(name))
  }, [name])

  return (
    <Suspense
      fallback={
        <div style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>
          <span style={{fontSize: 50}}>Loading...</span>
        </div>
      }>
      <Component {...props}>{children}</Component>
    </Suspense>
  )
}

const fetchComponent = async (name) => {
  const text = await fetch(
    `/index.umd.js?ts=${Date.now()}` // 将打包的放到CDN上,这里填写CDN的地址加载这个打包后的js文件
  ).then((res) => {
    if (!res.ok) {
      throw new Error('Network response was not ok')
    }
    return res.text()
  })
  const module = getParsedModule(text, name)
  if(Object.keys(module.exports).includes(name)){
    return {default: module.exports[name]} // 这里我们可以得到打包后的组件
  }
  return {default: ()=> <div style={{color:'red'}}>加载失败</div>}
}

const packages = { // 需要什么包传什么包(为了减小打包体积),或者在打包的时候将这些需要的包一起打包进去
  react: React,
  'antd/es': {Button, Form}
}
const getParsedModule = (code) => {
  let module = {
    exports: {},
  }
  const require = (name) => {
    return packages[name]
  }
  Function('require, exports, module', code)(require, {}, module)// 打包UMD格式的话把这些传进去
  return module
}

效果展示

相关推荐
朝新_2 分钟前
【SpringMVC】详解用户登录前后端交互流程:AJAX 异步通信与 Session 机制实战
前端·笔记·spring·ajax·交互·javaee
裴嘉靖4 分钟前
Vue 生成 PDF 完整教程
前端·vue.js·pdf
毕设小屋vx ylw2824266 分钟前
Java开发、Java Web应用、前端技术及Vue项目
java·前端·vue.js
冴羽1 小时前
今日苹果 App Store 前端源码泄露,赶紧 fork 一份看看
前端·javascript·typescript
蒜香拿铁1 小时前
Angular【router路由】
前端·javascript·angular.js
brzhang1 小时前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构
西洼工作室2 小时前
高效管理搜索历史:Vue持久化实践
前端·javascript·vue.js
广州华水科技2 小时前
北斗形变监测传感器在水库安全中的应用及技术优势分析
前端
开发者如是说2 小时前
Compose 开发桌面程序的一些问题
前端·架构
旺代2 小时前
Token 存储与安全防护
前端