微前端: single-spa + react

基于react的 single-spa 微应用搭建
更新于: 2023-03-24 10:47:54

创建 react 应用

基于 spa 创建 react 应用

修改端口

"start": "webpack serve --port 9002",

在 container 应用中注册

registerApplication({
  name: "@jswork/todos",
  app: () => System.import("@jswork/todos"),
  activeWhen: ["/todos"],
});

在 importmap 中添加

<% if (isLocal) { %>
<script type="systemjs-importmap">
  {
    "imports": {
      "@jswork/root-config": "//localhost:9000/jswork-root-config.js",
      "@jswork/lagou":"http://localhost:9001/jswork-lagou.js",
      "@jswork/todos":"http://localhost:9002/jswork-todos.js"
    }
  }
</script>
<% } %>

在公用包中添加 react/react-dom

<script type="systemjs-importmap">
  {
    "imports": {
      "single-spa": "https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js",
      "react": "https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js",
      "react-dom": "https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"
    }
  }
</script>

添加 prefetch/preload

公用模块,最大限度的利用浏览器缓存。

  • 更准确地确定资源加载的优先级。
  • 存储在缓存中以供将来请求使用,如果合适则重用该资源。
  • 对资源应用正确的内容安全策略。
  • Accept为其设置正确的请求标头。

我能想到的问题:

  1. 图片闪现
  2. 字体图标闪现问题
<link rel="preload" href="https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js" as="script">

可以预加载哪些类型的内容?

可以预加载许多内容类型。可能的as属性值是:

  • audio: 音频文件,通常用于<audio>.
  • document: 一个 HTML 文档,旨在由<frame>或嵌入<iframe>
  • embed:要嵌入到元素中的资源<embed>
  • fetch:要通过获取或 XHR 请求访问的资源,例如 ArrayBuffer、WebAssembly/WASM 二进制文件或 JSON 文件。
  • font: 字体文件。
  • image: 图像文件。
  • object:要嵌入到元素中的资源<object>
  • script: JavaScript 文件。
  • style: CSS 样式表。
  • track: WebVTT 文件。
  • worker:JavaScript 网络工作者或共享工作者。
  • video: 视频文件,通常用于<video>.

react 路由处理

  • 注意这里的处理:<BrowserRouter basename="/todos">
  • 打包的时候,可以将 react-router-dom 作为 externals 依赖(在子应用中设置,主应用加添加importmap)
import React from "react";
// react router v6
import { BrowserRouter, Routes, Route, NavLink } from "react-router-dom";
import Home from "./home";
import About from "./about";

export default function Root(props) {
  return (
    <section>
      <BrowserRouter basename="/todos">
        <nav>
          <NavLink to="/" end>
            Home
          </NavLink>
          <NavLink to="/about">About</NavLink>
        </nav>
        <Routes>
          <Route index path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </BrowserRouter>
    </section>
  );
}

参考