Sinon: Сбой / необъяснимая блокировка экспорта ESM по умолчанию

Созданный на 2 мая 2020  ·  21Комментарии  ·  Источник: sinonjs/sinon

Опишите ошибку
Раньше комбинация import * as foo from 'someModule' + spy(foo, 'default') работала нормально (и даже была указана в проблемах этого ручным запуском .

Ожидаемое поведение
Sinon шпионит за экспортом по умолчанию.

Контекст (просьба заполнить следующую информацию):

  • Версия библиотеки: 9.0.2

Дополнительный контекст
Я предполагаю, что это сделано для того, чтобы избежать TypeError: Cannot assign to read only property

Однако это можно обойти, используя старую школу __defineGetter__

Самый полезный комментарий

@mroderick, если вам не нравятся комментарии, игнорируйте их. Активное удаление комментариев, которые могут помочь другим пользователям, совершенно бесполезно. Предположим, вы удалите комментарии, тогда у вас просто появятся похожие пользователи, которые будут приходить и комментировать снова и снова, что, в свою очередь, приведет к блокировке потока.

Изменить: вы также можете использовать очень удобную кнопку «отказаться от подписки». :)

Я сопровождаю этот проект и стараюсь читать все комментарии.

Я не могу игнорировать комментарии или отказаться от подписки на проблему, потому что люди решают не играть по изложенным правилам, игнорировать предлагаемые инструкции и использовать исходную проблему в своих целях. Я обязан стараться решать вопросы вежливо, тактично и эффективно. Проблемы с взломом делают поддержку сообщества труднее, чем должно быть.

Пожалуйста, помогите мне помочь вам и остальному сообществу.

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

На самом деле в этом старом выпуске нет упоминания о __defineGetter__ , только Object.defineProperty, и только для работы с транспилированными модулями Webpack, а не с фактическими модулями ECMAScript. Я не говорю, что это не работает 😄

Не могли бы вы опубликовать какой-нибудь простой пример javascript, в котором вы можете перезаписать (не по умолчанию) экспорт импортированного модуля ES? Для проверки вам нужны два файла some-module.mjs и file-that-overwrites.mjs и они должны иметь расширение .mjs для Node, чтобы включить синтаксис import .

Этот набор тестов документирует текущее поведение Sinon.

Заглушка FYI не работает для [email protected]+ здесь

@ fatso83, что старая проблема действительно не работает (но я не говорил, что это так 😜).

Я имею в виду, что Sinon выдает ошибку при обнаружении ESM, потому что позже код Object.defineProperty(object, property, methodDesc) завершится ошибкой с TypeError: Cannot assign to read only property 'default' . Однако __defineGetter__ не подведет:

object.__defineGetter__(property, methodDesc.value);

Буууут, когда я попытался изменить код Sinon и запустить его, я получил неопределенную ошибку в __defineGetter__ (возможно, строгий режим или что-то в этом роде?).

Поэтому я думаю, возможно, по-другому, например, воссоздать объект (с новыми значениями) вместо того, чтобы переопределить его свойства. Посложнее, но, по крайней мере, выполнимо.

Заглушка FYI не работает для [email protected]+ здесь

Та же проблема здесь, последняя рабочая версия 3.8.3

@zorji и @aelbore : пишете в этой теме. Если вы сообщаете о новой проблеме, создайте отдельную проблему и выполните обычные шаги для отчета (как проверить, фактический код, версии и т. Д.). Мы не поддерживаем Typescript и никогда не говорили об этом, хотя, конечно, он должен работать, но детали будут зависеть от вашего шага транспиляции.

Поэтому я думаю, возможно, по-другому, например, воссоздать объект (с новыми значениями) вместо того, чтобы переопределить его свойства. Посложнее, но, по крайней мере, выполнимо.

Это? Модуль ES - это статическая функция, которая привязана во время выполнения, AFAIK, и вы не можете ее изменить.

импортированные функции доступны в файле, это виды экспортированной функции только для чтения. Вы не можете изменить импортированную переменную, но вы все равно можете изменять свойства, аналогичные const. Кроме того, эти функции импортируются как живые привязки, что означает, что они могут меняться по значению, даже если вы не можете изменить привязку в отличие от const.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules

С нетерпением жду встречи с этим, но я был бы удивлен, если бы вы (или кто-то еще!) Это сделали.

Эта проблема была автоматически помечена как устаревшая, поскольку в последнее время не было активности. Он будет закрыт, если больше не будет активности. Спасибо за ваш вклад.

Плохой бот. Можно ли отключить эту дурацкую штуку?

@OmgImAlexis, как вы думаете, есть ли причина оставлять этот вопрос открытым?

Ребята, пожалуйста, постарайтесь не упускать из виду проблему и обсуждайте только то, что упомянуто в исходном сообщении.

Сопровождающим достаточно сложно тратить наше неоплачиваемое свободное время на поддержку бесплатного программного обеспечения, не обращаясь при этом к ортогональным темам в том же выпуске.

Мы рады, что Sinon (инструмент JavaScript) также может быть полезен в сообществе TypeScript. Однако, как сказал @ fatso83 , мы не поддерживаем Typescript .

Все дальнейшие не относящиеся к теме комментарии о TypeScript в этом выпуске будут удалены.

Все дальнейшие не относящиеся к теме комментарии о TypeScript в этом выпуске будут удалены.

@mroderick, если вам не нравятся комментарии, игнорируйте их. Активное удаление комментариев, которые могут помочь другим пользователям, совершенно бесполезно. Предположим, вы удалите комментарии, тогда у вас просто появятся похожие пользователи, которые будут приходить и комментировать снова и снова, что, в свою очередь, приведет к блокировке потока.

Изменить: вы также можете использовать очень удобную кнопку «отказаться от подписки». :)

Извините, я был очень занят на работе. Попробую посмотреть через пару недель. Несколько библиотек делают это, так что это должно быть возможно 😁

@mroderick, если вам не нравятся комментарии, игнорируйте их. Активное удаление комментариев, которые могут помочь другим пользователям, совершенно бесполезно. Предположим, вы удалите комментарии, тогда у вас просто появятся похожие пользователи, которые будут приходить и комментировать снова и снова, что, в свою очередь, приведет к блокировке потока.

Изменить: вы также можете использовать очень удобную кнопку «отказаться от подписки». :)

Я сопровождаю этот проект и стараюсь читать все комментарии.

Я не могу игнорировать комментарии или отказаться от подписки на проблему, потому что люди решают не играть по изложенным правилам, игнорировать предлагаемые инструкции и использовать исходную проблему в своих целях. Я обязан стараться решать вопросы вежливо, тактично и эффективно. Проблемы с взломом делают поддержку сообщества труднее, чем должно быть.

Пожалуйста, помогите мне помочь вам и остальному сообществу.

Эта проблема была автоматически помечена как устаревшая, поскольку в последнее время не было активности. Он будет закрыт, если больше не будет активности. Спасибо за ваш вклад.

Плохой бот.

@ jshado1, как вы думаете, этот вопрос должен оставаться открытым?

Я вижу, что @ jshado1 говорит, что раньше это работало нормально, но я не думаю, что это когда-либо работало в ванильном непереносимом javascript. Потому что не должно. Он может работать при транспиляции модулей с использованием Babel / Webpack или аналогичных, потому что вы только эмулируете модули, а не создаете объект только для чтения во время выполнения (какие модули есть). Предложение throw было добавлено мной, потому что в противном случае оно было бы выброшено немного позже, когда вы попытались изменить неизменяемое. Однако среды выполнения / загрузчики модулей, такие как esm немного изменяют это поле.

Если вы считаете, что поведение неправильное, я предлагаю просто отредактировать node_modules/sinon/lib/sinon/spy.js , удалить предложение throws и сообщить об этом. Без обид. Обещание: единорог:: радуга:

Процитировать @RyanCavanaugh (https://github.com/microsoft/TypeScript/issues/38568#issuecomment-628860591)

Если вы нацеливаетесь на commonjs но пишете импорт / экспорт модуля ES, TS все равно попытается дать вам поведение модуля ES.

Этот код фактически не является законным ES, поскольку он пытается изменить (косвенно через sinon.stub ) свойство только для чтения (свойства чего-то, импортированного с помощью import * as name , не изменяются). Это никогда не должно было сработать.

Это в основном то, что я сказал. В заключение, поскольку результаты этого полностью зависят от того, используете ли вы этап транспиляции, от того, как транспилятор выполняет этот этап и т. Д., Если он пытается создать результат, который несколько соответствует спецификации ESM, _ он не должен работать_ как экспорт модулей ES неизменяем (конечно, не фактические объекты, связанные этими экспортами).

@mroderick @ fatso83 извините, у меня не было этого свободного времени, и с тех пор меня гнали на работе. Прошло несколько месяцев, но если мне не изменяет память, тогда у меня был очень_ рудиментарный (и грязный AF) рабочий пример, чтобы убедиться, что он действительно работает (но на самом деле, вероятно, этого не должно было быть). НО, я думаю, что это не лучший способ сделать это, потому что: я считаю, что существует / будет официальный способ сделать это с помощью загрузчиков ems: https://github.com/nodejs/node/blob/master/doc/api/esm .md # загрузчики

В настоящее время они нестабильны (явно указано, что скоро они будут изменены), поэтому, вероятно, подождите, пока они не станут более стабильными. Но как только они это сделают, я думаю, это правильный путь.

Обновление: в настоящее время это обсуждается в nodejs / node # 36396.

Я думаю, что мое предложение в этом комментарии упростит это. Пользователь мог вручную предоставить карту, и загрузчик esm мог использовать ее для замены:

// const mocksMap = { 'serviceA.js': 'serviceA.mock.js' };

const mock = mocksMap[importPath]; // note: it's not called `importPath` in the loader hooks
if (mock) // …

и / или загрузчик esm может искать фиктивное совпадение на основе имени файла (быстрый и грязный пример):

const ext = path.ext(importPath);
const filename = path.basename(importPath, ext);
const mockFile = await import(`${filename}.mock${ext}`);

if (mockFile) // …

@ jshado1 Спасибо за ссылку. Связанная проблема, по сути, связана с попыткой найти стандартизированный способ решения проблемы подстановки зависимостей на уровне _ссылки_, который аналогичен тем, что делают такие инструменты, как rewire и proxyquire (которые мы описываем в этом руководстве на нашей домашней странице ) . В любом случае, это не то, что Sinon должна или будет решать, так как это выходит за рамки, и то, как решить эту проблему, будет полностью зависеть от вашей среды.

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