React webpack proxy cors issue when calling the api - reactjs

Error in a reactjs , when connecting to the backend end via webpack proxy, the url doesnt work , gives 404 not found even tho the endpoint is correct. working with typescript
and I'm using axios to get my data in the httpservice page.
devServer: {
port: 8083,
historyApiFallback: true,
contentBase: paths.public,
proxy: {
"/api": "http://localhost:8083",
},
headers: {
"Access-Control-Allow-Origin": "*",
https: true,
},
},
mode: "development",
entry: paths.entry,
resolve: {
extensions: [".js", ".jsx", ".ts", ".tsx", ".json"],
alias: {
src: paths.src,
assets: paths.assets,
},
},
output: {
filename: "[name].[chunkhash:8].js",
publicPath: "/",
},
module: {
rules: [
{
test: /\.m?js/,
resolve: {
fullySpecified: false,
},
},
{
test: /\.tsx?$/,
use: "ts-loader",
},
{
test: /\.(png|jpg|gif|svg)$/i,
type: "asset/resource",
},
],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: paths.html,
}),
],
and on the fetch side I call like so
import http from "./httpServices";
const apiEndpoint = "/api/item";
function itemUrl(id) {
return `${apiEndpoint}/${id}`;
}
export const getItemsFromApi = () => {
return http.get(apiEndpoint);
};

you forgot to add pathRewrite: { '^/api': '' }.
The proxy is not overwriting the api endpoint. pathRewrite will replace /api with the target
proxy: {
"/api": {
target: "http://localhost:8083/",
pathRewrite: { "^/api": "" },
},
},
DevServer Documentation: https://webpack.js.org/configuration/dev-server/#devserverproxy

Related

firebase with react and custom webpack throws export loader error

i'm facing an issue with react with custom webpack config while I try to implement firebase
react version: 17+
webpack version: 5+
firebase: 9+
so when i try to import any function from firebase/messaging (also tried other packages from firebase like analytics, same issue happens) it throws an error about exports-loader module that is not installed.
then after installation it throws this error then:
ERROR in ./node_modules/whatwg-fetch/fetch.js (./node_modules/exports-loader/dist/cjs.js?self.fetch!./node_modules/whatwg-fetch/fetch.js)
Module build failed (from ./node_modules/exports-loader/dist/cjs.js):
ValidationError: Invalid options object. Exports Loader has been initialized using an options object that does not match the API schema.
options misses the property 'exports'. Should be:
non-empty string | non-empty string | object { name, syntax?, alias? } | [non-empty string | object { name, syntax?, alias? }, ...] (should not
have fewer than 1 item)
here is my webpack config, is there anything that I'm missing from webpack config or is this issue caused by webpack at all?
module.exports = {
devtool: 'eval',
entry: ['app/app.js'],
loader: { target: 'web' },
mode: 'development',
module: {
strictExportPresence: true,
rules: [
{
test: /\.svg/,
use: {
loader: 'svg-url-loader',
options: {
iesafe: true,
},
},
},
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
loader: 'babel-loader',
include: [PATHS.APP_DIR],
exclude: [/node_modules/],
options: {
...babelConfig,
},
},
{
test: /\.(eot|otf|ttf|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[contenthash].[ext]',
outputPath: 'fonts',
},
},
],
},
{
test: /\.(gif|png|jpe?g)$/i,
use: [
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65,
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.9],
speed: 4,
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75,
},
},
},
{
loader: 'file-loader',
options: {
name: '[name].[contenthash].[ext]',
outputPath: 'images',
},
},
],
},
{
test: /\.(s*)css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 1,
},
},
],
},
],
},
node: { global: false, __dirname: false, __filename: false },
output: {
path: 'build/',
publicPath: '/',
filename: '[name].js',
chunkFilename: '[name].chunk.js',
},
plugins: [
new WebpackBar({
name: 'CSR',
color: '#FFEB3B',
}),
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
}),
new webpack.DefinePlugin({
'process.env': webpackEnv(),
}),
new LoadablePlugin({
filename: 'loadable-stats.json',
writeToDisk: true,
}),
new CopyPlugin({
patterns: [
{
from: path.join('resources', 'public'),
to: 'build',
},
],
}),
new HtmlWebPackPlugin({
template: `/index.ejs`,
title: 'MY APP',
}),
new webpack.HotModuleReplacementPlugin({
multiStep: false,
}),
new CircularDependencyPlugin({
exclude: /a\.js|node_modules/, // exclude node_modules
failOnError: false, // show a warning when there is a circular dependency
}),
],
resolve: {
modules: ['node_modules'],
alias: {
// my aliases
},
},
stats: { preset: 'minimal', moduleTrace: true, errorDetails: true },
target: 'web',
};
the issue was caused by whatwg-fetch
fetch: 'exports-loader?self.fetch!whatwg-fetch',
by removing this line since it wasn't necessary, the problem has been solved

Webpack Hot Reload Issue

I was using webpack 3, there was no hot reload issue and then I upgraded to webpack 5.
Webpack version: ^5.50.0, React version: 17.0.2
My hot reload doesnt work properly. When state ve props are changed, it refresh the page and goes to home directory.
Here is my webpack hot config for development;
const webpack = require('webpack') //to access built-in plugins
const HtmlWebpackPlugin = require('html-webpack-plugin') //installed via npm
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const CopyPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const vendorArray = require('./vendors')
const path = require('path')
const Dotenv = require('dotenv-webpack')
module.exports = {
mode: 'development',
devtool: 'source-map',
entry: {
main: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://0.0.0.0:3002',
'webpack/hot/only-dev-server',
'./src/main.js'
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[hash:8].js'
},
resolve: {
extensions: ['.js', '.jsx', '.css', '.scss', '.json']
},
module: {
rules: [
{
test: /\.js?$/,
exclude: /(node_modules|bower_components)/,
loader: './config/webpack/style-loader'
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: [['#babel/preset-env', { targets: 'defaults' }], '#babel/preset-react'],
plugins: [
'#babel/plugin-transform-runtime',
'#babel/plugin-proposal-class-properties',
'#babel/plugin-proposal-optional-chaining',
'#babel/plugin-proposal-nullish-coalescing-operator',
[
'#babel/plugin-proposal-decorators',
{
legacy: true
}
]
]
}
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']
},
{
test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)([\?]?.*)$/,
type: 'asset/resource'
}
]
},
plugins: [
new webpack.DefinePlugin({
APP_ENV: JSON.stringify('dev')
}),
new HtmlWebpackPlugin({
template: './public/index.html',
templateParameters: {
recaptchaSiteKey: '6LfbRrEZAAAAAL1EiyUSq1yzEw1xqleak2xC2pzi',
intranetLogin: true
}
}),
new MiniCssExtractPlugin(),
new Dotenv({
path: path.resolve(__dirname, './../../.env.test')
})
]
}
And here is server.js
var webpack = require('webpack')
var config = require('./config/webpack/webpack-hot.config')
var WebpackDevServer = require('webpack-dev-server')
const stats = {
assets: true,
children: false,
chunks: false,
hash: false,
modules: false,
publicPath: false,
timings: true,
version: false,
warnings: true,
colors: { green: '\u001b[32m' }
}
config.plugins.push(
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development'),
TARGET: '"web"'
}
})
)
process.env.BABEL_ENV = 'dev'
new WebpackDevServer(webpack(config), {
hot: true,
contentBase: __dirname,
publicPath: '/',
compress: true,
historyApiFallback: true,
stats: stats,
port: 3002,
host: '0.0.0.0',
proxy: {
'/auth/*': {
target: 'blablabla',
secure: false,
onProxyRes: removeCookiePath,
changeOrigin: true
},
'/api/cti/*': {
target: 'blablabla',
secure: false,
onProxyRes: removeCookiePath,
changeOrigin: true
},
'/api/abc/*': {
secure: false,
target: 'https://blabla',
changeOrigin: true
}
}
}).listen(3002, '0.0.0.0', function(err, result) {
if (err) {
console.log(err)
}
console.log('Listening at http://127.0.0.1:3002')
console.log('webpack is bundling, please wait...')
})
Property contenBase, which you apply, is no longer supported in Webpack 5. Instead use static:
devServer: {
port: 8080,
hot: "only",
static: {
directory: path.join(__dirname, './'),
serveIndex: true,
},
},

Module federation re-renders many times a component in remote react app

I'd like to render my RemoteApp into my ShellApp. My RemoteApp has got a useEffect which makes an API call, but it seems is executed a lot of times.
So I suppose my remote component is re rendered more than it should be.
These are my webpack.config for ShellApp and RemoteApp:
Remote app
const webpack = require('webpack');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const deps = require('./package.json').dependencies;
module.exports = {
output: {
publicPath: 'http://localhost:3003/',
},
resolve: {
extensions: ['.tsx', '.ts', '.jsx', '.js', '.json', '*'],
},
devServer: {
port: 3003,
historyApiFallback: true,
hot: true,
},
module: {
rules: [
{
test: /\.m?js/,
type: 'javascript/auto',
resolve: {
fullySpecified: false,
},
},
{
test: /\.css$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
},
},
],
},
{
test: /\.(ts|tsx|js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.svg$/,
use: ['#svgr/webpack'],
},
{
test: /\.json$/,
loader: 'json-loader',
},
],
},
plugins: [
new ModuleFederationPlugin({
name: 'remoteApp',
filename: 'remoteEntry.js',
remotes: {},
exposes: {
'./Dashboard': './src/pages/Dashboard/Dashboard.jsx',
},
shared: {
...deps,
react: {
singleton: true,
requiredVersion: deps.react,
},
'react-dom': {
singleton: true,
requiredVersion: deps['react-dom'],
},
},
}),
new HtmlWebPackPlugin({
template: './public/index.html',
}),
new webpack.HotModuleReplacementPlugin(),
new ESLintPlugin({
extensions: ['js', 'jsx'],
}),
],
};
Shell app
const webpack = require('webpack');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const deps = require('./package.json').dependencies;
module.exports = {
output: {
publicPath: 'http://localhost:3000/',
},
resolve: {
extensions: ['.tsx', '.ts', '.jsx', '.js', '.json', '*'],
},
devServer: {
port: 3000,
historyApiFallback: true,
hot: true,
},
module: {
rules: [
{
test: /\.m?js/,
type: 'javascript/auto',
resolve: {
fullySpecified: false,
},
},
{
test: /\.css$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
},
},
],
},
{
test: /\.(ts|tsx|js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.svg$/,
use: ['#svgr/webpack'],
},
{
test: /\.json$/,
loader: 'json-loader',
},
],
},
plugins: [
new ModuleFederationPlugin({
name: 'frontend_shell',
filename: 'remoteEntry.js',
remotes: {
dashboard: 'frontend_equity_credit#http://localhost:3003/remoteEntry.js',
},
exposes: {},
shared: {
...deps,
react: {
singleton: true,
requiredVersion: deps.react,
},
'react-dom': {
singleton: true,
requiredVersion: deps['react-dom'],
},
},
}),
new HtmlWebPackPlugin({
template: './public/index.html',
}),
new webpack.HotModuleReplacementPlugin(),
new ESLintPlugin({
extensions: ['js', 'jsx'],
}),
],
};
I'm importing the remote component like this in Shell App.jsx
import Dashboard from 'dashboard/Dashboard';
function App() {
return (
<div>
<Dashboard/>
</div>
);
}
Finally, this is my Dashboard.jsx component inside the Remote application
import React, { useEffect } from 'react';
import { useStore } from './store/store';
function Dashboard() {
const { globalStore, actions, dispatch } = useStore();
const loggedUserId = globalStore.auth?.userInfo?.id;
useEffect(() => {
if (loggedUserId) {
dispatch(actions.getUsersPreferences(loggedUserId)); //API CALL
}
}, [loggedUserId]);
return (
<>
{/*render api response*/}
</>
);
}
export default Dashboard;
I got this in console:
Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
Any ideas?

Cannot find module Error (React, TypeScript, Webpack)

Want to run app, but get the following error:
This is my project structure:
this is my app module
i use export and also export default are same:
app component
and the imports of the module:
My webpack :
const devSever = (isDev) => !isDev ? {} : {
devServer: {
open: true,
hot: true,
port: 7070,
contentBase: path.join(__dirname,'public')
}
};
const esLintPlugin = (isDev) => isDev ? [] : [new ESLintPlugin({ extensions: ['.ts', '.tsx ','.js']}) ]
module.exports = ({develop}) => ( {
mode: develop ? 'development': 'production',
devtool: develop ? 'inline-source-map' : false,
entry:{
app: './src/index.tsx',
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
assetModuleFilename: 'assets/[hash][ext]' //may be hash
},
module: {
rules: [
{
test: /\.(ts|tsx|js)$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
test: /\.(?:ico|gif|png|jpg|jpeg|svg)$/i,
type: 'asset/resource'
},
{
test: /\.(woff(2)?|eot|ttf|otf)$/i,
type: 'asset/resource'
},
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader,'css-loader']
}
]
},
resolve: {
extensions: ['.tsx','.ts','.js']
},
plugins: [
new CircularDependencyPlugin({
exclude: /a\.js|node_modules/,
include: /dir/,
failOnError: true,
allowAsyncCycles: false,
cwd: process.cwd()
}),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'style.css'
}),
new CopyPlugin({
patterns: [{from: './public' }]
}),
new CleanWebpackPlugin({cleanStaleWebpackAssets: false}),
...esLintPlugin(develop)
],
...devSever(develop)
});
it's all work good only if there are not imports and if i write code only in one component
you check out tsconfig.json
{
"include": ["src/**/*"],
"compilerOptions": {
"rootDir": "./src"
}
}

Webpack hot module replacement stuck at [HMR] Waiting for update signal from WDS

I'm using webpack hot module replacement in my react project.
configuration looks like below.
let compilerConfig = {
entry: [
'babel-polyfill',
'webpack-dev-server/client?http://0.0.0.0:9000/',
'webpack/hot/only-dev-server',
path.join(ws.srcDir, 'client', 'src', 'index.js'),
],
devtool: 'source-map',
output: {
path: path.resolve(ws.srcDir, 'public'),
filename: 'main.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.(?:p|s)?css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: { config: { path: path.join(__dirname, "postcss.config.js") } }
},
],
}),
},
{
test: /\.(png|woff|woff2|eot|ttf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader',
},
{
test: /\.(js|jsx)?$/,
include: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules', 'astro'),
],
loader: 'babel-loader',
options: {
babelrc: false,
presets: [
'react',
'es2015',
'stage-2'
]
},
},
{
test: /\.svg$/i,
use: [
{
loader: "babel-loader",
},
{
loader: "svg-react-loader",
query: {
classIdPrefix: '[name]-[hash:8]__',
propsMap: {
fillRule: 'fill-rule',
foo: 'bar'
},
xmlnsTest: /^xmlns.*$/
}
}
],
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': `"${NODE_ENV}"`,
}),
new ExtractTextPlugin('styles.css'),
new HTMLWebpackPlugin({
template: path.join(ws.srcDir, 'client', 'src', "index.html"),
}),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
};
const serverConfig = {
contentBase: path.resolve(ws.srcDir, 'client', 'src'),
port: process.env.PORT || '9000',
inline: true,
host: '0.0.0.0',
historyApiFallback: true,
stats: {
colors: true,
},
headers: {
'Access-Control-Allow-Origin': '*'
},
};
And i'm starting webpack dev server through gulp as below.
gulp.task('webpack-dev', function() {
WebpackDevServer.addDevServerEntrypoints(compilerConfig, serverConfig);
const webpackConf = webpack(compilerConfig);
new WebpackDevServer(webpackConf, serverConfig)
.listen('9000', '0.0.0.0', function(err) {
if (err)
throw new Error("webpack-dev-server", err);
// Server listening
console.info("[webpack-dev-server]", "http://localhost:9000");
})
})
Getting [WDS] Disconnected! error after some time. And also i'm not seeing [WDS] Hot Module Replacement enabled. log in the console.
when i do a code change webpack is recompiling, but don't see it reflecting in the browser.
Using below version.
webpack = 2.3.x
webpack-dev-server = 2.4.x
Found the problem. I was loading a script in my index.html. That got failed(404). This is causing Hot Module Replacement to fail.

Resources