Search code examples
reactjswebpackwebpack-2

Do web pack import lib source into every single module?


I started a FE app with react-create-app. later, I moved the exact same source code to a django project of mine with a custom webpack configuration (so it can be loaded with django's static files).

Long story short, my custom webpack build is almost twice as big as the react-create-app build. 278kb vs 478kb

Most of the modules are importing jquery and bootstrap js. So my guess is that my configuration is importing said libraries into each module.

Most of my modules import look like :

let React = require('react');
import $ from 'jquery/src/jquery';
import 'bootstrap/dist/js/bootstrap';

And my webpack config looks like

const webpack = require('webpack');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  entry:[ 
    './app.jsx'
  ],
  output:{
    filename:'../app.bundle.js'
  },
  module:{
    loaders:[
      {
        test:/\.js[x]?$/,
        loader:'babel-loader',
        exclude:/(node_modules)/,
        query:{
          presets:['es2015','react']
        }
      }
    ]
  },
  plugins: [
    new UglifyJsPlugin()
  ]
}; 

Granted is a very basic webpack config. Hence, my guess is that I'm missing a existing plugin in react-create-app, that avoids to import the same library over and over. I have look for information in the docs to wether Webpack would do this, but can't seem to find any.

I've look into commons chunks, but that seems to solve other problem, and I don't really need or want to have an independent chunks bundle.


Solution

  • After further research I changed my webpack config file to :

      plugins: [
        new UglifyJsPlugin(),
        //enable production build:
        new webpack.DefinePlugin({
          'process.env.NODE_ENV': JSON.stringify('production')
        }),
        //expose jquery window.$ global
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            tether: 'tether',
            Tether: 'tether',
            'window.Tether': 'tether',
        })
      ]
    

    So bootstrap.js is able to find the $ object in window, instead of importing the whole source library into the module as before.

    I also changed:

    import $ from 'jquery/src/jquery';
    

    to

    let $ = require('jquery');
    

    It reduced the filsize from 480kb to 300 kbs, which seems in line with the react-create-app bundle.