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
相关产品推荐
相关产品推荐

