2022-06-23 create-react-app 项目 micro-frontends 对应


如何将 create-react-app 项目迁移成 micro-frontends(微前端) 项目?

前提:我的微前端项目主要使用 single-spa

Demo 演示

How-to

我主要参考的是 https://single-spa.js.org/docs/faq/#create-react-app 的 option 1 和 option 3。

为什么?

  1. option 1 足够简单,便于解释原理。
  2. option 3 和公司的核心项目使用的技术相同。

option 1: Remove react-scripts and then run create-single-spa on your project

1. 直接在项目路径下执行 create-single-spa

npx create-single-spa

// orgName: "thaddeusjiang"
// projectName: "legacy"

2. App.js 重命名成 root.component.js

3. 在 spa-root-config 中使用 @thaddeusjiang/legacy

启动你的 spa-root-config 项目,效果如下:

option 2: Use react-app-rewired to modify the webpack config.

1. 安装 react-app-rewired-single-spa

npm install react-app-rewired-single-spa

2. 修改 config-overrides.js

// config-overrides.js
const {
  rewiredSingleSpa,
  rewiredSingleSpaDevServer,
} = require("react-app-rewired-single-spa");

// use `customize-cra`
const { override, overrideDevServer } = require("customize-cra");

module.exports = {
  webpack: override(
    rewiredSingleSpa({
      orgName: "thaddeusjiang",
      projectName: "legacy",
      entry: "./src/thaddeus-legacy.js",
      reactPackagesAsExternal: true,
      peerDepsAsExternal: true,
      orgPackagesAsExternal: true,
    })
  ),
  devServer: overrideDevServer(rewiredSingleSpaDevServer()),
};

3. 创建 thaddeusjiang-legacy.js

import React from "react";
import ReactDOM from "react-dom";
import singleSpaReact from "single-spa-react";
import Root from "./App";

const lifecycles = singleSpaReact({
  React,
  ReactDOM,
  rootComponent: Root,
  errorBoundary(err, info, props) {
    // Customize the root error boundary for your microfrontend here.
    return null;
  },
});

export const { bootstrap, mount, unmount } = lifecycles;

4. 在 spa-root-config 项目中使用 @thaddeusjiang/legacy

启动你的 spa-root-config 项目,效果如下:

总结

两种方法其实是殊途同归,主要做了下面 3 件事。

  1. single-spa application 需要提供 lifecycles 才能在 single-spa root-config 中使用。
  2. import-maps 需要 JavaScript module,所以需要通过 webpack 打包。
  3. single-spa-layout 控制 single-spa 的 route、application 以及 DOM 。

ref: