简体   繁体   中英

Webpack Async Loading with Dynamic Require

I am very new (hours) to webpack.

I'd like to combine async loading, which is awesome, with dynamic requires. Suppose I want to asynchronously require one of two files, './DIRECTORY/FOO' or './DIRECTORY/BAR'. Here's a non-dynamic version that, I think, works as I expect:

if (condition_holds) {
  require.ensure([], function()
                     {
                       require('./DIRECTORY/FOO');
                     });
}
else {
  require.ensure([], function()
                     {
                       require('./DIRECTORY/BAR');
                     });
}

And here's my attempt to make this dynamic:

var file_name = condition_holds ? "FOO" : "BAR";
require.ensure([], function()
                   {
                     require('./DIRECTORY/' + file_name);
                   });

However, when I use webpack to compile these pieces of code, I get very different results. For the first (non-static), two different files are produced, one for FOO and one for BAR, and only that file is asynchronously loaded. For the second, only one file is produced, which contains both FOO and BAR. This is not what I was expecting or want. I'd like separate files to be produced, one for each module, and just that module to be asynchronously downloaded.

Is this expected behavior? If so, why, and how can use dynamic requires but still get separate modules, each loaded separately?

Here is my webpack.config.js:

module.exports =
{
  entry: {
  bundle: './main.js'
  },
  output: {
    path: './public/js/',
    filename: '[name].js',
    publicPath: "/js/"
  }
};

The problem is that webpack statically analyzes your source code. When it sees this:

require('./DIRECTORY/' + file_name);

...it creates a context which is a mapping that at runtime can resolve to bundled modules. Because file_name can be anything according to static analysis (webpack doesn't actually run your code to know what's available), it determines all possible files that could be under ./DIRECTORY/ and includes them in your bundle, which is not what you want.

There's really two problems to solve:

  1. Getting webpack to split your files into separate chunks
  2. Dynamically loading those chunks

It looks like someone has created a bundle-loader that can solve both of these problems.

var file_name = condition_holds ? "FOO" : "BAR";
var dynamicLoad = require('bundle!./DIRECTORY/' + file_name);
dynamicLoad(function (loadedModule) {
  // Use the module
});

According to this write-up , this should split every potential file in this context into its own bundle and give you a way to asynchronously load those bundles at runtime.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM