Underscore: WebPack неправильно эмулирует требование ('подчеркивание')

Созданный на 25 мая 2020  ·  9Комментарии  ·  Источник: jashkenas/underscore

Сегодня я обновился с 1.9.2 до 1.10.2, и для меня миксины больше не работают при использовании require('underscore');

Это не удается с TypeError: _.camelcase is not a function :

const _ = require('underscore');
const underscoreString = require('underscore.string');

_.mixin(underscoreString.exports());

console.log(_.camelcase('foo-bar'));

но это работает:

import _ from 'underscore';
const underscoreString = require('underscore.string');

_.mixin(underscoreString.exports());

console.log(_.camelcase('foo-bar'));

Все 9 Комментарий

Сожалею, что это тебя кусает, @dmaicher. Однако я не могу воспроизвести это с помощью Underscore 1.10.2 и underscore.string 3.3.5. Есть ли что-нибудь особенное в вашей настройке?

Спасибо за быстрый ответ: blush:

Я использую [email protected] и проблема возникает из-за кода, связанного с браузером. Когда я запускаю код с узлом в интерфейсе командной строки, все в порядке: confused:

Вот минимальный репродуктор: https://github.com/dmaicher/underscore_issue_2852

Вот твоя проблема:

https://github.com/dmaicher/underscore_issue_2852/blob/348eef226ec7392b2ced2b92ddf2fcba2517ab5c/public/build/app.js#L13

Этот путь импорта, underscore/modules/index-all.js , должен быть получен WebPack из поля module в нашем package.json :

https://github.com/jashkenas/underscore/blob/5d8ab5e37c9724f6f1181c5f95d0020815e4cb77/package.json#L17 -L18

тогда как поле main - это то, что нужно было использовать, учитывая, что вы используете импорт CommonJS. module - для импорта ES в инструментах, которые его поддерживают, main - для всех остальных. Это объясняет, почему ваш код работает с import но не с require() .

По-видимому, в настоящее время WebPack по умолчанию принимает модули ES, но имеет запасной вариант для импорта CommonJS. Думаю, вам придется как-то настроить его, чтобы не использовать модули ES или игнорировать поле module . Или, может быть, вы захотите перейти на модули ES.

Я закрываю это сейчас, потому что это проблема WebPack, а не проблема Underscore. Тем не менее, не стесняйтесь продолжать комментировать.

@jgonggrijp спасибо за проверку: +1:

Я смог исправить это, добавив псевдоним для разрешения в конфигурации веб-пакета:
'underscore': 'underscore/underscore.js',

Но мне это кажется немного странным. Многие другие пакеты, которые я использую, указывают "main" и "module" внутри своих package.json и для них это работает нормально.

Webpack берет первое найденное поле в порядке ['browser', 'module', 'main']
См. Https://webpack.js.org/configuration/resolve/#resolvemainfields.

Мне любопытно, почему он не работает только для подчеркивания, но, похоже, работает для других пакетов: blush:

Если вы назовете эти другие пакеты, я буду рад взглянуть. В любом случае, module и main не должны быть взаимозаменяемыми, поэтому WebPack рассматривает их как таковые неоправданно:

https://github.com/rollup/rollup/wiki/pkg.module

Документация, с которой вы связались, намекает на, возможно, немного менее уродливое решение, которое заключается в установке resolve.mainFields на ['main'] . Опять же, я считаю, что WebPack в первую очередь не должен рассматривать module , поскольку вы используете импорт CommonJS.

На всякий случай вот несколько пакетов, которые я использую, в которых есть как module и main :

https://www.npmjs.com/package/vuejs-datepicker
https://www.npmjs.com/package/bootstrap-vue
https://www.npmjs.com/package/acorn
https://www.npmjs.com/package/perfect-scrollbar

Связанная проблема с веб-пакетом: https://github.com/webpack/webpack/issues/5756

Да, это твоя проблема. Хотя также, похоже, что-то не так с тем, как WebPack эмулирует CommonJS при разрешении на module . Похоже, что он делает что-то вроде этого:

// converting modules/index-all.js to ES3
var underscoreESModule = {
    'default': _,
    map: _.map,
    filter: _.filter,
    // ...
};
// in your code that imports underscore
var _ = underscoreESModule;

Последняя строка имела бы смысл, если бы вы делали это:

import * as _ from 'underscore';

но то, что вы на самом деле делаете, эквивалентно этому:

import _ from 'underscore';

и правильный способ перевести это на ES3 в WebPack будет следующим:

var _ = underscoreESModule['default'];

Это как раз та проблема, с которой сталкиваются другие люди в webpack / webpack # 5756.

Другие инструменты сборки, такие как Browserify и Rollup, справляются с этим более разумно. Просто говорю...

Была ли эта страница полезной?
0 / 5 - 0 рейтинги