Decrease react app bundle size using webpack-merge

mdrahiem

Rahimuddin

Posted on July 23, 2020

Decrease react app bundle size using webpack-merge

Hello,

First of all I am very new to writing articles. Please bear with me.

While developing a react app we generally have a local host server, hot-reloading and strong source mapping which don't need in production for obvious reasons. So it doesn't make sense to have these tools unnecessarily which increases the bundle size.

To minimize bundle size by having these tools only in development we can make use of a plugin called webpack-merge. So, to achieve this we are going to follow the below steps.

Step1:

Install webpack-merge using yarn add --dev webpack-merge or npm install --save-dev webpack-merge.

Step2:

split the existing webpack.config.js to three files.

Alt Text

webpack.common.js It contains the common code which we use for development and production both

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const localConfig = require('./src/common/localConfig');

module.exports = {
  entry: {
    index: './src/index.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve(__dirname, 'src'),
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            plugins: [
              '@babel/plugin-transform-runtime',
              '@babel/plugin-proposal-class-properties'
            ]
          }
        }
      },{
        test: /logo.svg$/,
        loader: 'svg-url-loader'
      }, {
        test: /abcd-.*\.(?:le|c)ss$/,
        loaders: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader',
        ]
      }
    ],
  },
  plugins: [
    new CleanWebpackPlugin({ cleanStaleWebpackAssets: false }),
    new HtmlWebpackPlugin({
      template: "./src/index.ejs",
      inject: true,
      filename: "./index.html",
      templateParameters: {
        'localConfig': localConfig
      }
    }),
    new MiniCssExtractPlugin({
      filename: '[name]-[contenthash].css',
      chunkFilename: '[id]-[contenthash].css',
    }),
    new CopyPlugin(
      [
        { from: 'public', to: '' },
      ],
    ),
  ],
  output: {
    filename: '[name].[hash].bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

(the above is only sample code. It doesn't to match with yours)

webpack.dev.js It contains the development code which includes local server, hot reloading etc.

const { merge } = require('webpack-merge');
const common = require('./webpack.common');

module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer: {
    port: 3003,
    https: true,
    contentBase: './dist',
    hot: true,
    allowedHosts: [
      'local.dev.abcdefg.net'
    ],
    public: 'https://local.dev.abcdefg.net:3003/',
    publicPath: '/',
    open: {
      // This doesn't actually work
      app: ['firefox']
    }
  }
});
Enter fullscreen mode Exit fullscreen mode

webpack.prod.js It contains the production related code which doesn't include much (specifically)

const { merge } = require('webpack-merge');
const common = require('./webpack.common');

module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map'
});
Enter fullscreen mode Exit fullscreen mode

Step3:

run npm run build

Now you can compare the build size before and after. :)

💖 💪 🙅 🚩
mdrahiem
Rahimuddin

Posted on July 23, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related