React 17 and webpack 5 not working in IE11 - reactjs

I have looked into everything I could about the migration to react 17 and webpack 5. This for an application that is also running on IE11. And after all the changes (as you will see in the code) , according to evrything I read, it still doesnt work. I get the same error . When I look at the bundle and open it, there is a const there, which belongs to es6. It means that there was not translation, despite all the babel change I made.
If someone has an idea what could be done it would great!
Here is my webpack fike:
const webpack = require('webpack');
const path = require("path");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const autoprefixer = require('autoprefixer');
const Dotenv = require('dotenv-webpack')
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const nodeEnv = process.env.NODE_ENV || "development"
const simulateProd = process.env.SIMULATE_PROD
const isProdEnv = nodeEnv === 'production'
const isNotDevEnv = nodeEnv !== "development"
const buildPath =
const sourcePath =
const imagesPath =
const iconsPath =
const soundsPath = ;
// Common plugins
const plugins = [
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser',
}),
new MiniCssExtractPlugin(),
new webpack.LoaderOptionsPlugin({
options: {
postcss: [
autoprefixer(),
],
context: sourcePath,
},
}),
new CopyWebpackPlugin(
{
patterns: [
{from: iconsPath, to: 'icons'},
{from: imagesPath, to: 'images'}
]
}
),
new Dotenv({
systemvars: true
}),
new HtmlWebpackPlugin({
template: path.join(sourcePath, 'index.html'),
path: buildPath,
filename: 'index.html',
}),
]
// Common rules
const rules = [
{
test: /\.(js|jsx)$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
plugins: ['react-hot-loader/babel'],
presets: ["#babel/preset-env"] //Preset used for env setup
}
// use: [
// 'babel-loader',
// ],
},
{
test: /\.s[ac]ss$/i,
exclude: /node_modules/,
use: [
{
// creates style nodes from JS strings
loader: "style-loader",
// options: {sourceMap: true}
},
// Translates CSS into CommonJS
{
loader: 'css-loader',
options: {
importLoaders: 1,
url: false,
modules: {localIdentName: "[path]___[name]__[local]___[hash:base64:5]"}
}
},
{
loader:"resolve-url-loader"
},
{
// compiles Sass to CSS
loader: "sass-loader",
options: {
sourceMap: true
}
},
],
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "style-loader", 'css-loader'],
},
{
test: /\.(ico|jpe?g|png|gif|svg|mp3|html)$/,
include: [imagesPath, soundsPath],
type: 'asset/resource',
// use: 'file-loader',
// generator: {
// filename: '[path][name].[ext]'
// },
},
{
test: /\.md$/,
use: 'raw-loader'
}
]
if (isProdEnv) {
// Production plugins
plugins.push(
new TerserPlugin({
// cache: true,
parallel: true,
// sourceMap: true
})
)
}
else {
// Development plugins
}
module.exports = smp.wrap({
mode : isNotDevEnv ? 'production' : 'development',
target: ['web', 'es5'],
experiments: {
asset: true
},
devtool: isNotDevEnv ? false : 'source-map',
context: sourcePath,
entry: {
js: ['react-hot-loader/patch','./index.js'],
},
output: {
path: buildPath,
publicPath: '/',
filename: "bundle.js",
assetModuleFilename: '[path][name].[ext]'
},
module: {
rules,
},
resolve: {
extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx', '.md', '.scss', '.css'],
modules: [
path.resolve(__dirname, 'node_modules'),
sourcePath,
],
fallback: {
"buffer": require.resolve('buffers'),
"assert": require.resolve('assert/'),
"fs": false,
"os": false,
"path": false,
"zlib": require.resolve('browserify-zlib'),
"stream": require.resolve('stream-browserify'),
"crypto": false,
} ,
},
plugins,
optimization : {
moduleIds: 'named',
sideEffects: isProdEnv,
},
devServer: {
contentBase: isNotDevEnv ? buildPath : sourcePath,
historyApiFallback: true,
port: 8080,
compress: isNotDevEnv,
inline: !isNotDevEnv,
hot: !isNotDevEnv,
host: "localhost",
disableHostCheck: true,
stats: {
assets: true,
children: false,
chunks: false,
hash: false,
modules: false,
publicPath: false,
timings: true,
version: false,
warnings: true,
colors: {
green: '\u001b[32m',
},
},
},
});
Here is my babel.config.json file:
{
"presets": [
[
"#babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": "3",
"targets": {
"browsers": ["last 5 versions", "ie >= 9"]
}
}
],
"#babel/preset-typescript",
"#babel/preset-react"
],
"plugins": [
"#babel/plugin-proposal-object-rest-spread",
["#babel/plugin-proposal-decorators", { "legacy": true }],
"react-hot-loader/babel",
"#babel/plugin-transform-arrow-functions",
"#babel/plugin-proposal-optional-chaining",
"#babel/plugin-proposal-nullish-coalescing-operator",
"#babel/plugin-proposal-class-properties",
[
"#babel/plugin-transform-modules-commonjs",
{
"allowTopLevelThis": true
}
]
]
}
at the start of my src/index.js
there is that :
require('es6-promise/auto')
require('string.prototype.startswith')
require('string.prototype.endswith')
import 'react-app-polyfill/ie11';
import "react-app-polyfill/stable";
import "core-js/stable";
import "regenerator-runtime/runtime";
in my package.json I added that:
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all",
"IE 11"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version",
"IE 11"
]
},
Thank you !

Related

How to configure webpack for react-easy-crop package while it shows cropper is not defined?

I am trying to configure webpack for my react project. But while it is working fine for other packages like sweetalert2 and all; it shows error for react-easy-crop package.
Here is my .babelrc
{
"presets": [
[
"#babel/preset-env",
{
"modules": false,
"targets": {
"browsers": [
"last 2 Chrome versions",
"last 2 Firefox versions",
"last 2 Safari versions",
"last 2 iOS versions",
"last 1 Android versions",
"last 1 ChromeAndroid versions",
"ie 11"
]
}
}
],
"#babel/preset-react"
],
"plugins": [
["#babel/plugin-proposal-class-properties"],
["#babel/plugin-transform-runtime"],
[
"babel-plugin-import",
{
"libraryName": "#mui/material",
"libraryDirectory": "",
"camel2DashComponentName": false
},
"core"
],
[
"babel-plugin-import",
{
"libraryName": "#mui/icons-material",
"libraryDirectory": "",
"camel2DashComponentName": false
},
"icons"
],
[
"babel-plugin-import",
{
"libraryName": "react-easy-crop",
"libraryDirectory": "",
"camel2DashComponentName": false
},
"Cropper"
]
]
}
And below is my webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
const Dotenv = require('dotenv-webpack');
module.exports = {
context: __dirname,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js',
publicPath: '/',
},
devServer: {
historyApiFallback: true,
port: 3000,
},
resolve: {
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
fallback: {
process: require.resolve('process/browser'),
buffer: require.resolve('buffer'),
http: require.resolve('stream-http'),
https: require.resolve('https-browserify'),
url: require.resolve('url/'),
crypto: require.resolve('crypto-browserify'),
stream: require.resolve('stream-browserify'),
},
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|j?g|jpg|jpeg|svg|gif)?$/,
use: 'file-loader?name=./assets/images/[name].[ext]',
},
{
test: /\.(woff|woff2|ttf|eot)$/,
use: 'file-loader',
},
{
test: /#material-ui\/core\/.*/,
type: 'asset/resource',
},
],
},
plugins: [
new Dotenv({
path: './.env',
safe: true,
systemvars: true,
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'public/index.html'),
filename: 'index.html',
}),
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
],
};
Now when I try to import Cropper from react-easy-crop it shows me an error that Uncaught ReferenceError : Cropper is not defined . I have tried uninstalling the package and then install it again with both npm and yarn; but it's of no use!
How do you import the Cropper in your code?
Why are you using "babel-plugin-import" explicitly for react-easy-crop? I don't think this is needed. I guess you used it for #mui in order to avoid loading the whole library when only using a few components. react-easy-crop only exports a single component so you don't need this optimisation.

React app in S3 returns 404 error with document type when refresh page

My React app running inside S3. I have set S3 to host my app and make index document and error document to index.html. The app is running well on the S3 link, however, when I refresh the page, even the app is still running correct, the devtool shows document 404 error.
I use webpack for build the app. With webpack devServer, I don't have this issue. Here is my webpack file:
const { resolve } = require("path")
const webpack = require("webpack")
const HtmlWebPackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const Dotenv = require("dotenv-webpack")
module.exports = {
mode: process.env.NODE_ENV === "development" ? "development" : "production",
devtool: "source-map",
entry: ["react-hot-loader/patch", "./src"],
output: {
path: resolve(__dirname, "dist"),
filename: "[name].[chunkhash:5].js",
chunkFilename: "[name].[chunkhash:5].js",
publicPath: "/",
},
devServer: {
contentBase: resolve(__dirname, "static"),
compress: true,
port: 3000,
open: true,
hot: true,
historyApiFallback: true,
proxy: {
"/api": "http://localhost:5000",
},
},
resolve: {
alias: {
"#": resolve(__dirname, "src"),
},
extensions: [".js", ".jsx"],
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
presets: [
[
"#babel/preset-env",
{
targets: "> 0.25%, not dead",
},
],
["#babel/preset-react"],
],
plugins: [
["react-hot-loader/babel"],
["#babel/plugin-proposal-class-properties", { loose: false }],
[
"#babel/plugin-transform-runtime",
{
corejs: 3,
helpers: true,
regenerator: true,
},
],
],
},
},
],
},
{
test: /\.css$/,
use: [
process.env.NODE_ENV === "development" ? { loader: "style-loader" } : MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
importLoaders: 1,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
browsers: "last 10 version",
},
],
],
},
},
},
],
},
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
[
"postcss-preset-env",
{
browsers: "last 10 version",
},
],
],
},
},
},
"less-loader",
],
},
{
test: /\.(txt|csv|xlsx|mmdb)$/,
use: [
{
loader: "file-loader",
},
],
},
{
test: /\.(jpg|png|gif|bmp)$/,
use: [
{
loader: "url-loader",
options: {
name: "[hash:10].[ext]",
esModule: false,
limit: 10 * 1024,
outputPath: "images",
publicPath: "/images",
},
},
],
},
{
test: /\.html$/i,
loader: "html-loader",
},
],
},
plugins: [
new Dotenv({
path: resolve(__dirname, "./.env"),
systemvars: true,
}),
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html",
}),
new MiniCssExtractPlugin({
filename: "[name].[contenthash:5].css",
}),
new CleanWebpackPlugin(),
new webpack.HotModuleReplacementPlugin(),
],
}
My route file is like
<BrowserRouter>
<Switch>
<Route path="/a" component={A} />
<Route path="/b" component={B} />
<Route path="/c" component={C} />
<Route path="/d" component={D} />
<Route component={Admin} />
</Switch>
</BrowserRouter>
I don't know if S3 or webpack made this issue.

webpack 5 in a lerna monorepo loads files outside of the package

I have a fairly standard lerna monorepo setup, using yarn workspaces and TypeScript.
There are pacakge folders for various services and also the React frontend. I've been migrating the Webpack config to Webpack 5 so that I can take advantage of the module federation. The React app is complex, uses CSS modules with scss, TypeScript, etc so the config is relatively complex, nevertheless I feel as if I am there with compilation. That notwithstanding there are 2 issues that I cannot seem to fathom, the most problematic of them being that webpack seems to be trying to load files from other packages in the monorepo (and these are causing TypeScript/eslint errors).
Webpack.config.js
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
const ESLintPlugin = require("eslint-webpack-plugin");
const isDevelopment = process.env.NODE_ENV === "development";
const imageInlineSizeLimit = 2000;
// Default js and ts rules
const tsRules = {
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: path.resolve(__dirname, "src"),
exclude: [/node_modules/],
loader: "babel-loader",
options: {
customize: require.resolve("babel-preset-react-app/webpack-overrides"),
presets: [
"#babel/preset-env",
"#babel/preset-react",
"#babel/preset-typescript",
],
plugins: [],
},
};
// Process any JS outside of the app with Babel.
// Unlike the application files, we only compile the standard ES features.
const externalJsRules = {
test: /\.(js|mjs)$/,
exclude: [/node_modules/],
loader: "babel-loader",
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve("babel-preset-react-app/dependencies"),
{ helpers: true },
],
],
cacheDirectory: true,
cacheCompression: false,
},
};
let plugins = [
new ForkTsCheckerWebpackPlugin({
async: false,
}),
new ESLintPlugin({
extensions: ["js", "jsx", "ts", "tsx"],
}),
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
chunkFilename: "[id].[contenthash].css",
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "public", "index.html"),
}),
new webpack.IgnorePlugin({
// #todo: this prevents webpack paying attention to all tests and stories, which probably ought only be done on build
resourceRegExp: /(coverage\/|\.spec.tsx?|\.mdx?$)/,
}),
];
if (isDevelopment) {
// For use with dev server
tsRules.options.plugins.push("react-refresh/babel");
externalJsRules.options.sourceMaps = true;
externalJsRules.options.inputSourceMap = true;
plugins = [...plugins, new webpack.HotModuleReplacementPlugin()];
}
module.exports = {
entry: path.resolve(__dirname, "src", "index.tsx"),
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/",
clean: true,
},
module: {
rules: [
externalJsRules,
tsRules,
{
test: [/\.avif$/],
loader: "url-loader",
options: {
limit: imageInlineSizeLimit,
mimetype: "image/avif",
name: "static/media/[name].[hash:8].[ext]",
},
},
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: "url-loader",
options: {
limit: imageInlineSizeLimit,
name: "static/media/[name].[hash:8].[ext]",
},
},
{
test: /\.svg$/,
use: ["#svgr/webpack", "url-loader"],
},
{
test: /\.s?css$/,
oneOf: [
{
test: /\.module\.s?css$/,
use: [
isDevelopment
? // insert css into DOM via js
"style-loader"
: // insert link tags
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: true,
sourceMap: isDevelopment,
importLoaders: 2,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
autoprefixer: {
flexbox: "no-2009",
},
stage: 3,
},
],
"postcss-normalize",
],
},
},
},
{
loader: "sass-loader",
options: {
sourceMap: isDevelopment,
},
},
],
},
{
use: [
isDevelopment
? // insert css into DOM via js
"style-loader"
: // insert link tags
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: isDevelopment,
importLoaders: 2,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
autoprefixer: {
flexbox: "no-2009",
},
stage: 3,
},
],
"postcss-normalize",
],
},
},
},
{
loader: "sass-loader",
options: {
sourceMap: isDevelopment,
},
},
],
},
],
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js", ".scss"],
symlinks: false,
// don't provide polyfills for non UUI-core
fallback: {
// crypto: false,
// fs: false,
// stream: false,
// path: false,
},
},
optimization: {
runtimeChunk: true,
},
plugins: [...plugins],
devtool: "eval-cheap-module-source-map",
devServer: {
static: path.join(__dirname, "build"),
historyApiFallback: true,
port: 3000,
open: true,
hot: true,
},
};
Webpack is run from the frontend package folder. Also I have scanned the code for any refrences to other packages in the React code, but there are none, so I can't understand why this is loading and how to prevent them loading.
Example error:
ERROR in ../../node_modules/#githubpackage/src/aFile.ts:2:25
TS2801: This condition will always return true since this 'Promise<boolean>' is always defined.
Help much appreciated (I realise the issue should be fixed too ;p).
[EDIT] I've edited the error to indicate that the problematic package is the only package that I am installing via github packages (in a couple of the other monorepo packages).
ALSO I edited the entry file so that it only imported React and ReactDOM and rendered a <p> tag and webpack still tried loading this package... so unless there is something wrong with the webpack config, this is some odd behaviour.

Webpack 5 module federation missing chunk when dynamically loading remote module

I am trying to split a big monolith React app into micro-frontends using webpack module federation.
I already have the remote module deployed and working great when running the dev server locally, everything works perfectly fine.
But after running yarn build and deploying the consumer app, it fails with the following error:
Uncaught (in promise) ChunkLoadError: Loading chunk 935 failed.
When commenting out the lazy loaded remote module, everything works fine.
Anyone have any idea how to get webpack to build correctly with a remotely loaded module?
This is my consumer component:
import WorkOrderTrackingErrorBoundary from './work_order_tracking_error_boundary'
const WorkOrderTracking = lazy(() => import('dMove/WorkOrderTracking'))
const WorkOrderTrackingPage = (props) => {
const spinner = (
<SpinnerContainer>
<Spinner type="bars" color="#3e145e" width="48px"/>
</SpinnerContainer>
)
return (
<Suspense fallback={spinner}>
<WorkOrderTrackingErrorBoundary>
<WorkOrderTracking/>
</WorkOrderTrackingErrorBoundary>
</Suspense>
);
};
export default WorkOrderTrackingPage;
and this is my webpack.prod.config.js file:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const StringReplacePlugin = require('string-replace-webpack-plugin');
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin")
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const paths = require('./paths');
const path = require('path');
module.exports = {
bail: true,
mode: 'production',
devtool: 'source-map',
module: {
rules: [
{
oneOf: [
{
test: /\.(js|jsx)$/,
exclude: paths.appNodeModules,
use: {
loader: 'babel-loader'
}
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader'
}
]
},
{
test: [
/\.bmp$/,
/\.gif$/,
/\.jpe?g$/,
/\.png$/,
/\.svg$/
],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]'
}
},
{
exclude: [paths.appResources, paths.appNodeModules],
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}
]
},
{
include: [paths.appResources, paths.appNodeModules],
test: /\.css$/,
use: [
{
loader: 'style-loader' // creates style nodes from JS strings
},
{
loader: 'css-loader' // translates CSS into CommonJS
}
]
},
{
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
loader: require.resolve('file-loader'),
options: {
name: 'static/media/[name].[hash:8].[ext]'
}
}
]
}
]
},
plugins: [
new ModuleFederationPlugin({
name: "dView", // name of this project
filename: "remoteEntry.js", // entry file to this project, remoteEntry.js is the conventional name
exposes: {
// components exposed out for other projects to consume
},
remotes: {
// projects to consume
dMove: "dMove#https://dmove-dev.3dsignals.io/remoteEntry.js"
},
shared: {
// shared modules between projects
react: {singleton: true},
"react-dom": {singleton: true}
}
}),
new webpack.DefinePlugin({
"GET_API_TOKEN_URL": JSON.stringify("/security/getAPIToken"),
"GET_REFRESH_TOKEN_URL": JSON.stringify("/security/refreshToken"),
"LOGIN_WITH_FOREIGN_IDM": JSON.stringify("/security/foreignLogin"),
"MAPBOX_API_TOKEN": JSON.stringify("pk.eyJ1IjoiM2RzZGV2b3BzIiwiYSI6ImNrazB2ZHJ2bTBsOTMydnJ1cG40dXc2NjYifQ.pGAk7cQ-ekRJY9KSSrW3lg")
}),
new StringReplacePlugin(),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}
}),
new NodePolyfillPlugin()
],
output: {
filename: 'static/js/bundle.js',
chunkFilename: 'static/js/[name].[contenthash].chunk.js',
publicPath: '/',
path: paths.appBuild,
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')
},
entry: [
'#babel/polyfill',
paths.appIndexJs
],
resolve: {
modules: [
'node_modules',
paths.appNodeModules,
paths.appSrc,
paths.appResources
],
extensions: [
'.web.js',
'.mjs',
'.js',
'.json',
'.web.jsx',
'.jsx',
'tsx',
'ts'
]
}
};
ChunkLoadError: Loading chunk 946 failed. (missing:
I was also facing the missing - Uncaught (in promise) ChunkLoadError: Loading chunk 935 failed when access the chunks of another remote entry js and other chunks in development server but it's working fine local environment.
This chunk file was loading but content type showing as text/html instead of application/javascript when file loads in network tab response header.
You can check the response header - content type as application/javascript..If no then try to check nginx web server config for MIME types.
For me, it worked well in UAT but SIT was showing this error.
Hopes this will help to understand the reason of chunk files missing error.
In your webpack.prod.config.js file, eagerly load all of your shared libaries -
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const StringReplacePlugin = require('string-replace-webpack-plugin');
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin")
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const paths = require('./paths');
const path = require('path');
//DO THIS
const packageJson = require("../package.json");
const eagerlyLoadedDependencyObject = Object.keys(
packageJson.dependencies
).reduce((obj, val) => {
obj[val] = {
eager: true,
};
return obj;
}, {});
module.exports = {
bail: true,
mode: 'production',
devtool: 'source-map',
module: {
rules: [
{
oneOf: [
{
test: /\.(js|jsx)$/,
exclude: paths.appNodeModules,
use: {
loader: 'babel-loader'
}
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader'
}
]
},
{
test: [
/\.bmp$/,
/\.gif$/,
/\.jpe?g$/,
/\.png$/,
/\.svg$/
],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]'
}
},
{
exclude: [paths.appResources, paths.appNodeModules],
test: /\.css$/,
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
}
]
},
{
include: [paths.appResources, paths.appNodeModules],
test: /\.css$/,
use: [
{
loader: 'style-loader' // creates style nodes from JS strings
},
{
loader: 'css-loader' // translates CSS into CommonJS
}
]
},
{
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
loader: require.resolve('file-loader'),
options: {
name: 'static/media/[name].[hash:8].[ext]'
}
}
]
}
]
},
plugins: [
new ModuleFederationPlugin({
name: "dView", // name of this project
filename: "remoteEntry.js", // entry file to this project, remoteEntry.js is the conventional name
exposes: {
// components exposed out for other projects to consume
},
remotes: {
// projects to consume
dMove: "dMove#https://dmove-dev.3dsignals.io/remoteEntry.js"
},
shared: packageJson.dependencies,
}),
new webpack.DefinePlugin({
"GET_API_TOKEN_URL": JSON.stringify("/security/getAPIToken"),
"GET_REFRESH_TOKEN_URL": JSON.stringify("/security/refreshToken"),
"LOGIN_WITH_FOREIGN_IDM": JSON.stringify("/security/foreignLogin"),
"MAPBOX_API_TOKEN": JSON.stringify("pk.eyJ1IjoiM2RzZGV2b3BzIiwiYSI6ImNrazB2ZHJ2bTBsOTMydnJ1cG40dXc2NjYifQ.pGAk7cQ-ekRJY9KSSrW3lg")
}),
new StringReplacePlugin(),
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}
}),
new NodePolyfillPlugin()
],
output: {
filename: 'static/js/bundle.js',
chunkFilename: 'static/js/[name].[contenthash].chunk.js',
publicPath: '/',
path: paths.appBuild,
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')
},
entry: [
'#babel/polyfill',
paths.appIndexJs
],
resolve: {
modules: [
'node_modules',
paths.appNodeModules,
paths.appSrc,
paths.appResources
],
extensions: [
'.web.js',
'.mjs',
'.js',
'.json',
'.web.jsx',
'.jsx',
'tsx',
'ts'
]
}
};
eagerlyLoadedDependencyObject changes your dependencies from -
{
"react": "17.0.2",
"react-dom": "17.0.2",
"react-redux": "7.2.6",
"react-router-dom": "5.3.4"
}
to this -
{
"react":
{
"eager": true
},
"react-dom":
{
"eager": true
},
"react-redux":
{
"eager": true
},
"react-router-dom":
{
"eager": true
}
}

How to fix a Babel/runtime/helper issue in Webpack 5?

I want to upgrade to webpack 5. I've followed the official guide, upgraded all critical libraries (react17, babel, loaders, etc.). When launching the app, it crashes with 23 errors. 21 of them come from #babel/runtime/helpers.
A typical error looks like this:
ERROR in ../../node_modules/#babel/runtime/helpers/esm/createSuper.js 1:0-46
Module not found: Error: Can't resolve './getPrototypeOf' in '/Users/myName/Desktop/myapp/node_modules/#babel/runtime/helpers/esm'
The two other errors are:
Module not found: Error: Can't resolve 'url-loader'
ERROR in FaviconsWebpackPlugin - This FaviconsWebpackPlugin version is not compatible with your current HtmlWebpackPlugin version.
Please upgrade to HtmlWebpackPlugin >= 5 OR downgrade to FaviconsWebpackPlugin 2.x
Note: My html-webpack-plugin version is above 5 and favicons-webpack-plugin is the latest version as well...
Anyway, here is my webpack file:
const FaviconsWebpackPlugin = require("favicons-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const path = require("path");
const TerserPlugin = require("terser-webpack-plugin");
const webpack = require("webpack");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const getKonf = require("./konf");
const getWebpackServerOptions = require("./server");
function buildWebpackConfiguration() {
const konfiguration = getKonf("development"); // returns a large json with proxies, token, etc.
const rootPath = path.resolve(__dirname, "../../../");
return {
devtool: "eval-source-map",
mode: "development",
node: {
global: false,
__filename: false,
__dirname: false,
},
resolve: {
extensions: [".json", ".jsx", ".js", ".tsx", ".ts"],
alias: {
"#componens": "./components",
"react-dom": "#hot-loader/react-dom",
},
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules\/(?!(redux-logger|strict-uri-encode|query-string)\/).*/,
use: [
{
loader: "babel-loader",
options: {
configFile: path.resolve(rootPath, "./babel.config.js"),
},
},
"react-hot-loader/webpack",
],
},
{
test: /\.html$/,
use: ["html-loader"],
},
{
test: /\.less$/,
exclude: /\.m\.less$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
},
{
test: /\.(eot|gif|jpg|png|svg|ttf|woff)$/,
exclude: [
path.resolve(rootPath, "./assets/svg"),
path.resolve(rootPath, "./icon/glyphs"),
path.resolve(rootPath, "./search/assets"),
],
use: "url-loader?limit=1024",
},
{
test: /\.m\.less$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[local]___[hash:base64:5]",
},
},
},
"less-loader",
],
},
{
test: /\.svg$/,
use: {
loader:
"svg-inline-loader?{'removeTags': true, 'removingTags': ['title', 'desc']",
},
},
{
test: /\.tsx?$/,
use: [{ loader: "ts-loader", options: { transpileOnly: true } }],
exclude: /node_modules/,
},
{
include: /assets\/sw/,
test: /\.js$/,
loader: "file-loader",
},
],
},
plugins: [
new HtmlWebpackPlugin({
title: "My app",
template: path.resolve(__dirname, "./template/index.ejs"),
minify: true,
hash: true,
scripts: [],
styles: [],
}),
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("development"),
"process.env.MOCK_REQUESTS": JSON.stringify(
process.env.MOCK_REQUESTS || "0"
),
KONF: JSON.stringify(konfiguration),
}),
new FaviconsWebpackPlugin({
logo: path.resolve(rootPath, "./assets/logo.svg"),
inject: true,
title: "My App",
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /de|en|fr|zh/),
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
chunkFilename: "[id].[contenthash].css",
}),
new BundleAnalyzerPlugin(),
],
optimization: {
minimize: true,
minimizer: [new OptimizeCSSAssetsPlugin({}), new TerserPlugin()],
moduleIds: "deterministic",
splitChunks: {
chunks: "all",
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
name: "node_vendors",
chunks: "all",
},
},
},
},
devServer: getWebpackServerOptions(konfiguration),
};
}
module.exports = buildWebpackConfiguration;
Here is my Babel config file:
module.exports = {
ignore: ["node_modules"],
babelrcRoots: [".", "./packages/*", "./app/*"],
presets: [
"#babel/preset-typescript",
[
"#babel/preset-env",
{
targets: {
browsers: ["defaults"],
},
},
],
"#babel/preset-react",
],
env: {
test: {
plugins: [
[
"babel-plugin-react-css-modules",
{
generateScopedName: "[local]",
filetypes: {
".less": {
syntax: "postcss-less",
},
},
},
],
],
},
development: {
plugins: [
[
"babel-plugin-react-css-modules",
{
webpackHotModuleReloading: true,
generateScopedName: "[local]___[hash:base64:5]",
handleMissingStyleName: "warn",
filetypes: {
".less": {
syntax: "postcss-less",
},
},
},
],
],
},
production: {
plugins: [
[
"babel-plugin-react-css-modules",
{
webpackHotModuleReloading: true,
generateScopedName: "[hash:base64]",
filetypes: {
".less": {
syntax: "postcss-less",
},
},
},
],
],
},
},
plugins: [
"#babel/plugin-transform-object-assign",
"#babel/plugin-transform-regenerator",
"#babel/plugin-transform-runtime",
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-transform-modules-commonjs",
["#babel/plugin-proposal-class-properties", { loose: true }],
[
"module-resolver",
{
cwd: "babelrc",
root: "./",
alias: {
"#components": "./components",
"#assets": "./assets",
},
},
],
],
};
How to fix this?
releted to https://github.com/babel/babel/issues/8462, runtime issues can be solved by upgrading the #babel/runtime pkg version above 7.12.0

Resources