Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically require vendor module with webpack

Tags:

webpack

Normally, with static requires or imports (CommonJS/ES imports), webpack can require any module from /node_modules/, for example:

var vendorModule = require('vendor-module');

But I want to dynamically load a module from /node_modules/ like:

var vendorModuleId = 'vendor-module';

...

var vendorModule = require(vendorModuleId);

This doesn't work because webpack can't determine the dependency at compile time and it's obviously insane to include all of /node_modules/ in the bundle just in case we might want to dynamically load some vendor module.

I'm looking for a way to trick webpack into resolving these modules dynamically. Preferably by telling webpack which modules in /node_modules/ should be included in the bundle via the webpack config file.

Some people say the ContextReplacementPlugin can be useful for these situations, but I can't understand how.

Anybody have any idea how to accomplish this? Thanks in advance!

like image 967
martijnboland Avatar asked Jan 27 '16 23:01

martijnboland


1 Answers

You can make a file for import and export needed modules via loaders.

  1. Create an empty file "./vendors.js";
  2. npm install exports-loader imports-loader --save-dev
  3. In webpack.config.js:

    // config needed vendor modules
    var vendorModules = [
        'one', 'two', 'three', 'vendor-module'
    ];
    
    ...
    
    module.exports = {
    ...
        loaders: [{ // Add loader
            include: require.resolve('./vendors.js'),
            loader: 'imports-loader?' + vendorsModules.map(function(module, index) {
                return 'dep' + index + '=' + module;
            }).join(',') + '!exports-loader?' + vendorsModules.map(function(module, index) {
                return module + '=dep' + index;
            }).join(',')
        },...]
        ...
    }
    
  4. In module where you need to require vendor:

    // import * as vendorsModules from './vendors';
    var vendorsModules = require('./vendors');
    
    var vendorModuleId = 'vendor-module';
    ...
    var vendorModule = vendorsModules[vendorModuleId];
    console.log('module', vendorModule);
    

It will adds configured vendors to your bundle. If you need to lazy load these modules, you need to do more complex modules factory using require.resolve and promise-like interface for getting needed module.

like image 97
Dmitry Yaremenko Avatar answered Oct 02 '22 13:10

Dmitry Yaremenko