Steph Steph - 2 months ago 21
React JSX Question

Code splitting with dynamic modules?

I am using Webpack's code splitting feature within React. I'm building an app where the user will select an option, and the corresponding React component will render. However, I'm finding that using the CommonJs

require.ensure
only works with hard coded strings. When I use variables it seems like it is working, the components switch out. But when I look at the network tab I see that it does not split the code - it doesn't load any new bundles. Where when I hard code, there is a call each time for a new bundle.

Here is what is working:

executeDynamic(component){
var that = this;
switch(component){
case 'SolidButton':
require.ensure([], function(require){
DynamicModule = require(`./elements/SolidButton/index.js`);
that.forceUpdate();
});
break;
case 'ThreeDButton':
require.ensure([], function(require){
DynamicModule = require(`./elements/ThreeDButton/index.js`);
that.forceUpdate();
});
break;
case 'NoPreview':
require.ensure([], function(require){
DynamicModule = require(`./elements/NoPreview/index.js`);
that.forceUpdate();
});
break;
default:
break;
}
}


Here is what I want to be working:

executeDynamic(component){
var that = this;
require.ensure([], function(require) {
DynamicModule = require(`./elements/${component}/index.js`);
that.forceUpdate();
});
}

Answer

I finally got it!! I moved the dynamic require to its own file, so below is my call to that file from my react component, and then the contents of the file. You need the bundle-loader package installed to do this.

So this is where I make the call, passing in this along with the name of the component I want to load.

loadLiveCode(that, component) {
    req(component, function(result) { 
        DynamicModule = result;
        that.forceUpdate();
    });
}

And the dynamicRequire.js file that holds our dynamic require call that utilizes bundle-loader:

module.exports = function loadAsync(expr, callback) {
  var bundledResult = require("bundle!./elements/" + expr + "/index.js");
  bundledResult(function(result) { 
    callback(result); 
  });
};