You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Single-SPA+Vite+React微前端子应用无法通过根应用加载求助

问题:Single-SPA + Vite + React微前端无法加载子应用

搭建了一个Single-SPA微前端项目,根应用运行在9000端口,Vite-React子应用运行在9002端口,但无法通过根应用(localhost:9000)获取子应用。已移除.eslintrc.cjs中的react-refresh,问题仍未解决。

根应用配置

index.ejs

<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://unpkg.com/react@18/umd/react.production.min.js",
        "react-dom": "https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"
      }
    }
  </script>
  <link rel="preload" href="https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js" as="script">


  <% if (isLocal) { %>
  <script type="systemjs-importmap">
    {
      "imports": {
        "@org/root-config": "//localhost:9000/pi-root-config.js"

      }
    }
  </script>
  <% } %>

root-config.js

import { registerApplication, start } from "single-spa";

registerApplication({
  name: "@org/react-test",
  app: () => 
    import(
      /* webpackIgnore: true */
      "http://localhost:9002/src/main.jsx"
    ),
  activeWhen: ["/"]
});

start({
  urlRerouteOnly: true,
});

webpack.config.js

const { merge } = require("webpack-merge");
const singleSpaDefaults = require("webpack-config-single-spa");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = (webpackConfigEnv, argv) => {
  const orgName = "org";
  const defaultConfig = singleSpaDefaults({
    orgName,
    projectName: "root-config",
    webpackConfigEnv,
    argv,
    disableHtmlGeneration: true,
  });

  return merge(defaultConfig, {
    plugins: [
      new HtmlWebpackPlugin({
        inject: false,
        template: "src/index.ejs",
        templateParameters: {
          isLocal: webpackConfigEnv && webpackConfigEnv.isLocal,
          orgName,
        },
      }),
    ],
    output: {
      publicPath: 'http://localhost:9000/'
    },
    resolve: {
      extensions: ['.jsx', '.js', '.json', '.png', '.svg']
    },
    module: {
      rules: [
        {
          test: /\.css$/i,
          use: ["style-loader", "css-loader"],
        },
      ],
    },
  });
};

Vite-React子应用配置

main.jsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import singleSpaReact from "single-spa-react";
import App from './App.jsx'
import './index.css'

const lifecycles = singleSpaReact({
  React,
  ReactDOM,
  rootComponent: App,
  errorBoundary(err, info, props) {
    return <div>This renders when a error occurs</div>;
  },
});

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

vite.config.js

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  rollupOptions: {
    input: 'src/main.jsx',
    format: 'system',
    preserveEntrySignatures: true,
  },
  base: "http://localhost:9002",
  plugins: [react()],
  server: {
    origin: "http://localhost:9002",
  },
})

解决方案

1. 补充根应用的SystemJS核心依赖

Single-SPA的SystemJS版本依赖SystemJS核心库加载模块,根应用index.ejs中需先引入SystemJS:

<!-- 添加SystemJS核心库 -->
<script src="https://cdn.jsdelivr.net/npm/systemjs@6.14.0/dist/system.js"></script>
<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://unpkg.com/react@18/umd/react.production.min.js",
        "react-dom": "https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"
      }
    }
</script>
<link rel="preload" href="https://cdn.jsdelivr.net/npm/single-spa@5.9.0/lib/system/single-spa.min.js" as="script">

2. 使用vite-plugin-single-spa简化子应用配置

安装适配插件:

npm install vite-plugin-single-spa --save-dev

修改vite.config.js,确保输出SystemJS兼容模块并开启跨域:

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import singleSpa from 'vite-plugin-single-spa'

export default defineConfig({
  plugins: [
    react(),
    singleSpa({
      type: 'react',
      rootComponent: 'src/main.jsx'
    })
  ],
  server: {
    port: 9002,
    cors: true, // 允许根应用跨域请求
    origin: "http://localhost:9002"
  },
  build: {
    rollupOptions: {
      output: {
        format: 'system',
        preserveEntrySignatures: 'strict'
      }
    }
  }
})

3. 适配React 18的渲染方式

修改子应用main.jsx,指定使用React 18的createRoot:

import React from 'react'
import ReactDOM from 'react-dom/client'
import singleSpaReact from "single-spa-react";
import App from './App.jsx'
import './index.css'

const lifecycles = singleSpaReact({
  React,
  ReactDOM,
  rootComponent: App,
  errorBoundary(err, info, props) {
    return <div>This renders when a error occurs</div>;
  },
  renderType: 'createRoot' // 适配React 18
});

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

4. 修正根应用的子应用加载逻辑

使用System.import替代原生import,确保兼容SystemJS模块加载:

import { registerApplication, start } from "single-spa";

registerApplication({
  name: "@org/react-test",
  app: () => 
    System.import(
      /* webpackIgnore: true */
      "http://localhost:9002/src/main.jsx"
    ),
  activeWhen: ["/"]
});

start({
  urlRerouteOnly: true,
});

5. 验证跨域与资源路径

  • 子应用已开启cors: true,解决跨域限制
  • 根应用webpack.config.js中的publicPath设置正确,确保资源加载路径无误

内容的提问来源于stack exchange,提问作者inesvbm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 02:53:10