在现有的基于 Angular 的容器应用程序中,具有多个 Angular 微前端,我想加载另一个基于 React 和Atlasmap的应用程序。但是,我不断收到以下异常:
zone.js:209 Uncaught TypeError: Class extends value undefined is not a constructor or null
at Module../node_modules/@patternfly/react-core/dist/esm/components/FormSelect/FormSelect.js (FormSelect.js:15)
at __webpack_require__ (bootstrap:24)
at fn (hot module replacement:61)
at Module../node_modules/@patternfly/react-core/dist/esm/components/InputGroup/InputGroup.js (main.bundle.js:25253)
at __webpack_require__ (bootstrap:24)
at fn (hot module replacement:61)
at Module../node_modules/@atlasmap/atlasmap/dist/atlasmap.esm.js (main.bundle.js:245)
at __webpack_require__ (bootstrap:24)
at fn (hot module replacement:61)
at Module../src/App.tsx (index.js:176)
这表明未加载 React。到目前为止我已经尝试过:
- 将 React 添加到导入映射
- 使用导入映射开发工具覆盖模块导入
- 尝试在 webpack 生成的包中包含 React
- 纱线代替 npm
- 将 React 直接添加到
<head>
容器应用程序的 - 与 Pika 的“ESM”构建的 React相同
一切似乎都不起作用,所以它可能归结为不正确的 Webpack 配置。配置变得相当大,所以我会在下面发布它,它基于几篇博文和 patternfly/react Webpack 配置推荐
正在使用的版本:“single-spa-react”:“^4.0.0”、“ts-config-single-spa”:“^2.0.0”、“typescript”:“^4.1.2”、“webpack” :“^5.8.0”、“webpack-cli”:“^4.2.0”、“webpack-config-single-spa-react”:“^2.0.0”、“webpack-config-single-spa-react” -ts”:“^2.0.0”、“webpack-config-single-spa-ts”:“^2.0.0”、“react”:“^16.13.1”、“react-dom”:“^16.13. 1" "@atlasmap/atlasmap": "^2.2.2",
const { merge } = require("webpack-merge");
const singleSpaDefaults = require("webpack-config-single-spa-react-ts");
const path = require("path");
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
const BG_IMAGES_DIRNAME = "bgimages";
const ASSET_PATH = process.env.ASSET_PATH || "/";
module.exports = (webpackConfigEnv, argv) => {
const defaultConfig = singleSpaDefaults({
orgName: "",
projectName: "data-mapping-mf",
webpackConfigEnv,
argv,
});
delete defaultConfig.devServer.disableHostCheck;
// for debugging uncomment the line below
// console.log(JSON.stringify(defaultConfig));
return merge(defaultConfig, {
module: {
rules: [
{
test: /\.(tsx|ts|jsx)?$/,
use: [
{
loader: "ts-loader",
options: {
transpileOnly: true,
experimentalWatchApi: true,
},
},
],
},
{
test: /\.(svg|ttf|eot|woff|woff2)$/,
// only process modules with this loader
// if they live under a 'fonts' or 'pficon' directory
include: [
path.resolve(__dirname, "node_modules/patternfly/dist/fonts"),
path.resolve(
__dirname,
"node_modules/@patternfly/react-core/dist/styles/assets/fonts"
),
path.resolve(
__dirname,
"node_modules/@patternfly/react-core/dist/styles/assets/pficon"
),
path.resolve(
__dirname,
"node_modules/@patternfly/patternfly/assets/fonts"
),
path.resolve(
__dirname,
"node_modules/@patternfly/patternfly/assets/pficon"
),
],
use: {
loader: "file-loader",
options: {
// Limit at 50k. larger files emited into separate files
limit: 5000,
outputPath: "fonts",
name: "[name].[ext]",
},
},
},
{
test: /\.svg$/,
include: (input) => input.indexOf("background-filter.svg") > 1,
use: [
{
loader: "url-loader",
options: {
limit: 5000,
outputPath: "svgs",
name: "[name].[ext]",
},
},
],
},
{
test: /\.svg$/,
// only process SVG modules with this loader if they live under a 'bgimages' directory
// this is primarily useful when applying a CSS background using an SVG
include: (input) => input.indexOf(BG_IMAGES_DIRNAME) > -1,
use: {
loader: "svg-url-loader",
options: {},
},
},
{
test: /\.svg$/,
// only process SVG modules with this loader when they don't live under a 'bgimages',
// 'fonts', or 'pficon' directory, those are handled with other loaders
include: (input) =>
input.indexOf(BG_IMAGES_DIRNAME) === -1 &&
input.indexOf("fonts") === -1 &&
input.indexOf("background-filter") === -1 &&
input.indexOf("pficon") === -1,
use: {
loader: "raw-loader",
options: {},
},
},
{
test: /\.(jpg|jpeg|png|gif)$/i,
include: [
path.resolve(__dirname, "src"),
path.resolve(__dirname, "node_modules/patternfly"),
path.resolve(
__dirname,
"node_modules/@patternfly/patternfly/assets/images"
),
path.resolve(
__dirname,
"node_modules/@patternfly/react-styles/css/assets/images"
),
path.resolve(
__dirname,
"node_modules/@patternfly/react-core/dist/styles/assets/images"
),
path.resolve(
__dirname,
"node_modules/@patternfly/react-core/node_modules/@patternfly/react-styles/css/assets/images"
),
path.resolve(
__dirname,
"node_modules/@patternfly/react-table/node_modules/@patternfly/react-styles/css/assets/images"
),
path.resolve(
__dirname,
"node_modules/@patternfly/react-inline-edit-extension/node_modules/@patternfly/react-styles/css/assets/images"
),
],
use: [
{
loader: "url-loader",
options: {
limit: 5000,
outputPath: "images",
name: "[name].[ext]",
},
},
],
},
],
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
publicPath: ASSET_PATH,
},
resolve: {
extensions: [".js", ".ts", ".tsx", ".jsx"],
plugins: [
new TsconfigPathsPlugin({
configFile: path.resolve(__dirname, "./tsconfig.json"),
}),
],
symlinks: false,
cacheWithContext: false,
},
});
};
这是一个复杂的问题,有很多活动部件,但如果没有任何解决方案,我已经很感激可以尝试的指针。
如果您需要更多信息,请告诉我。
/编辑更多信息
tsconfig.json:
{
"extends": "ts-config-single-spa",
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "."
},
"include": ["src/**/*", "node_modules/@types"],
"exclude": ["src/**/*.test*"]
}
SphereMall-data-mapping-mf.tsx(为单个水疗中心创建生命周期)
import React from "react";
import ReactDOM from "react-dom";
import singleSpaReact from "single-spa-react";
import App from "./App";
const lifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: App,
errorBoundary(err, info, props) {
return (
<ul>
<li>Error: ${err}</li>
<li>Info: ${info}</li>
<li>Props: ${props}</li>
</ul>
);
},
});
export const { bootstrap, mount, unmount } = lifecycles;
App.tsx(复制并改编自https://github.com/atlasmap/atlasmap/blob/master/ui/packages/atlasmap-standalone/src/App.tsx和https://github.com/atlasmap/atlasmap/ blob/master/ui/packages/atlasmap-standalone/src/index.tsx)
import { Atlasmap, AtlasmapProvider } from "@atlasmap/atlasmap";
import React from "react";
const App: React.FC = () => {
return (
<AtlasmapProvider
baseJavaInspectionServiceUrl={"/v2/atlas/java/"}
baseXMLInspectionServiceUrl={"/v2/atlas/xml/"}
baseJSONInspectionServiceUrl={"/v2/atlas/json/"}
baseCSVInspectionServiceUrl={"/v2/atlas/csv/"}
baseMappingServiceUrl={"/v2/atlas/"}
>
<Atlasmap />
</AtlasmapProvider>
);
};
export default App;