Renjith P N
Renjith P N

Reputation: 4241

Require multiple files dynamically using webpack bundle loader

I have been trying to load multiple files in a single require using bundle-loader plugin of webpack. Below is how require a single file.

var waitForChunk = require("bundle-loader!./file.js");

// To wait until the chunk is available (and get the exports)
//  you need to async wait for it.
waitForChunk(function(file) {
    // use file like is was required with
    // var file = require("./file.js");
});
// wraps the require in a require.ensure block

But couldn't figure out how this can be achieved , any idea?

Upvotes: 1

Views: 2721

Answers (1)

yadhu
yadhu

Reputation: 15632

As far I see in the docs and other examples I don't think using loaders in require supports multiple files; instead could load a single file/bundle.

Although webpack has this feature of using loaders in require for loading dynamic dependencies, webpack docs discourages its use.

Avoid using this, if at all possible, if you intend your scripts to be environment agnostic (node.js and browser). Use the configuration convention for specifying loaders (see it here).

The bundle-loader wraps a file in a require.ensure block. So why don't we go with the original require.ensure way? You can load multiple dynamic dependencies as follows:

require.ensure(dependencies, callback);

The require.ensure method ensures that every dependency in dependencies can be synchronously required when calling the callback. callback is called with the require function as parameter.

See the below examples. The modules required inside require.ensure is not loaded until you call the loadAsyncDeps function.

example 1:

function loadAsyncDeps(moduleName, cb)
    // `module-a` and `module-b` can now be split into different files,
    // and the callback function will not run until they have loaded.
    require.ensure(['./module-a', './module-b'], function(require) {
        var modules = {
            a: require('./module-a'),
            b: require('./module-b'),
            // ...
        };

        cb(modules[moduleName]); // callback fn which returns required module
    });
}

example 2:

function loadAsyncDeps(moduleName, cb)
    require.ensure([], function() {  //empty first param
        var modules = {
            a: require('./module-a'),
            b: require('./module-b'),
            // ...
        };

        cb(modules[moduleName]); // callback fn which returns required module
    }, 'my-lazy-modules');
}

Here require.ensure defines a split point. Everything goes into a single chunk named my-lazy-modules.


UPDATE:

How to create separate chunk for each of these files? ie, module-a and module-b should go to two different chunks with proper name.

Create separate functions for loading module-a and module-b

Here module-a-1 and module-a-1 are dependencies of module-a

require.ensure(['./module-a', './module-a-1', './module-a-2'], function(require) {
    var a = require('./module-a');
}, 'lazy-module-a');

module-b-1 and module-b-2 are dependencies of module-b module

require.ensure(['./module-b', './module-b-1', './module-b-2'], function(require) {
    var b = require('./module-b');
}, 'lazy-module-b');

As quoted above, the callback function is not invoked until all modules in the dependency array is loaded (and safe for a synchronous require).

Upvotes: 1

Related Questions