Sinon: El espionaje de la exportación predeterminada de ESM falla / se bloquea inexplicablemente

Creado en 2 may. 2020  ·  21Comentarios  ·  Fuente: sinonjs/sinon

Describe el error
Anteriormente, una combinación de import * as foo from 'someModule' + spy(foo, 'default') funcionaría bien (e incluso se incluyó en los problemas de este lanzamiento manual .

Comportamiento esperado
Sinon para espiar la exportación predeterminada.

Contexto (complete la siguiente información):

  • Versión de la biblioteca: 9.0.2

Contexto adicional
Supongo que esto es para evitar TypeError: Cannot assign to read only property

Sin embargo, esto se puede circunnavegar usando el skool antiguo __defineGetter__

Comentario más útil

@mroderick si no le gustan los comentarios,

Editar: también puede utilizar el botón "cancelar suscripción", que es muy fácil de encontrar. :)

Soy un mantenedor de este proyecto e intento leer todos los comentarios.

No puedo ignorar los comentarios o darme de baja de un problema porque las personas deciden no seguir las reglas establecidas, ignorar la orientación ofrecida y secuestrar el problema original para sus propios fines. Es mi responsabilidad tratar de resolver los problemas de manera educada, discreta y eficiente. Los problemas de secuestro hacen que sea más difícil de lo necesario apoyar a la comunidad.

Ayúdame a ayudarte a ti y al resto de la comunidad.

Todos 21 comentarios

En realidad, no se menciona __defineGetter__ en ese problema anterior, solo Object.defineProperty, y luego solo para tratar los módulos Webpack transpilados, no los módulos ECMAScript reales. Sin embargo, no digo que no funcione 😄

¿Podría publicar algún ejemplo simple de JavaScript vanilla en el que pueda sobrescribir las exportaciones (no predeterminadas) de un módulo ES importado? Necesita dos archivos some-module.mjs y file-that-overwrites.mjs para probar esto y necesitan tener la extensión .mjs para Node para habilitar la sintaxis import .

Este conjunto de pruebas documenta el comportamiento actual de Sinon.

FYI stub no funciona para [email protected]+ aquí

@ fatso83 ese viejo problema de hecho no lo hace (pero no dije que sí 😜).

Lo que quiero decir es que Sinon arroja un error al detectar un ESM porque luego el código Object.defineProperty(object, property, methodDesc) fallará con TypeError: Cannot assign to read only property 'default' . Sin embargo, __defineGetter__ no fallaría:

object.__defineGetter__(property, methodDesc.value);

Pero, cuando intenté modificar el código Sinon y ejecutarlo, obtuve un error indefinido en __defineGetter__ (¿quizás un modo estricto o algo así?).

Entonces, estoy pensando quizás de una manera diferente, como volver a crear el objeto (con nuevos valores) en lugar de anular sus propiedades. Más complejo, pero al menos factible.

FYI stub no funciona para [email protected]+ aquí

El mismo problema aquí última versión de trabajo 3.8.3

@zorji y @aelbore : No tengo idea de por qué publican en este hilo. Si está informando un nuevo problema, cree un problema por separado y siga los pasos normales para informar (cómo verificar, código real, versiones, etc.). No admitimos Typecript y nunca lo hemos dicho, aunque debería funcionar, por supuesto, pero los detalles dependerán de su paso de transpilación.

Entonces, estoy pensando quizás de una manera diferente, como volver a crear el objeto (con nuevos valores) en lugar de anular sus propiedades. Más complejo, pero al menos factible.

¿Lo es? Un módulo ES es una función estática que está vinculada en tiempo de ejecución, AFAIK, y no se puede modificar.

las características importadas están disponibles en el archivo, son vistas de solo lectura de la característica que se exportó. No puede cambiar la variable que se importó, pero aún puede modificar propiedades similares a const. Además, estas características se importan como enlaces activos, lo que significa que pueden cambiar de valor incluso si no puede modificar el enlace a diferencia de const.

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

Espero ver si puedes llegar a algún lado con esto, pero me sorprendería si tú (¡o cualquiera!) Lo hicieras.

Este problema se ha marcado automáticamente como obsoleto porque no ha tenido actividad reciente. Se cerrará si no se produce más actividad. Gracias por sus aportaciones.

Mal bot. ¿Se puede apagar esta estúpida cosa?

@OmgImAlexis , ¿crees que hay alguna razón para mantener abierto este problema?

Amigos, intenten mantener el problema en el punto y solo discutan lo que se menciona en la publicación original.

Es lo suficientemente desafiante para los mantenedores dedicar nuestro tiempo libre no remunerado a respaldar software gratuito, sin tener que navegar también por temas ortogonales en el mismo problema.

Estamos encantados de que Sinon (una herramienta de JavaScript) también pueda ser útil en la comunidad de TypeScript. Sin embargo, como dijo @ fatso83 , no admitimos Typecript .

Se eliminarán otros comentarios fuera del tema sobre TypeScript en este número.

Se eliminarán otros comentarios fuera del tema sobre TypeScript en este número.

@mroderick si no le gustan los comentarios,

Editar: también puede utilizar el botón "cancelar suscripción", que es muy fácil de encontrar. :)

Ack lo siento, estaba muy ocupado en el trabajo. Intentaré echarle un vistazo en un par de semanas. Varias bibliotecas logran esto, por lo que debe ser posible 😁

@mroderick si no le gustan los comentarios,

Editar: también puede utilizar el botón "cancelar suscripción", que es muy fácil de encontrar. :)

Soy un mantenedor de este proyecto e intento leer todos los comentarios.

No puedo ignorar los comentarios o darme de baja de un problema porque las personas deciden no seguir las reglas establecidas, ignorar la orientación ofrecida y secuestrar el problema original para sus propios fines. Es mi responsabilidad tratar de resolver los problemas de manera educada, discreta y eficiente. Los problemas de secuestro hacen que sea más difícil de lo necesario apoyar a la comunidad.

Ayúdame a ayudarte a ti y al resto de la comunidad.

Este problema se ha marcado automáticamente como obsoleto porque no ha tenido actividad reciente. Se cerrará si no se produce más actividad. Gracias por sus aportaciones.

Mal bot.

@ jshado1 ¿cree que este problema debería permanecer abierto?

Veo que @ jshado1 dice que esto solía funcionar bien, pero no creo que esto haya funcionado nunca en JavaScript sin transpilar vainilla. Porque no debería. Puede funcionar al transpilar módulos usando Babel / Webpack o similar, porque solo emula módulos y no crea realmente un objeto de solo lectura en el tiempo de ejecución (qué módulos son). La cláusula de lanzamiento fue agregada por mí, porque _de lo contrario, arrojaría_ un poco más tarde cuando intentaste cambiar el invariable. Sin embargo, los tiempos de ejecución / cargadores de módulos como esm cambian un poco el campo.

Si cree que el comportamiento es incorrecto, le sugiero que simplemente edite node_modules/sinon/lib/sinon/spy.js , elimine la cláusula throws e informe. Sin resentimientos. Promesa: unicornio: arcoiris:

Para citar a @RyanCavanaugh (https://github.com/microsoft/TypeScript/issues/38568#issuecomment-628860591)

Si tiene como objetivo commonjs pero escribe importaciones / exportaciones de módulos ES, TS todavía intentará darle el comportamiento del módulo ES.

Este código efectivamente no es ES legal, ya que está intentando modificar (indirectamente a través de sinon.stub ) una propiedad de solo lectura (las propiedades de algo importado con import * as name no son mutables). Nunca debería haber funcionado.

Que es básicamente lo que he estado diciendo. Por lo tanto, cerrando, ya que los resultados de esto dependen completamente de que use un paso de transpilación, cómo el transpilador hace ese paso, etc. las exportaciones de los módulos ES son inmutables (no los objetos reales vinculados por esas exportaciones, por supuesto).

@mroderick @ fatso83 lo siento, nunca tuve ese tiempo libre y me han golpeado en el trabajo desde entonces. Han pasado varios meses, pero si la memoria no me falla, tuve un ejemplo de trabajo _muy_ rudimentario (y sucio AF) en ese entonces para confirmar que funcionó (pero de hecho _probablemente_ no debería haberlo hecho). PERO, creo que ese no es el camino a seguir porque creo que hay / habrá una forma oficial de hacer esto a través de los cargadores de ems: https://github.com/nodejs/node/blob/master/doc/api/esm .md # cargadores

Estos son actualmente inestables (se indica explícitamente que se cambiarán pronto), por lo que probablemente espere hasta que se vuelvan más estables. Pero una vez que lo hagan, creo que ese es el camino a seguir.

Actualización: esto se está discutiendo actualmente en nodejs / node # 36396.

Creo que mi propuesta en este comentario lo haría muy simple. Un usuario podría proporcionar manualmente un mapa, y el cargador de esm podría usarlo para sustituir:

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

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

y / o, el cargador de esm podría buscar una coincidencia simulada basada en el nombre del archivo (ejemplo rápido y sucio):

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

if (mockFile) // …

@ jshado1 Gracias por proporcionar ese enlace. El problema vinculado se trata esencialmente de tratar de encontrar una forma estandarizada de manejar el problema de la sustitución de dependencias en el _nivel de enlace_, que es similar a lo que hacen las herramientas como rewire y proxyquire (que describimos en este tutorial en nuestra página de inicio ) . En cualquier caso, esto no es algo que Sinon deba o vaya a resolver, ya que está fuera de alcance y la forma de resolverlo dependerá por completo de su entorno.

¿Fue útil esta página
0 / 5 - 0 calificaciones