0

I'm starting a React project with ES6 classes (and ESLint with airbnb config) and I need webpack to bundle them.

I started with the React tutorial and tried using const React = require('react'); and const $ = require('jquery');, but I realized my bundle grew from 15 kb to 700 kb. I then decided to include jquery, react and react-dom via <script/> tags.

Hash: 082980fb232d17977e55
Version: webpack 1.13.0
Time: 869ms
    Asset     Size  Chunks             Chunk Names
bundle.js  13.3 kB       0  [emitted]  app
    + 5 hidden modules

But when I remove the const React = require('react');, I get errors in my code (e.g. : React must be in scope when using JSX - react/react-in-jsx-scope). I then read some docs about Webpack's externals, and tried doing this :

module.exports = {
  entry: {
    app: './main.js',
  },
  output: {
    filename: 'bundle.js',
  },
  externals: {
    jquery: 'jQuery',
    $: '$',
    React: 'React',
    ReactDOM: 'ReactDOM',
    marked: 'marked',
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
      },
    ],
  },
};

But Webpack bundles them anyway, whereas I read here and here it shouldn't.

Hash: 6438094053346ce42228
Version: webpack 1.13.0
Time: 4975ms
    Asset    Size  Chunks             Chunk Names
bundle.js  709 kB       0  [emitted]  app
    + 172 hidden modules

What am I missing?

Thanks in advance!

Community
  • 1
  • 1
adrienharnay
  • 795
  • 2
  • 9
  • 27

1 Answers1

0

You can bundle all dependencies into a separate bundle by using webpack's CommonsChunkPlugin. Require all dependencies normally.

const webpack = require('webpack');
const pkg = require('./package.json');

const libs = Object.keys(pkg.dependencies); // collect all dependencies from package 

module.exports = {
  entry: {
    app: './main.js',
    libs: libs // the entry point for the libs
  },
  output: {
    filename: 'bundle.js',
  },
  externals: {
    jquery: 'jQuery',
    $: '$',
    React: 'React',
    ReactDOM: 'ReactDOM',
    marked: 'marked',
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
      },
    ],
  },
  plugins: [
    plugins: [
        new webpack.optimize.CommonsChunkPlugin("libs", "libs.js") // bundle all libs to libs.js
    ]
};
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
  • Hello, thanks for this answer, I tried this too and since I have to load the "libs.js" in my html too, it still takes the same time to run... I'd like NOT to bundle jquery and react. – adrienharnay Apr 19 '16 at 09:08
  • Loading multiple separate dependencies takes more time, then one dependencies bundle. You're worrying about caching? – Ori Drori Apr 19 '16 at 09:11
  • Yes indeed, I had guessed loading react, react-dom and jquery from a link (e.g. ``) was faster because the file would be cached by the user, because present on all websites, whereas bundling them would force the user to load them at least once (first time on my website). Am I wrong? – adrienharnay Apr 19 '16 at 15:22
  • It depends on the library popularity, and the versions the user have. JQuery will probably be cached with multiple versions. The others maybe for react, probably not for marked. 4 round trips instead of one, I'm not sure it's better, but you can profile. – Ori Drori Apr 19 '16 at 16:00