warpdesign
warpdesign

Reputation: 747

Dynamic System.import with webpack?

I am trying to port some ES6 code I have written that uses systemjs + Babel.

I didn't have any problem porting most of the code.

However, I have some code that needs to dynamically load an ES6 module, like this:

function load(src) {
    System.import(src).then(function() {});
}

src is an external ES6 module which may also have dependencies (static imports).

How could I port this code to Webpack ? If I try to use require statement I'm getting a WARNING which seems to be normal according to the Webpack docs.

Upvotes: 6

Views: 20943

Answers (4)

sic1
sic1

Reputation: 486

The previous answers were correct, but now in webpack 2.2 + babel (as of writing, v2.2.0-rc.3 is the latest version) we can do this. I have not tested myself, but just did the research that lead me here as well.

Read this from the webpack documentation: Code Splitting with es2015

Just below that section is Dynamic Expressions with this example:

function route(path, query) {
  return import("./routes/" + path + "/route")
    .then(route => new route.Route(query));
}
// This creates a separate chunk for each possible route

Be sure to note you will need to install the Syntax Dynamic Import plugin, as the doc mentions.

Upvotes: 9

David Burrows
David Burrows

Reputation: 5247

Webpack 1 doesn't support System.import, you may be able to work around this by using Webpack's require.ensure to dynamically load modules. Details of that approach may be found here: https://webpack.github.io/docs/code-splitting.html#es6-modules

Depending on exactly what you want to do, you may need to use Webpack's context feature as well, see here for more info https://webpack.github.io/docs/context.html

Webpack 2 should fix these issues as it's going to support ES6 & System.import directly.

Upvotes: 3

You could try to use a library like little-loader to handle this. Example:

var load = require('little-loader');

load('<src>', function(err) {
    // loaded now, do something
});

Upvotes: 1

topheman
topheman

Reputation: 7922

You don't have such thing as "dynamic loading" in webpack (since the bundler needs to go down to all your module dependencies). The closest thing to what you want to achieve (and the right way to do it in webpack) would be to use require.ensure - see documentation.

One way of turning your SystemJS code into webpack would be:

function load(moduleName) {
    switch (moduleName) {
        case 'foo':
            require.ensure([], require) => {
                const foo = require('./foo.js');
                // do something with it
            }
            break;
        case 'bar':
            require.ensure([], require) => {
                const bar = require('./bar.js');
                // do something with it
            }
            break;
    }
}

I'd advise you to make a load function encapsulating each require.ensure (you may want to manage callbacks differently).

You can check out an example here

Upvotes: 2

Related Questions