javascript - React hittades inte från Webpack-genererat micro-frontend
Inuti en befintlig, Angular-baserad, containerapp med flera Angular-mikrofrontendar vill jag ladda en annan baserad på React och Atlasmap. Jag får dock hela tiden följande undantag:
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)
Vilket indikerar att React på något sätt inte är laddat. Vad jag har försökt hittills:
- Lägga till React i importkartan
- Åsidosätta modulimporten med importkarta dev-verktyget
- Försöker inkludera React inuti den webpack-genererade buntningen
- Yarn istället för npm
- Att lägga till React direkt i
<head>i containerappen - Samma med Pikas "ESM"-version av React
Alla verkar inte fungera, så det beror förmodligen på en felaktig Webpack-konfiguration. Konfigurationen börjar bli ganska stor, så jag postar den nedan, den är baserad på flera blogginlägg och patternfly/react:s Webpack-konfigurationsrekommendation.
Versioner som används: "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,
},
});
};
Det är ett komplext problem med många rörliga delar, men om det inte finns några lösningar skulle jag redan vara tacksam för tips att prova.
Vänligen låt mig veta om du behöver mer information.
/REDIGERA mer info
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 (livscykel skapas för single spa)
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 (kopierad och anpassad från https://github.com/atlasmap/atlasmap/blob/master/ui/packages/atlasmap-standalone/src/App.tsx och 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;