(Webpack) Как разделить зависимости динамического модуля

Я просто понял, что если вы загружаете модули динамически, используя require.ensure(), webpack не будет анализировать и разбивать зависимости друг на друга. В некотором смысле это имеет смысл, что можно утверждать, что веб-пакет не может знать, переносятся ли когда-либо такие модули, но можем ли мы заставить веб-пакет выполнить эту работу в любом случае?

Пример:

app.js:

require.ensure([ 'module1.js' ], ( require ) => {
    // at some point
    require( 'module1.js' );
}, 'Module1');

require.ensure([ 'module2.js' ], ( require ) => {
    // at some point
    require( 'module2.js' );
}, 'Module2');

module1.js

let io = require( 'socket.io-client' );

module2.js

let io = require( 'socket.io-client' );

Результатом этой компиляции является то, что оба этих модуля "связывают" всю библиотеку socket-io в свои блоки. Мое первоначальное ожидание состояло в том, что CommonsChunkPlugin поймает тех, requires и поместите эту большую библиотеку в общий кусок.

new webpack.optimize.CommonsChunkPlugin( 'common' ),

Не работает однако. Конечно, я всегда мог "разрешить" эту зависимость вручную, но я надеялся, что веб-пакет как-то справится?

2 ответа

Решение

Ответ скрыт в конфигурации CommonsChunkPlugin

new webpack.optimize.CommonsChunkPlugin({
  name: 'main', // Important to use 'main' or not specify, since 'main' is default
  children: true, // Look for common dependencies in all children,
  minChunks: 2, // How many times a dependency must come up before being extracted
});

children: true является основной частью этой конфигурации. Из документов:

Если это правда, все дочерние элементы общего блока выбраны


Редактировать для асинхронного общего блока

Если вы хотите загружать асинхронно общий код в чанк, вы должны изменить вышеуказанную конфигурацию с добавлением async: true

new webpack.optimize.CommonsChunkPlugin({
  name: 'main',
  children: true, 
  minChunks: 2, 
  async: true, // modification
});

Из документов о async:

Если это правда, новый асинхронный чанк общего ресурса создается как дочерний элемент options.name и одноуровневый элемент options.chunks. Загружается параллельно с options.chunks. Можно изменить имя выходного файла, указав нужную строку вместо true.

Теперь создан дополнительный блок, содержащий только socket.io-client из вашего примера. Это близко к оригинальному примеру в документах веб-пакета.

Пока я нашел одно возможное решение. Если вы используете веб-пакеты require.include() способ просто включить (не оценивать) "разделяемую библиотеку, здесь socket.io-client" также в родительский модуль, здесь app.js, CommonChunkPlugin теперь сможет правильно разобраться.

require.include( 'socket.io-client' ); // import io from 'socket.io-client'; also works
require.ensure([ 'module1.js' ], ( require ) => {
    // at some point
    require( 'module1.js' );
}, 'Module1');

require.ensure([ 'module2.js' ], ( require ) => {
    // at some point
    require( 'module2.js' );
}, 'Module2');

Тем не менее, это не кажется мне правильным, поскольку это ручное разрешение зависимостей, что на самом деле не то, что я хочу делать, используя что-то вроде Webpack.

Другие вопросы по тегам