Why is my Webpack bundle so large?
Asked Answered
R

2

6

I am writing some JavaScript which uses Moment.js and Handlebars. Moment.js is supposed to be 30 KB gzipped and Handlebars is supposed to be less than 10 KB gzipped. But when I use Webpack to bundle my code, I get a resulting file which is 271 KB!

I installed webpack-bundle-size-analyzer to investigate and found much larger files than expected:

$ webpack --json | webpack-bundle-size-analyzer
moment: 454.54 KB (74.1%)
handlebars: 94.39 KB (15.4%)
twitter-text: 62.3 KB (10.2%)
<self>: 1.94 KB (0.317%)

I have a feeling I am doing something which is causing a lot of unnecessary things to be loaded since I was expecting a final file size <100 KB.

main.js

var template = require('./template.handlebars')
var Handlebars = require('handlebars/runtime')
var twitter = require('twitter-text')
var moment = require('moment')

webpack.config.js

var path = require('path')
var webpack = require('webpack')

module.exports = {
  entry: './src/main.js',

  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'bundle.min.js'
  },

  resolveLoader: {
    root: path.join(__dirname, 'node_modules')
  },

  module: {
    loaders: [
      {
        test: /\.handlebars$/,
        loader: 'handlebars-loader'
      }
    ]
  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
}
Rhettrhetta answered 10/7, 2016 at 2:20 Comment(2)
are you configuring for prod or dev?Jook
I saved quite a bit of space by switching from moment to date-fns. I can probably also save a bit of space by not using handlebars.Rhettrhetta
C
6

Update on Aug 10

You may refer to this issue on github/moment. Basically you can eliminate out all other locales which you don't need.

Extract from the comments:

plugins: [
    new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en|zh-tw)$/)
]

I think the webpack did its best already. When you look into the files in node_modules/moment/min/

You will see these:

220K  moment-with-locales.min.js
 57K  moment.min.js

So, if you include the moment with locales, 2XXKB is making sense. To further reduce the size, you may try

  1. include the moment without locales explicitly

    var moment = require('moment/min/moment.min')
    // if you dun need the locale support
    
  2. Or you can try to compress your output with gz manually with this plugin compression-webpack-plugin.

Cowes answered 9/8, 2016 at 23:7 Comment(1)
Actually, if you have access to the webserver, let say express, you can easily do the compression by adding app.use(compression({ threshold: 0 })). This helps compress my js file from 600kb to 200kb. :DCowes
P
1

Add IgnorePlugin into webpack.config.js file and import locale/xx what you need.

Read more: https://webpack.js.org/plugins/ignore-plugin/

const webpack = require('webpack')
new webpack.IgnorePlugin({
  resourceRegExp: /^\.\/locale$/,
  contextRegExp: /moment$/,
});
Poucher answered 1/2, 2023 at 12:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.