(Webpack) Как разделять зависимости динамического модуля
Я просто понял, что если вы загружаете модули динамически с помощью require.ensure()
, webpack не будет анализировать и блокировать зависимости вместе. Это имеет смысл в некотором роде, что можно утверждать, что веб-пакет не может знать, когда такие модули будут переданы, но можем ли мы заставить 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' ),
Не работает. Конечно, я всегда мог "разрешить" эту зависимость вручную, но я надеялся, что веб-пакет каким-то образом может сделать трюк?
Ответы
Ответ 1
Ответ скрыт в конфигурации 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
является основной частью этой конфигурации.
Из документов:
Если выбрано значение true для всех дочерних элементов пакета commons
Редактировать для общей строки aync
Если вы хотите загрузить асинхронно общий код в куске, вы должны изменить выше конфигурацию с добавлением async: true
new webpack.optimize.CommonsChunkPlugin({
name: 'main',
children: true,
minChunks: 2,
async: true, // modification
});
Из документов о async
:
Если true, новый кусок async commons создается как дочерний элемент options.name и братьев из вариантов. Он загружается параллельно с options.chunks. Можно изменить имя выходного файла путем предоставления нужной строки вместо true.
Теперь в вашем примере создается дополнительный кусок, содержащий только socket.io-client
.
Это близко к оригинальному примеру в веб-документах.
Ответ 2
До сих пор я нашел одно возможное решение.
Если вы используете метод require.include()
для webpack, чтобы просто включить (не оценивать) "общую библиотеку, здесь 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.