Reduce abnormally high bundle size

Viewed 1037

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:

enter image description here

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 of import 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?

0 Answers
Related