My bundle size for a small single-page React project is abnormally high (19mb in development mode), (7mb in production mode).
I have tried to search for potential solutions, but most solutions deal with optimizing at the sub-megabyte level. However, this is a pathological case and I am certain that I must have a gross configuration mistake causing the abnormal size. The distribution is as follows:
In actuality, webpack output says the bundle size is 27Mb (!):
Version: webpack 4.44.1
Time: 29086ms
Built at: 11/17/2020 5:52:02 PM
Asset Size Chunks Chunk Names
favicon.ico 1.26 KiB [emitted]
index.html 2.02 KiB [emitted]
main.bundle.js 27.4 MiB main [emitted] main
Entrypoint main = main.bundle.js
[0] multi (webpack)-dev-server/client?http://0.0.0.0 ./client/index.tsx 40 bytes {main} [built]
[./client/app.tsx] 1.19 KiB {main} [built]
[./client/css/index.css] 525 bytes {main} [built]
[./client/index.css] 519 bytes {main} [built]
[./client/index.tsx] 299 bytes {main} [built]
[./node_modules/antd/dist/antd.less] 539 bytes {main} [built]
[./node_modules/loglevel/lib/loglevel.js] 8.65 KiB {main} [built]
[./node_modules/querystring-es3/index.js] 127 bytes {main} [built]
[./node_modules/react-dom/index.js] 1.33 KiB {main} [built]
[./node_modules/react/index.js] 190 bytes {main} [built]
[./node_modules/strip-ansi/index.js] 161 bytes {main} [built]
[./node_modules/url/url.js] 22.8 KiB {main} [built]
[./node_modules/webpack-dev-server/client/index.js?http://0.0.0.0] (webpack)-dev-server/client?http://0.0.0.0 8.26 KiB {main} [built]
[./node_modules/webpack-dev-server/client/overlay.js] (webpack)-dev-server/client/overlay.js 3.59 KiB {main} [built]
[./node_modules/webpack-dev-server/client/socket.js] (webpack)-dev-server/client/socket.js 1.05 KiB {main} [built]
+ 4603 hidden modules
Child HtmlWebpackCompiler:
1 asset
Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0
[./node_modules/html-webpack-plugin/lib/loader.js!./public/index.html] 2.26 KiB {HtmlWebpackPlugin_0} [built]
ℹ 「wdm」: Compiled successfully.
Things I have tried / facts:
- using webpack 4.44.1
- ensure no unused imports
- try to import as low in the hierarchy as possible (
import Amplify from "@aws-amplify/core"instead ofimport Amplify from"aws-amplify"`) - split into chunks
- various compressions
Here is my configuration:
package.json:
{
"name": "client",
"sideEffects": [
"*.css"
],
"version": "0.0.1",
"license": "UNLICENSED",
"description": "",
"scripts": {
"dev-server": "webpack-dev-server --config webpack.config.dev.js --history-api-fallback --host 0.0.0.0",
"build": "webpack --config webpack.config.prod.js"
},
"dependencies": {
"@ant-design/icons": "^4.1.0",
"@apollo/client": "^3.1.3",
"@stripe/react-stripe-js": "^1.1.2",
"@stripe/stripe-js": "^1.11.0",
"@types/classnames": "^2.2.10",
"@types/react-responsive": "^8.0.2",
"@types/react-router-dom": "^5.1.5",
"@types/stripe": "^7.13.25",
"antd": "^4.2.4",
"aws-amplify": "^3.0.12",
"classnames": "^2.2.6",
"lodash": "4.17.13",
"rc-queue-anim": "^1.8.5",
"rc-scroll-anim": "^2.7.5",
"rc-tween-one": "^2.7.3",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-icons": "^3.11.0",
"react-responsive": "^8.0.3",
"react-router-dom": "^5.2.0"
},
"devDependencies": {
...
},
"resolutions": {
"**/@types/react": "^16.9.0",
"**/upath": "^1.2.0"
}
}
webpack.common.js:
const webpack = require("webpack");
const utils = require("./build-utils");
const path = require("path");
const LodashModuleReplacementPlugin = require("lodash-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
module.exports = {
cache: true,
resolve: {
extensions: [".mjs", ".js", ".jsx", ".tsx", ".ts", ".graphql"],
modules: ["./client, "node_modules"],
},
entry: "./client/index.tsx",
output: {
filename: "[name].[contentHash].bundle.js",
path: path.resolve(__dirname, "dist"),
chunkFilename: "[chunkhash].js",
publicPath: '/',
},
plugins: [
new CleanWebpackPlugin(),
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),
new LodashModuleReplacementPlugin(),
new BundleAnalyzerPlugin(),
],
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: "babel-loader",
exclude: /node_modules/,
},
{
test: /\.ts(x)?$/,
use: [
{ loader: "ts-loader", options: { onlyCompileBundledFiles: true } },
],
exclude: /node_modules/,
},
{
test: /\.graphql?$/,
use: [{ loader: "webpack-graphql-loader" }],
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.less$/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader", // translates CSS into CommonJS
},
{
loader: "less-loader", // compiles Less to CSS
options: {
lessOptions: {
modifyVars: {
"border-radius-base": "2px",
},
javascriptEnabled: true,
},
},
},
],
},
{
test: /\.(png|jp(e*)g|svg|gif|ico)$/,
use: [
{
loader: "file-loader",
options: {
name: "images/[hash]-[name].[ext]",
},
},
],
},
{
test: /\.ico$/,
use: [
{
loader: "file-loader",
},
],
},
],
},
};
webpack.config.dev.js:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
const common = require("./webpack.common");
const merge = require("webpack-merge");
const path = require("path");
module.exports = merge(common, {
mode: "development",
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist_dev"),
publicPath: '/',
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html",
favicon: "./public/favicon.ico",
}),
],
});
Are there any pointers towards reducing the size to a reasonable number?
