Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to exclude vendor module peerDependencies from export in Webpack?

Question

When exporting a bundle in Webpack, how can I exclude 3rd-party module's peerDependency? (not 3rd-party module itself)

Background

I would like to create an UIkit with customized components on top of angular-material framework. With Webpack, I can bundle my customzied components and angular-material together into something like uikit.js, and then port to other application later on. However, I don't want to include angular module itself into this uikit.js.

Issue

It seems that Webpack is "clever" enough to notice that angular module is a dependency of angular-material module, and thus would export both angular module and angular-material module to the bundle. One can either use config.externals: {'angular': 'angular'} or new webpack.IgnorePlugin(/angular$/) to exclude angular module which are explicitly require in the app, but for peerDependency (i.e. the one require inside angular-material), it would still include it.

So, how could I exclude this 3rd-party depended modules out from export?

Example:

// app.js
var angular = require('angular');
var material = require('angular-material');

// ... other application logic    

// webpack.config.js
var webpack = require('webpack');

module.exports = {
  entry: {
    app: './app.js'
  },
  module: {
    loaders: [
      // some module loaders
    ]
  },

  // This only excludes the angular module require by the app, not the one require by the angular-material
  externals: {'angular': 'angular'},

  plugins: [
    // This is the same as externals, only the one required by app.js would be excluded
    new webpack.IgnorePlugin(/angular$/)
  ]
};
like image 897
kavare Avatar asked May 14 '16 00:05

kavare


1 Answers

In the webpack (version 4) config, I export vendor apps into a vendor bundle and chunk all like this:

entry: {
  app: './app.js',
  vendor: [ 'angular', 'angular-material', '...' ],
},
optimization: {
  splitChunks: {
    chunks: 'all',
  }
},

Basically, this indicates which chunks will be selected for optimization and all means that chunks can be shared even between async and non-async chunks. Furthermore, How your modules are built and how you handle dependancies can further streamline your chunk size.

In addition you can provide a function whose return value will indicate whether to include each chunk:

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks (chunk) {
        // exclude `my-excluded-chunk`
        return chunk.name !== 'my-excluded-chunk';
      }
    }
  }
};

Here is a link to webpack explaining the splitChunks plugin.

like image 91
KMims Avatar answered Nov 15 '22 07:11

KMims