GuerillaRadio
GuerillaRadio

Reputation: 1297

Webpack - Huge bundle.js file due to FullCalendar

I'm using Fullcalendar & Moment.js to build a simple interactive calendar using JSON data. I'm using Webpack 2 to bundle my JS into one file. Below is a simplified version of my webpack.config.js file (the full thing is loading in much more than this).

var webpack = require('webpack');

var bower_dir = __dirname + '/library/bower_components';

var config = {
    resolve: {
        alias: {
            jquery: bower_dir + '/jquery/src/jquery.js',
            vue: bower_dir + '/vue/dist/vue.js',
            fullCalendar: bower_dir + '/fullcalendar/dist/fullcalendar.js',
            moment: bower_dir + '/moment/moment.js',
        }
    },

    entry: {
        app: './library/js/main.js'
    },

    output: {
        path: __dirname + '/dist/library/js',
        filename: "bundle.js"
    },

    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            Vue: 'vue'
        }),
    ],

    module: {
        noParse: /moment.js/
    }

};

module.exports = config;

I've noticed that my bundle file dramatically increased in file size after both of these were included. I read about similar issues with Moment here and implemented the changes which reduced my uncompressed bundle size from 2.13MB to 1.83MB.

When running the output of webpack --json through the Webpack Visualiser I notice that Full Calendar is still accountable for a huge percentage of the file size, more so than any of the other libraries I'm including (23.7%, the next highest is jQuery at 15.8% and then Vue.JS at 15.4%).

I'm wondering if anyone knows of any way I can reduce this file size? I currently run webpack -p in production which reduces the size down to 656kB but this still seems like a lot.

enter image description here

Upvotes: 3

Views: 1467

Answers (3)

Roman
Roman

Reputation: 21845

Use webpack config file and configure IgnorePlugin to exclude all locale files:

var webpack = require('webpack')

module.exports = {
  ...
  plugins: [
    // Ignore all locale files of moment.js
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
  ],
  ...
};

You might need some locales. To have theem you can import them in your code:

import moment from 'moment'
import 'moment/locale/fr'

Upvotes: 2

Denis Tsoi
Denis Tsoi

Reputation: 10414

Config

entry: {
  moment: bower_dir + '/moment/moment.js',
  fullcalendar: bower_dir + '/fullcalendar/dist/fullcalendar.js',
  app: './library/js/main.js'
},
plugins: [
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    Vue: 'vue'
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: ['moment', 'fullcalendar', 'manifest']
  })
]

Assuming that you absolutely need to serve those library dependancies from your application serve (instead of CDN), then we need to code split and ensure we're separating common libraries that are required/imported within your code base.

Alternatively, you can also reduce the file size by minifying your bundle but i'm assuming that you already know how to do that.

Upvotes: 0

Sasha Ko
Sasha Ko

Reputation: 112

Have you considered using CDN versions for both jQuery and Fullcalendar? First of all, those are more likely to be cached by your users' browsers (jQuery for sure, given that many sites use it) and also caching of those libs will become independent from your dev cycle, which might speed up things on repeated page loads. Don't know how you do caching, but because Fullcalendar and jQuery are part of your bundle, every time you change the bundle the user has to re-download those libs as well. Using an existing CDN removes that issue.

Also if you're using babel for JS transpilation, maybe try out Webpack 2 and with some minimal babel config adjustment you get tree-shaking, which might reduce the size of the bundle as well.

Upvotes: 0

Related Questions