Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I force individually required lodash modules into a vendor chunk with webpack?

I am requiring lodash modules individually, so that my JS build contains only the lodash code that I need (e.g. import map from 'lodash/map' instead of import _ from 'lodash'. (Actually, I'm using babel-plugin-lodash to automate this.) So nowhere in the code do I actually import the whole of 'lodash'.

I would like webpack to put any lodash code that needs to be included into a vendor bundle. Following the webpack examples out there for splitting vendor and app bundles, I know how to include all of lodash in the vendor bundle (using the CommonsChunkPlugin). But I don't want to just use 'lodash' as an entry point and pull in the whole library. Instead, I want to make all the modules that I actually import that start with lodash to end up in the vendor bundle.

Any ideas?

Addition

The situation is further complicated by the fact that I build 3 bundles for each app: a vendor bundle, a bundle of stuff common across apps (which will use lodash modules), and the app-specific code (which will also use lodash modules).

Here are the key parts of my webpack config:

// ...
entry: {
  specificApp: specificAppEntry,
  appCommon: [appCommonEntry],
  vendor: [listOfVendorJsLibraries],
},
// ...
plugins : [
  new webpack.optimize.CommonsChunkPlugin({
    names: ['appCommon', 'vendor'],
    minChunks: Infinity,
  }),
  // ...
],
// ...
like image 805
davidtheclark Avatar asked Sep 25 '22 16:09

davidtheclark


1 Answers

You can pass a minChunks function to implement custom logic: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin

You could use this to check if the module being imported is coming from node_modules/lodash.

e.g. I use the following to pull everything imported from node_modules into a vendor bundle:

import path from 'path'

import webpack from 'webpack'

new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  minChunks: function (module, count) {
    return (
      module.resource &&
      module.resource.indexOf(path.resolve('node_modules')) === 0
    )
  }
})

Working solution for use with CommonsChunkPlugin, as posted in a comment:

  minChunks: function(module, count) {
    return module.resource && module.resource.indexOf('lodash') !== -1
  }
like image 148
Jonny Buchanan Avatar answered Oct 11 '22 12:10

Jonny Buchanan