Асинхронная загрузка Webpack с динамическим требованием

#javascript #webpack

#javascript #webpack

Вопрос:

Я очень новичок (часы) в webpack.

Я бы хотел совместить асинхронную загрузку, которая является потрясающей, с динамическими требованиями. Предположим, я хочу асинхронно запросить один из двух файлов: ‘./DIRECTORY/FOO’ или ‘./DIRECTORY/BAR’. Вот нединамическая версия, которая, я думаю, работает так, как я ожидаю:

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

И вот моя попытка сделать это динамическим:

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

Однако, когда я использую webpack для компиляции этих фрагментов кода, я получаю совсем другие результаты. Для первого (нестатического) создаются два разных файла, один для FOO и один для BAR, и только этот файл загружается асинхронно. Для второго создается только один файл, который содержит как FOO, так и BAR . Это не то, чего я ожидал или чего хотел. Я бы хотел, чтобы создавались отдельные файлы, по одному для каждого модуля, и только этот модуль загружался асинхронно.

Это ожидаемое поведение? Если да, то почему и как можно использовать динамические требования, но при этом получать отдельные модули, каждый из которых загружается отдельно?

Вот мой webpack.config.js:

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

Ответ №1:

Проблема в том, что webpack статически анализирует ваш исходный код. Когда он видит это:

 require('./DIRECTORY/'   file_name);
  

… это создает контекст, который представляет собой сопоставление, которое во время выполнения может разрешаться для связанных модулей. Поскольку file_name в соответствии со статическим анализом может быть что угодно (webpack фактически не запускает ваш код, чтобы узнать, что доступно), он определяет все возможные файлы, которые могут находиться под ./DIRECTORY/ и включает их в ваш пакет, что не то, что вы хотите.

На самом деле нужно решить две проблемы:

  1. Получение webpack для разделения ваших файлов на отдельные блоки
  2. Динамическая загрузка этих фрагментов

Похоже, кто-то создал a bundle-loader , который может решить обе эти проблемы.

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

Согласно этой записи, это должно разделить каждый потенциальный файл в этом контексте на его собственный пакет и дать вам возможность асинхронно загружать эти пакеты во время выполнения.