18

I'm trying to generate a second webpack bundle that's dependent on another bundle. Every page needs bundle-one, but only some pages need bundle-two.

For instance, let's say I have the following entry point scripts (these are trivial examples, just using them to get the point across):

bundle-one.js

import $ from 'jquery';
$(document).data('key', 'value');

bundle-two.js

import $ from 'jquery';
const value = $(document).data('key');

I know that I can use CommonsChunkPlugin to generate a commons.js file containing the WebPack loader and jQuery, but that would require loading both commons.js and bundle-one.js on every page, even when I don't need to load bundle-two.js.

So, basically: is there a way to build bundle-one.js as the "main" JavaScript bundle for all my pages, and then have bundle-two.js setup to load jQuery from bundle-one.js?

dstaley
  • 1,002
  • 1
  • 12
  • 32
  • Possible solution [here](http://stackoverflow.com/questions/30329337/how-to-bundle-vendor-scripts-separately-and-require-them-as-needed-with-webpack?rq=1) – highFlyingSmurfs Sep 27 '16 at 04:42

2 Answers2

10

Option 1

Have two separate Webpack configs, one for each bundle. In your first bundle, expose jQuery as a global variable when you first require it using the expose-loader:

loaders: [
    { test: require.resolve('jquery'), loader: 'expose?jQuery!expose?$' }
]

Then, in your second bundle config, tell Webpack that jQuery is "external" and shouldn't be bundled in with the rest of the code:

{
    externals: {
        // require("jquery") is external and available
        //  on the global var jQuery
        "jquery": "jQuery"
    }
}

This way the first bundle exposes jQuery as a global variable, then the second bundle looks for that global variable instead of including the source.

Option 2

I'm not sure if this will work, but the CommonsChunkPlugin documentation says you can specify the name config option as an existing chunk. You try setting the name to your bundle1 entry point chunk name, and in theory jQuery (and other libs required across all chunks) will be built into bundle 1, and not bundle 2.

Community
  • 1
  • 1
Andy Ray
  • 30,372
  • 14
  • 101
  • 138
  • 1
    I went with Option 2 since it seemed the most scalable when the number of libraries reused from bundle 1 is variable. I gave it a test with a simple set of modules, and you're correct in that the common chunks are built into the entry point defined using the `name` parameter. – dstaley Sep 30 '16 at 16:24
2

You can do this in the following way using the provide plugin -

//webpack.config.js
module.exports = {
  entry: './index.js',
  output: { 
    filename: '[name].js' 
  },
  externals: {
    jquery: 'jQuery'
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
    })
  ]
};

This can be useful for refactoring legacy code with a lot of different files referencing $.

Pritish Vaidya
  • 21,561
  • 3
  • 58
  • 76