DEV Community

Cover image for Decrease react app bundle size using webpack-merge
Rahimuddin
Rahimuddin

Posted on

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',
    },
  },
};

(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']
    }
  }
});

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'
});

Step3:

run npm run build

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

Top comments (1)

Collapse
 
arminops profile image
Armin Tor

It's better to have more precise details on 'npm run build' about command running.
Btw, thank you it really helped.