Hi PatternFly community, this is a cross-post from SO. Hope that’s ok:
Inside an existing, Angular based, container app, with multiple Angular micro-frontends, I want to load another one based on React and Atlasmap. However, I keep getting the following exception:
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)
Which indicates that somehow React is not loaded. What I’ve tried so far:
- Adding React to the import map
- Overriding the module import with the import map dev tool
- Trying to include React inside the webpack generated bundle
- Yarn instead of npm
- Adding React directly to the
<head>
of the container app - The same with Pika’s “ESM” React build
All don’t seem to work, so it probably boils down to an incorrect Webpack configuration. The config is getting pretty big, so I’ll post it below, it’s based on several blogposts and the patternfly/react Webpack config recommendation
Versions in use:
“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,
},
});
};
It’s a complex problem with lots of moving parts, but if not for any solutions, I would already be grateful for pointers to try.
Please let me know if you need more info.