React Loadable Problem In My React Website - reactjs

Can someone help me with the Issue in my React Website?
We have used react-loadable for chunks whenever we deploy it on production environment the website get stuck on the loading part. Below is the URL
URL WITH LOADABLE: http://fcastage.surge.sh/
Any help will be appreciated.
We have tried making the website using react loadabale and without react loadable. But to make the website fast and load in chunks we have to use loadable . The react loadable is working fine with Development Environment but its not working when I am switching to Production.
Below is the Config File for Production
const HtmlWebpackPlugin = require("html-webpack-plugin");
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const path = require("path")
const webpack = require('webpack');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { ReactLoadablePlugin } = require('react-loadable/webpack')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
mode: "production",
entry: "./app/index.js",
output: {
path: path.resolve(__dirname, "./build"),
filename: '[name].bundle.js',
chunkFilename: '[name].js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader")
},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{
//because remove style-loader,my css can't work
loader: "css-loader",
options: {
importLoaders: 1,
modules: true,
localIdentName: "[local]"
} // translates CSS into CommonJS
},
{
loader: "less-loader" // compiles Sass to CSS
}
]
})
},
{
test: /\.(jpe?g|png|gif|svg|ico)$/i,
use: [
{
loader: "url-loader",
options: {
outputPath: "assets/",
limit: 10 * 1024
}
}
]
},
{
test: /\.(woff|woff2|eot|ttf)$/i,
use: [
{
loader: "url-loader",
options: {
outputPath: "assets/"
}
}
]
}
]
},
optimization : {
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
}
}
}
// minimizer: [
// new UglifyJsPlugin({
// uglifyOptions: {
// compress: {
// unused: true,
// dead_code: true,
// warnings: false
// }
// },
// sourceMap: true
// }),
// ]
},
plugins: [
new HtmlWebpackPlugin({
template: "./app/index.html",
hash: true,
filename: "index.html"
}),
//for surge.sh
new HtmlWebpackPlugin({
template: "./app/index.html",
hash: true,
filename: "200.html"
}),
new CleanWebpackPlugin(),
new ExtractTextPlugin("main.css"),
new webpack.DefinePlugin( {'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.DEBUG': JSON.stringify(process.env.DEBUG) } ),
new ReactLoadablePlugin({
filename: path.resolve(__dirname, "build/react-loadable.json")
})
],
};

Related

Webpack 5 devserver doesnt recompile on file change

I'm new to Webpack configuration and having trouble setting it up and stuck on it for weeks.
I've got it to compile on start but it doesn't rebuild/recompile on changes.
I've tried to preserve log in browser console and when I save changes, it displays:
[webpack-dev-server] "src/components/Login.jsx" from static directory was changed. Reloading...
But since the code hasnt recompiled, theres no changes on the web.
If anyone can assist please.
I'm using:
NPM 6.14.17
Node v18.14.0
"webpack": "^5.47.0",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^4.9.3"
Script> "start": "webpack serve --env type=local"
webpack.config.js
const path = require("path");
// const moment = require('moment');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require ("html-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
let mode = "development";
let target = "web";
if (process.env.NODE_ENV === "production") {
mode = "production";
target = "browserslist";
}
const port = process.env.PORT || 3000;
module.exports = (env) => {
console.log("Passing env", env);
console.log("Target", target);
return {
mode,
stats: "normal",
optimization: {
usedExports: true, //providedExports enabled by default (only used exports are generated for each module)
},
target,
entry: './src/index.js',
output: {
filename: 'bundle.[fullhash].js',
path: path.resolve(__dirname, "dist"),
assetModuleFilename: "images/[hash][ext][query]",
publicPath: '/',
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
}
},
{
test: /\.(png|jpe?g|gif|svg)$/i,
type: "asset",
// loader: 'file-loader',
// type: "asset/resource",
// type: "asset/inline",
// parser: {
// dataUrlCondition: {
// maxSize: 8 * 1024,
// }
// }
},
// {
// test: /\.(s[ac]|c)ss$/i,
// use: [
// {
// loader: MiniCssExtractPlugin.loader,
// options: { publicPath: "" }
// },
// "css-loader",
// "postcss-loader",
// "sass-loader"
// ]
// },
{
test: /\.css/,
use: [
"style-loader",
"css-loader",
],
},
{
test: /\.(sass|scss)$/,
use: [{
loader: 'style-loader', // creates style nodes from JS strings
// options: { minimize: env.type == 'live' },
}, {
loader: 'css-loader', // translates CSS into CommonJS
// options: { minimize: env.type === 'live' },
}, {
loader: 'sass-loader', // compiles Sass to CSS
// options: { minimize: env.type === 'live' },
}],
},
]
},
plugins: [
// new CleanWebpackPlugin(),
// new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
template: "./src/index.html",
// favicon: 'public/favicon.ico',
}),
new BundleAnalyzerPlugin({
analyzerMode: process.env.STATS || "disabled"
}),
],
resolve: {
extensions: [".js", ".jsx"],
},
devtool: 'source-map',
devServer: {
host: 'localhost',
port: port,
liveReload: true,
watchFiles: {
paths: ['src/**/*.jsx', 'public/**/*'],
options: {
usePolling: true,
},
},
static: [
// Simple example
path.resolve(__dirname, 'static'),
// Complex example
{
directory: path.resolve(__dirname, 'static'),
staticOptions: {},
// Don't be confused with `dev.publicPath`, it is `publicPath` for static directory
// Can be:
// publicPath: ['/static-public-path-one/', '/static-public-path-two/'],
publicPath: '/static-public-path/',
// Can be:
// serveIndex: {} (options for the `serveIndex` option you can find https://github.com/expressjs/serve-index)
serveIndex: true,
// Can be:
// watch: {} (options for the `watch` option you can find https://github.com/paulmillr/chokidar)
watch: true,
},
],
hot: true,
historyApiFallback: true,
}
}
}
I've tried looking online for answers and trying different settings but haven't had much luck.
Also tried setting Hot to false but didnt work

Webpack 5, Server-Side rendering, and FOUC

I'm upgrading an existing web site from Webpack 3 to Webpack 5.
The site uses server side rendering for the first load, the client side routing for any in-site navigation. All this worked fine with Webpack 3, but after migrating to Webpack 5 it looks like some of the styles are being applied via javascript and that's creating a FOUC during the first load (after that, in-site navigation works fine and looks correct). As a test, I turned off javascript in my browser; the old site loads fine and looks correct, but the upgraded site does not. It feels like I need style-loader in the server config somewhere, but when that's added, I get a "Cannot GET /" when trying to load the site. Any help is appreciated.
Server-side config
require('dotenv').config({ silent: true });
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const includePaths = [path.resolve(__dirname, 'stylesheets')];
module.exports = {
bail: true,
entry: {
main: './src/entry-server',
},
output: {
path: path.join(__dirname, 'build', 'prerender'),
filename: '[name].js',
publicPath: '/bundle/',
libraryTarget: 'commonjs2',
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
PRERENDER: true,
ASSETS_CDN_PREFIX: JSON.stringify(process.env.ASSETS_CDN_PREFIX || ''),
},
}),
// only load moment english locale: https://github.com/moment/moment/issues/2517
new webpack.ContextReplacementPlugin(/moment[\\/]locale$/, /^\.\/(en)$/),
new webpack.optimize.ModuleConcatenationPlugin(),
new MiniCssExtractPlugin({
ignoreOrder: true,
}),
],
module: {
rules: [
{
test: /\.jsx?$/,
include: path.join(__dirname, 'src'),
use: 'babel-loader',
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
},
},
'postcss-loader',
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths,
data: `$assetprefix: "${process.env.ASSETS_CDN_PREFIX || ''}";`,
},
},
},
],
},
{
test: /\.svg$/,
use: `svg-inline-loader?removeTags&removingTags[]=${['defs', 'style', 'title'].join(',removingTags[]=')}`,
},
],
},
resolve: {
extensions: ['.js', '.jsx', '.css', '.scss', '.json'],
},
target: 'node',
};
Server entry point
export default function (req, res, environmentConstants, callback) {
// ...setup
match({ routes, location: targetUrl }, (error, redirectLocation, renderProps) => {
// ...setup
fetchSomeData().then(() => renderToString(
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>,
))
.then((content) => {
callback(null, {
helmet: Helmet.renderStatic(),
content,
initialState: serialize(store.getState(), { isJSON: true }),
env: serialize(someEnvConstants),
});
})
Client-side config
require('dotenv').config({ silent: true });
const AssetsPlugin = require('assets-webpack-plugin');
const CleanPlugin = require('clean-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
const webpack = require('webpack');
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const includePaths = [path.resolve(__dirname, 'stylesheets')];
// Match all routes that we want to lazy load
const lazyRouteRegex = /route\/([^/]+\/?[^/]+)Route.jsx$/;
module.exports = {
bail: true,
entry: {
main: './src/entry-client',
vendor: [
'react',
'react-dom',
'react-router',
'redux',
'react-redux',
'xmldom',
],
},
output: {
path: path.join(__dirname, 'build', 'public', '[fullhash]'),
filename: '[name].js',
chunkFilename: '[id].chunk.js',
publicPath: `${process.env.ASSETS_CDN_PREFIX || ''}/build/public/[fullhash]/`,
},
plugins: [
// only load moment english locale: https://github.com/moment/moment/issues/2517
new webpack.ContextReplacementPlugin(/moment[\\/]locale$/, /^\.\/(en)$/),
new MiniCssExtractPlugin({
ignoreOrder: true,
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
PRERENDER: false,
ASSETS_CDN_PREFIX: JSON.stringify(process.env.ASSETS_CDN_PREFIX || ''),
},
}),
new AssetsPlugin(),
new CleanPlugin([path.join(__dirname, 'build', 'public')]),
new CompressionPlugin(),
// new BundleAnalyzerPlugin(),
],
module: {
rules: [
{
test: /\.jsx?$/,
include: path.join(__dirname, 'src'),
exclude: lazyRouteRegex,
use: [
{
loader: 'babel-loader',
},
],
},
{
test: lazyRouteRegex,
include: path.resolve(__dirname, 'src'),
use: [
{
loader: 'bundle-loader',
options: {
lazy: true,
},
},
{
loader: 'babel-loader',
},
],
},
{
test: /swiper.*\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: false,
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths,
data: `$assetprefix: "${process.env.ASSETS_CDN_PREFIX || ''}";`,
},
},
},
],
},
{
test: /\.s?css$/,
exclude: /swiper.*\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
},
},
{
loader: 'postcss-loader',
},
{
loader: 'sass-loader',
options: {
sassOptions: {
includePaths,
data: `$assetprefix: "${process.env.ASSETS_CDN_PREFIX || ''}";`,
},
},
},
],
},
{
test: /\.svg$/,
use: `svg-inline-loader?removeTags&removingTags[]=${['defs', 'style', 'title'].join(',removingTags[]=')}`,
},
],
},
resolve: {
extensions: ['.js', '.jsx', '.css', '.scss', '.json'],
},
target: 'web',
};

Can I optimize my webpack config so my production file size gets reduced even more?

I have spent days getting to my current Webpack configuration setup.
When Webpack runs the build, the file size of my minified output file "react_customer.uniqueid.js" ends up being 2.53 MB, I would be satisfied if the file size would be under 1 MB.
Here is a visualization of the bundled JavaScript.
Could this setup be optimized further so the file size gets reduced?
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const nodeExternals = require("webpack-node-externals");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const { EnvironmentPlugin } = require("webpack");
module.exports = {
mode: "production",
entry: {
react_customer: path.resolve(__dirname, "react-customer/index.js"),
react_admin: path.resolve(__dirname, "react-admin/index.js"),
},
output: {
path: path.resolve(__dirname, "production-build"),
filename: "[name].[contenthash].js",
assetModuleFilename: "[name][ext]",
clean: true,
publicPath: "/",
},
//externals: [nodeExternals()],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.uglifyJsMinify,
// `terserOptions` options will be passed to `uglify-js`
// Link to options - https://github.com/mishoo/UglifyJS#minify-options
terserOptions: {},
}),
],
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, /*"style-loader",*/ "css-loader"],
},
{ test: /\.(svg|ico|png|webp|jpg|gif|jpeg)$/, type: "asset/resource" },
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
["#babel/preset-env", { modules: false }],
["#babel/preset-react", { runtime: "automatic" }],
],
},
},
},
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
//"style-loader",
MiniCssExtractPlugin.loader,
// Translates CSS into CommonJS
"css-loader",
// Compiles Sass to CSS
"sass-loader",
],
},
],
},
plugins: [
new EnvironmentPlugin({
backend_server: "https://www.example.com",
frontend_customer: "https://www.example.com",
}),
new BundleAnalyzerPlugin(),
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
filename: "index.html",
template: path.resolve(
__dirname,
"server/templates/other/react-customer-template.html"
),
chunks: ["react_customer"],
}),
new HtmlWebpackPlugin({
filename: "admin.html",
template: path.resolve(
__dirname,
"server/templates/other/react-admin-template.html"
),
chunks: ["react_admin"],
}),
],
};

Webpack collecting wrong src path

I think that the whole problem is in configuring the webpack, the images are successfully collected in the folder when building, but when importing ...
Somewhere I found a solution indicating the public path, but somehow it did not grow together
webpack.config.js
const path = require('path');
// const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
entry: { main: './src/lib/index.js' },
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
libraryTarget: "umd",
library: "#compassplus/ui-mobicash"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
url: true,
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
},
],
include: /\.module\.css$/,
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'
],
exclude: /\.module\.css$/,
},
{
test: /\.(png|jp(e*)g|svg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[hash:12].[ext]',
outputPath: 'images/',
esModule: false,
},
},
],
},
]
},
plugins: [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: 'index.css',
}),
// new HtmlWebpackPlugin({
// template: './public/index.html',
// }),
// new webpack.ProvidePlugin({
// "React": "react",
// }),
],
externals: {
react: 'react',
},
resolve: {
extensions: ['.js', '.jsx'],
},
}
Путь указанный в src / Path in the src:
src="images/809853c38dec.svg"
In the React component, I hook it up via import and pass it as an object
import imgLight from './img/theme-light.svg';
<img src={img} alt='Картинка' className={style.img}></img>
Solved the problem using url-loader:
{
loader: "url-loader",
options: {
limit: 8192,
name: "static/media/[name].[hash:8].[ext]"
},
}

Webpack 3: css-loader style-loader error

I am receiving the following error:
ERROR in ./common/app.css Module parse failed:
E:\universal-starter\common\app.css Unexpected token (1:5) You may
need an appropriate loader to handle this file type.
| body {
| background-color: orange;
| }
My App.js file:
import React from 'react';
require('./app.css');
const App = () => <div>Hello from React</div>;
export default App;
My webpack.config:
const webpack = require('webpack');
const path = require('path');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const HTMLWebpackPlugin = require('html-webpack-plugin');
module.exports = {
devtool: 'inline-source-map',
entry: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:3001',
'webpack/hot/only-dev-server',
'./client/index',
],
target: 'web',
module: {
rules: [
{
enforce: 'pre',
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
emitWarning: true
},
test: /\.(js|jsx)$/
},
{
exclude: /node_modules/,
test: /\.js?$/,
use: ['babel-loader']},
// WHY IS THIS WRONG & CAUSING THE PROBLEM?!?!?!?!
// embed styles in styles folder
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract({
fallback: 'style-loader',
use: ['css-loader']
})
},
// fonts
{
test: /\.(woff|woff2|eot|ttf|svg)$/,
exclude: /node_modules/,
loader: 'url-loader?limit=1024&name=fonts/[name].[ext]'
},
// examine img file size
{
test: /\.(jpe?g|png|svg|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 40000,
name: 'images/[name].[hash].[ext]',
}
},
{
loader: 'image-webpack-loader',
}
]
}
],
},
plugins: [
new ExtractTextWebpackPlugin('./css/styles.css'),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new HTMLWebpackPlugin({
template: './client/template/index.html',
}),
new webpack.DefinePlugin({
'process.env': { BUILD_TARGET: JSON.stringify('client') },
}),
],
devServer: {
host: 'localhost',
port: 3001,
historyApiFallback: true,
hot: true,
},
output: {
path: path.join(__dirname, '.build'),
publicPath: 'http://localhost:3001/',
filename: 'client.js',
},
};
Very little help out there so far on Webpack 3.
Any ideas?
Thanks!!
Try this:
In your App.js file, replace require('./app.css'); for import './app.css'

Resources