Webpack 5 не может импортировать модуль UMD

Недавно я обновился до Webpack 5, и у меня возникли проблемы с импортом модулей UMD.

В частности, я пытаюсь импортировать Leaflet. Leaflet, кажется, экспортирует модуль UMD, созданный rollup.js, который выглядит так:

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (factory((global.L = {})));
}(this, (function (exports) { 'use strict';
  [...]
})));

Как видите, он сначала пытается использовать CommonJS (если определены exports и module), затем пытается использовать AMD (если определено define), а в противном случае пытается поместить себя в глобальную область видимости, ссылаясь на this из модуля. контекст.

Webpack (без всяких загрузчиков) компилирует вот так:

(function (global, factory) {
  typeof exports === 'object' && "object" !== 'undefined' ? factory(exports) :
  typeof define === 'function' && __webpack_require__.amdO ? define(['exports'], factory) :
  (factory((global.L = {})));
}(undefined, (function (exports) { 'use strict';
  [...]
})));

Конкретно, что было сделано:

  • Замените typeof module на "object"
  • Замените define.amd на __webpack_require__.amd0
  • Замените this на undefined

Во время сборки webpack выдает мне предупреждение: export 'default' (imported as 'L') was not found in 'leaflet' (possible exports: ). Когда я открываю скомпилированный пакет в браузере, я получаю сообщение об ошибке Uncaught TypeError: Cannot set property 'L' of undefined.

Что происходит, так это то, что CommonJS терпит неудачу (потому что exports не определен), AMD терпит неудачу (потому что define не определен) и, наконец, установка глобального значения также не выполняется, потому что this заменяется на undefined.

Согласно документации Webpack, Webpack должен повсеместно поддерживать импорт модулей CommonJS и AMD, но, похоже, в данном случае ни один из них не работает.

Что я могу сделать, чтобы исправить это?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
2 270
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я сузил проблему и обнаружил, что проблема была вызвана тем, что я использовал imports-loader определенным образом.

Перед обновлением я использовал imports-loader, чтобы добавить все необходимые транзитивные зависимости, которые мои зависимости не импортировали, в частности файлы CSS. Конфигурация выглядела примерно так:

{ module: { rules: [ {
    test: //node_modules/leaflet/.*\.js$/,
    loader: "imports-loader?asdf=leaflet/dist/leaflet.css"
} ] } }

После обновления webpack больше не принимал строковый синтаксис для загрузчиков, и imports-loader также изменил свой синтаксис, поэтому я изменил его на:

{ module: { rules: [ {
    test: //node_modules/leaflet/.*\.js$/,
    loader: "imports-loader",
    options: {
        imports: "default leaflet/dist/leaflet.css asdf"
    }
} ] } }

Это, казалось, сделало работу и правильно включило необходимый файл CSS. Однако, когда я обнаружил, что эта часть конфига является причиной проблемы, я углубился в документацию imports-loader. Оказывается, конфигурация, которую я использовал, теперь генерировала следующую строку кода:

import asdf from "leaflet/dist/leaflet.css";

(и я мог бы использовать "side-effects leaflet/dist/leaflet.css", чтобы получить тот же результат, не используя asdf в качестве фиктивного имени импорта). Хотя это правильно импортировало файл CSS, это, вероятно, заставило веб-пакет думать, что этот файл является правильным модулем ES, отключив поддержку модулей CommonJS/AMD/UMD. Я изменил конфигурацию imports-loader на следующее:

{ module: { rules: [ {
    test: //node_modules/leaflet/.*\.js$/,
    loader: "imports-loader",
    options: {
        imports: "pure leaflet/dist/leaflet.css",
        type: "commonjs"
    }
} ] } }

Согласно документам, это создает следующую строку кода:

require("leaflet/dist/leaflet.css");

После внесения этого изменения, кажется, работает без проблем.

Интересно, что кажется, что webpack фактически обнаруживает весь блок UMD, а не просто предоставляет переменные exports и define, поэтому теперь он компилирует код Leaflet в это:

(function (global, factory) {
   true ? factory(exports) :
  0;
}(this, (function (exports) { 'use strict';
   [...]
})));

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