Webpack модули отложенной загрузки из изоморфных компонентов (общий код между серверной и клиентской сторонами)

#javascript #node.js #webpack #babeljs

#javascript #node.js #webpack #babeljs

Вопрос:

Допустим, у меня есть сервер node express и приложение JavaScript на стороне клиента.

Оба используют одни и те же компоненты.

Javascript на стороне клиента поставляется через webpack.

Естественно, есть некоторые библиотеки, необходимые только на стороне клиента.

Проблема в том, как настроить webpack для ленивой загрузки этих модулей.

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

 await import( /* webpackChunkName: "tinymce" */ 'tinymce' );
  

Вместе с использованием chunkFilename: опции в директиве вывода webpacks это привело к загрузке модуля только по запросу.

К сожалению, это не работает при запуске кода с node, поскольку метод импорта недоступен.

Если я теперь использую эквивалент узла, требующий вызова внутри функции вместо этого:

 require( 'tinymce' );
  

Webpack включает в себя всю зависимость в точке входа и больше не разделяет фрагмент.

Как я могу использовать отложенную загрузку модулей при совместном использовании кодовой базы между сервером и клиентской стороной без необходимости переноса кода узла?

Комментарии:

1. medium.com/airbnb-engineering/…

2. @Dominic спасибо за комментарий, на самом деле это не решает проблему. Я имею в виду, что это может быть, но мне пришлось бы настроить второй шаг переноса для кода на стороне сервера, чтобы я мог использовать async imports вместо requires . В настоящее время я выполняю только перенос на клиентскую сторону, но оставляю код на стороне сервера нетронутым. Я мог бы решить сделать это, если я не могу сделать это иначе

3. импорт es6 не работает в узле за пределами файлов .mjs, вам нужно будет перенести. Или, возможно, переименуйте все ваши файлы в mjs и вместо этого обрабатывайте их в пользовательском интерфейсе (но обратите внимание, что многие облачные провайдеры поддерживают только узел 8 в стандартных средах).

Ответ №1:

Можно повторно использовать один и тот же код внутри узла и на стороне клиента без необходимости переноса кода на стороне сервера.

Он работает, используя require.ensure() вместо только require() :

 // Returns a promise that resolves with the Module
require.ensure( [], ( require ) => require( 'pikaday' ) )
  

Узел не будет жаловаться, и если вы определяете a chunkFilename в своей webpack.config.js output директиве, webpack успешно поместит модуль в свой собственный файл, который будет загружен при необходимости.

Я тестировал это только с модулями, которые мне нужны только на стороне клиента, и вызывал их условно, проверяя, является ли typeof document === 'object' as на самом деле require.ensure не стандартным методом, а специфичным для webpack. Так что, вероятно, это не сработает, если вам нужен модуль как на стороне клиента, так и на стороне сервера, хотя вы можете попробовать использовать полизаполнение для require.обеспечить для узла.