Webpack bundle throwing content length mismatch error - reactjs

I'm working on a React project that gets served by a Go application.
I've been trying to integrate a component library, first with Ant Design, and now with Material UI.
In both instances, as soon as I add a simple component (in this case a Button), my webpack bundle throws net::ERR_CONTENT_LENGTH_MISMATCH in Chrome.
Before adding a component library, my outputted bundle is around 1mb, when adding Material it grows to about 5.5mb, with Ant it was about 11mb.
The strange behavior is that this only happens when I bundle the resources in the development mode configuration with Webpack. If I build for production, everything is fine, although I do get the warning about the bundle size exceeding the recommended limit.
My webpack looks like this:
const path = require("path");
const webpack = require("webpack");
const dotenv = require("dotenv-webpack");
const miniCSS = require("mini-css-extract-plugin");
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
entry: path.resolve(__dirname, "src/index.tsx"),
output: {
path: path.resolve(__dirname, "dist"),
filename: "js/anx.js",
},
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js"],
alias: {
components: path.resolve(__dirname, "src/components"),
containers: path.resolve(__dirname, "src/containers"),
src: path.resolve(__dirname, "src"),
},
},
plugins: [
new miniCSS({
filename: "css/anx.css",
}),
],
module: {
rules: [
{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [
{
loader: "ts-loader",
},
],
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{
loader: miniCSS.loader,
options: {
publicPath: "/dist/css",
},
},
"css-loader",
],
},
{
test: /\.s[ac]ss$/,
use: [
{
loader: miniCSS.loader,
options: {
publicPath: "/dist/css",
},
},
"css-loader",
"sass-loader",
],
},
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader",
},
],
},
// When importing a module whose path matches one of the following, just
// assume a corresponding global variable exists and use that instead.
// This is important because it allows us to avoid bundling all of our
// dependencies, which allows browsers to cache those libraries between builds.
externals: {
react: "React",
"react-dom": "ReactDOM",
},
};
if (process.env.NODE_ENV === "production") {
module.exports.devtool = "source-map";
module.exports.mode = "production";
module.exports.optimization = { minimize: true };
module.exports.plugins = (module.exports.plugins || []).concat([
new CopyPlugin([
{
from: "node_modules/react/umd/react.production.min.js",
to: "js/react.js",
},
{
from: "node_modules/react-dom/umd/react-dom.production.min.js",
to: "js/react-dom.js",
},
]),
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: '"production"',
},
}),
new webpack.LoaderOptionsPlugin({
minimize: true,
}),
]);
} else {
module.exports.devtool = "eval-source-map";
module.exports.mode = "development";
module.exports.plugins = (module.exports.plugins || []).concat([
new CopyPlugin([
{
from: "node_modules/react/umd/react.development.js",
to: "js/react.js",
},
{
from: "node_modules/react-dom/umd/react-dom.development.js",
to: "js/react-dom.js",
},
]),
new dotenv({ path: "secrets/.env.dev" }),
]);
}
I suspect that, in development mode, Webpack includes the source maps and the bundle balloons in size, and this somehow results in the content mismatch error. However, I'm not totally sure. Any help would be appreciated
edit: I found a working solution for this by replacing eval-source-map with source-map in the development environments devtool. I'm not totally sure why this works; my suspicion is that it has something to do with my project running on WSL and the bundle sizes that are produced.

Related

Webpack 5 sourcemap loaded by chrome in different "area" - unable to debug

I have two react components - I would like to be able to debug the jsx in chrome.
When I load the page I see my component code where I expect (using inline sourcemap)
The sourcemap is loading (it works with a separate source-map file as well as in-line)
But it loads in another section under the "page" menu in chrome.
I see my jsx code as expected here. If I put a breakpoint (say on line 7 in the above picture) it will add the corresponding breakpoint in my minified code. However if I "hit" the breakpoint it will hit in the minified code and not my original jsx (which I thought was possible with sourcemaps in chrome?)
I've used webpack for sourcemaps before - but I don't remember coming across this problem and haven't had any luck searching stackoverflow/google.
Here is my Webpack.Config
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const SourceMapDevToolPlugin = require('webpack/lib/SourceMapDevToolPlugin');
const webpackEntries = {
SavingsGoalAccount: './src/SavingsGoalAccount.jsx',
SavingsGoalsList: './src/SavingsGoalsList.jsx',
};
module.exports = {
mode: 'production',
entry: webpackEntries,
//devtool: "inline-source-map",
devtool: 'source-map',
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].[contenthash].js',
library: {
type: 'umd',
name: '[name]',
},
globalObject: 'this',
},
resolve: {
extensions: ['.js', '.jsx'],
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /\.(css)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
{
test: /\.s[ac]ss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
externals: {
react: {
root: 'React',
commonjs2: 'react',
commonjs: 'react',
amd: 'react',
},
},
optimization: {
moduleIds: 'deterministic',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
plugins: [
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [path.join(__dirname, 'dist/**/*')],
}),
new MiniCssExtractPlugin(),
],
};
It outputs in my dist folder as expected:
Since you're using devTool value as source-map. It will load the original code you wrote as source map. This also happened to me and I changed the devTool value to a different one as per my need.
As per webpack documetation - https://webpack.js.org/configuration/devtool/#devtool
if the quality is original then it'll load the entire code:
quality: original- You will see the original code that you wrote, assuming all loaders support SourceMapping.
If you don't need it. Please go with an option as per your need.

Webpack chunk loading using HTTP instead of HTTPS

I've just converted one of my React components to use lazy loading and although it builds OK, I'm getting a scrip-src CSP error because the chunk is attempting to load over HTTP instead of HTTPS which the site is running. (If I switch CSP off, I get a mixed-content error so it isn't the CSP itself that's causing the problem )
Content Security Policy: The page's settings blocked the loading of a resource at http://passport.local//app/assets/bundle/1.bundle.js ("script-src"). bootstrap:128
I'm using Webpack 4.46.0
Am I missing a setting to force it to use the same protocol as the main application?
Many Thanks.
Neil
My webpack config is below
const webpack = require('webpack');
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = (env, argv ) =>
{
const IS_DEVELOPMENT = argv.mode === "development";
const IS_PRODUCTION = argv.mode === "production";
let plugins = [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// all options are optional
filename: path.join('..', 'css', 'app.css'),
//chunkFilename: '[id].css',
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
new webpack.DefinePlugin({
'__DEV__': JSON.stringify(true),
'__API_HOST__': JSON.stringify('https://passport.local/'),
}),
] ;
return {
devtool: 'source-map',
optimization: {
minimize: IS_PRODUCTION
},
entry: {
main: [
'./_devapp/app.js',
'./_devapp/css/app.scss'
],
login: [
'./_devapp/login.js',
]
},
output: {
path: path.resolve(__dirname, 'assets', 'bundle'),
filename: '[name].bundle.js'
},
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
alias: {
ui: path.resolve(__dirname, '_devapp/ui/'),
root: path.resolve(__dirname, '_devapp/')
}
},
module: {
rules: [
{
test: /\.(js|jsx|tsx|ts)$/,
exclude: path.resolve(__dirname, 'node_modules'),
use: {
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-env',
'#babel/preset-react',
'#babel/preset-typescript'
],
plugins: [
["#babel/plugin-proposal-decorators", {"legacy": true}],
'#babel/plugin-syntax-dynamic-import',
['#babel/plugin-proposal-class-properties', {"loose": true}],
["#babel/plugin-proposal-private-property-in-object", { "loose": true }],
["#babel/plugin-proposal-private-methods", {"loose": true}]
]
}
},
},
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: '../',
},
},
'css-loader',
'postcss-loader',
'sass-loader'
],
},
{
test: /.(png|woff(2)?|eot|ttf|svg|gif)(\?[a-z0-9=\.]+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '../css/[hash].[ext]'
}
}
]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
}
]
},
externals: {
myApp: 'myApp',
},
plugins: plugins,
};
}
I managed to resolve this. It was caused by a webpack_public_path definition buried in my code. I'd inherited this line in the react site template I used many years ago and never knew what it did... until now:
__webpack_public_path__ = `${window.STATIC_URL}/app/assets/bundle/`;
${window.STATIC_URL} is (at least on my platform) an http:// constant and overrides the https:// that the main site is running on.
Commenting out this line resolved the problem :-)

Autodesk React Forge problem with forge-dataviz-iot-react-components in a empty project

If you install the official npm package, it works.
But according to the official documentation and simply including import { Viewer } from "forge-dataviz-iot-react-components" (like in this example) in a empty new react project (using npx create-react-app) you will get this error:
./node_modules/forge-dataviz-iot-react-components/client/components/BasicTree.jsx 107:16
Module parse failed: Unexpected token (107:16)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| if (node.children.length > 0) {
| return (
> <TreeItem
| id={`tree-node-${node.id}`}
| key={node.id}
Which loader do I need to add on webpack to avoid this error?
it is not possible to include the package https://www.npmjs.com/package/forge-dataviz-iot-react-components inside a react project made with npx create-react-app (hoping Autodesk is going to fix this problem soon).
You need to edit /node_modules/react-scripts/config/webpack.config.js in 2 parts:
one line about PIXI
...
alias: {
'PIXI': "pixi.js/",
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
// Allows for better profiling with ReactDevTools
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
}),
...(modules.webpackAliases || {}),
},
...
and another part about /forge-dataviz-iot-react-component
...
module: {
strictExportPresence: true,
rules: [
// Disable require.ensure as it's not a standard language feature.
{ parser: { requireEnsure: false } },
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
{
test: /forge-dataviz-iot-react-component.*.jsx?$/,
use: [
{
loader: require.resolve('babel-loader'),
options: {
presets: ["#babel/react", ["#babel/env", { "targets": "defaults" }]],
plugins: ["#babel/plugin-transform-spread"]
}
},
],
exclude: path.resolve(__dirname, "node_modules", "forge-dataviz-iot-react-components", "node_modules"),
},
// TODO: Merge this config once `image/avif` is in the mime-db
// https://github.com/jshttp/mime-db
{
test: [/\.avif$/],
loader: require.resolve('url-loader'),
options: {
limit: imageInlineSizeLimit,
mimetype: 'image/avif',
name: 'static/media/[name].[hash:8].[ext]',
},
},
...
after that on /node_modules/forge-dataviz-iot-react-components/client/components/Viewer.jsx you will get errors about undefined Autodesk variable easily fixable changing Autodesk with window.Autodesk.
Although you will not see any other errors, the package will not work.
I recently tried this package and I got the same problem.
So I created a React project from scratch without CRA and followed the webpack.config.js of this repo : Forge Dataviz IOT Reference App
Here's my webpack.config.js file :
const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');
module.exports = {
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
},
resolve: {
modules: [path.join(__dirname, 'src'), 'node_modules'],
alias: {
react: path.join(__dirname, 'node_modules', 'react'),
PIXI: path.resolve(__dirname, "node_modules/pixi.js/"),
},
},
devServer: {
port: process.env.PORT || 3000
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{ loader: "babel-loader" }
]
},
{
test: /forge-dataviz-iot-react-component.*.jsx?$/,
use: [
{
loader: "babel-loader",
options: {
presets: ["#babel/react", ["#babel/env", { "targets": "defaults" }]],
plugins: ["#babel/plugin-transform-spread"]
}
},
],
exclude: path.resolve(__dirname, "node_modules", "forge-dataviz-iot-react-components", "node_modules"),
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
],
},
{
test: /\.svg$/i,
use: {
loader: "svg-url-loader",
options: {
// make loader to behave like url-loader, for all svg files
encoding: "base64",
},
},
},
],
},
plugins: [
new HtmlWebPackPlugin({
template: './src/index.html',
}),
],
};
Update :
If you want to use CRA, you can customise your webpack config using Customize-CRA and create a config-overrides.js like this :
/* config-overrides.js */
const path = require("path");
const {
override,
addExternalBabelPlugins,
babelInclude,
babelExclude,
addWebpackAlias
} = require("customize-cra");
module.exports = override(
babelInclude([
path.resolve("src"), // make sure you link your own source
path.resolve("node_modules")
]),
babelExclude([path.resolve("node_modules/forge-dataviz-iot-react-components/node_modules")]),
addWebpackAlias({
['PIXI']: path.resolve(__dirname, 'node_modules/pixi.js/')
})
);
I managed to make this work on a fresh CreateReactApp project, so you should be able to make it working on your project.

React error even after using DefinePlugin

I am using React 15.4.2 and Redux 3.6.0 with Webpack and this is my webpack.config.js file contents: (some of the code is omitted for brevity)
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const pkg = require('./package.json');
const TARGET = process.env.npm_lifecycle_event;
const PATHS = {
src: path.join(__dirname, 'src/js'),
dist: path.join(__dirname, 'dist')
};
process.env.BABEL_ENV = TARGET;
const common = {
resolve: {
extensions: ['', '.js', '.jsx']
},
entry: {
app: PATHS.src
},
output: {
path: PATHS.dist,
publicPath: '/',
filename: '[name].[hash].js'
},
module: {
loaders: [
{ test: /\.jsx?$/, loaders: ['babel?cacheDirectory'], include: PATHS.src },
{ test: /\.scss$/, exclude: /node_modules/, loaders: ['style', 'css', 'sass'] },
{ test: /(\.ttf|\.woff2?|\.eot|\.svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, exclude: /node_modules/, loader: 'url' },
{ test: /\.(jpe?g|png|gif|svg)$/i, exclude: /node_modules/, loader: 'url?limit=10000!img?progressive=true' },
{ test: /\.json/, loaders: ['json']}
]
},
plugins: [
new HTMLWebpackPlugin({
template: 'src/index.html',
inject: 'body'
})
]
};
if (TARGET === 'build') {
module.exports = merge(common, {
entry: {
vendor: Object.keys(pkg.dependencies)
},
output: {
path: PATHS.dist,
filename: '[name].[chunkhash].js',
chunkFilename: '[chunkhash].js'
},
module: {
loaders: [
{ test: /\.css$/, loader: ExtractTextWebpackPlugin.extract('style', 'css'), include: PATHS.src }
]
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new CleanWebpackPlugin([PATHS.dist]),
new ExtractTextWebpackPlugin('[name].[chunkhash].css'),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest']
})
]
});
}
Running npm run build gives the minified code. But it still gives the error
Warning: It looks like you're using a minified copy of the development build of React. When deploying React apps to production, make sure to use the production build which skips development warnings and is faster. See https://facebook.github.io/react/docs/optimizing-performance.html#use-the-production-build for more details.
I have also tried reordering the plugins in build TARGET, but its giving the same error.
What am I missing here?
P.S. Redux gives the same minification error too.
EDIT
This is my package.json build script:
"scripts": {
...
"build": "NODE_ENV=production webpack --progress"
...
}
EDIT #2
This is the output to a console.log statement from within the application.
You could use this syntax for the DefinePlugin.
new webpack.DefinePlugin({
'process.env':{
'NODE_ENV': JSON.stringify('production')
}
}),
I enabled source maps to see that its a package I have been using that was minified using non-standard ways. So, setting NODE_ENV to 'production' had no effect on the said package. Nevertheless, my Webpack config and my build scripts have been working perfectly fine. Thank you for your help guys!

Webpack -p doesn't create bundle correctly

I started learning React by myself and I decided to create a boilerplate for me. I'm getting a problem to build a project using webpack. When I run in dev mode, works fine. When I run the command 'postinstall' to build for production, it generates a bundle.js with only a few bytes. But when I run the 'postinstall' without the parameter -p, it generates my bundle with ~ 2MB, the same thing when generates for dev mode (obviously because is not set for production). I didn't figure out why the production flag isn't creating my bundle correct. Can someone help me with this problem?
The project is in the repository:
https://github.com/ribeiroguilherme/react-boilerplate-dashboard
The webpack.production.config.js file:
const webpack = require('webpack');
const path = require('path');
const ExtractPlugin = require('extract-text-webpack-plugin');
const CleanPlugin = require('clean-webpack-plugin');
const plugins = [
new CleanPlugin('dist'),
new ExtractPlugin('bundle.css'),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({ minimize: true }),
new webpack.optimize.AggressiveMergingPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
},
}),
];
module.exports = {
devtool: 'eval',
debug: false,
context: __dirname + '/src/client',
entry: {
javascript: './index.jsx',
html: './index.html',
},
output: {
filename: 'bundle.js',
path: __dirname + '/dist',
},
resolve: {
extensions: ['', '.js', '.jsx', '.json'],
root: path.resolve(__dirname, './src/client'),
},
eslint: {
configFile: './.eslintrc',
},
module: {
preLoaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'eslint-loader',
},
],
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['babel-loader'],
},
{
test: /\.html$/,
loader: 'file?name=[name].[ext]',
},
{
test: /\.css$/,
loader: ExtractPlugin.extract('style-loader', 'css-loader'),
},
],
},
plugins: plugins,
};
I'm also worried because the bundle looks pretty big for a project that I just started now. Any hints will be very appreciated.
Best Regards

Resources