Sinon: A espionagem da exportação padrão do ESM falha / inexplicavelmente bloqueada

Criado em 2 mai. 2020  ·  21Comentários  ·  Fonte: sinonjs/sinon

Descreva o bug
Anteriormente, uma combinação de import * as foo from 'someModule' + spy(foo, 'default') funcionaria muito bem (e até foi listada nos problemas deste repo como a solução ); no entanto, agora isso é explicitamente bloqueado por um lance manual .

Comportamento esperado
Sinon para espionar a exportação padrão.

Contexto (preencha as seguintes informações):

  • Versão da biblioteca: 9.0.2

Contexto adicional
Presumo que seja para evitar TypeError: Cannot assign to read only property

No entanto, isso pode ser circunavegado usando o antigo skool __defineGetter__

Comentários muito úteis

@mroderick se não gostar dos comentários, ignore-os. Remover ativamente comentários que ajudariam outros usuários não ajuda em nada. Digamos que você remova os comentários e acabe com usuários semelhantes vindo e comentando repetidamente, o que, por sua vez, acabaria com o thread sendo bloqueado.

Editar: Você também pode usar o botão "cancelar inscrição" super fácil de encontrar. :)

Eu sou um mantenedor deste projeto e tento ler todos os comentários.

Não posso ignorar os comentários ou cancelar a inscrição de um problema porque as pessoas decidem não seguir as regras estabelecidas, ignorar a orientação oferecida e sequestrar o problema original para seus próprios fins. É minha responsabilidade tentar resolver os problemas de maneira educada, diplomática e eficiente. Os problemas de sequestro tornam mais difícil do que o necessário para dar suporte à comunidade.

Por favor me ajude a ajudar você e o resto da comunidade.

Todos 21 comentários

Na verdade, não há menção de __defineGetter__ naquele problema antigo, apenas Object.defineProperty, e apenas para lidar com módulos Webpack transpilados, não módulos ECMAScript reais. Não estou dizendo que não funciona, no entanto 😄

Você poderia postar algum exemplo simples de javascript onde você possa substituir as exportações (não padrão) de um Módulo ES importado? Você precisa de dois arquivos some-module.mjs e file-that-overwrites.mjs para testar isso e eles precisam ter a extensão .mjs para Nó para habilitar a sintaxe import .

Este conjunto de testes documenta o comportamento atual do Sinon.

O stub FYI não funciona para [email protected]+ aqui

@ fatso83 aquele velho problema de fato não (mas eu não disse que sim 😜).

O que quero dizer é que o Sinon gera um erro ao detectar um ESM porque mais tarde o código Object.defineProperty(object, property, methodDesc) falhará com TypeError: Cannot assign to read only property 'default' . No entanto, __defineGetter__ não falharia:

object.__defineGetter__(property, methodDesc.value);

Mas, quando tentei modificar o código Sinon e executá-lo, recebi um erro indefinido em __defineGetter__ (talvez um modo estrito ou algo assim?).

Portanto, estou pensando talvez de uma maneira diferente, como recriar o objeto (com novos valores) em vez de substituir suas propriedades. Mais complexo, mas pelo menos capaz de fazer.

O stub FYI não funciona para [email protected]+ aqui

Mesmo problema aqui na última versão de trabalho 3.8.3

@zorji e @aelbore : Não tenho ideia de por que você está postando neste tópico. Se você estiver relatando um novo problema, crie um problema separado e siga as etapas normais para relatar (como verificar, código real, versões etc.). Não oferecemos suporte ao Typescript e nunca dissemos isso, embora deva funcionar, é claro, mas os detalhes dependerão da sua etapa de transpilação.

Portanto, estou pensando talvez de uma maneira diferente, como recriar o objeto (com novos valores) em vez de substituir suas propriedades. Mais complexo, mas pelo menos capaz de fazer.

É isso? Um Módulo ES é um recurso estático vinculado ao tempo de execução, AFAIK, e você não pode modificá-lo.

os recursos importados estão disponíveis no arquivo, eles são visualizações somente leitura do recurso que foi exportado. Você não pode alterar a variável que foi importada, mas ainda pode modificar propriedades semelhantes a const. Além disso, esses recursos são importados como ligações ativas, o que significa que eles podem mudar de valor mesmo se você não puder modificar a ligação, ao contrário de const.

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

Estou ansioso para ver se você pode chegar a algum lugar com isso, mas ficaria surpreso se você (ou qualquer pessoa!) O fizesse.

Este problema foi marcado automaticamente como obsoleto porque não teve atividades recentes. Ele será fechado se nenhuma outra atividade ocorrer. Obrigado por suas contribuições.

Bot ruim. Essa coisa estúpida pode ser desligada?

@OmgImAlexis , você acha que há alguma razão para manter esse problema aberto?

Pessoal, por favor, tentem manter o problema no ponto e discutir apenas o que é mencionado na postagem original.

É bastante desafiador para os mantenedores gastar nosso tempo livre não remunerado apoiando software livre, sem também ter que navegar por tópicos ortogonais no mesmo problema.

Estamos muito satisfeitos que Sinon (uma ferramenta JavaScript) também possa ser útil na comunidade TypeScript. No entanto, como @ fatso83 disse, não oferecemos suporte para Typescript .

Quaisquer outros comentários fora do tópico sobre o TypeScript neste problema serão excluídos.

Quaisquer outros comentários fora do tópico sobre o TypeScript neste problema serão excluídos.

@mroderick se não gostar dos comentários, ignore-os. Remover ativamente comentários que ajudariam outros usuários não ajuda em nada. Digamos que você remova os comentários e acabe com usuários semelhantes vindo e comentando repetidamente, o que, por sua vez, acabaria com o thread sendo bloqueado.

Editar: Você também pode usar o botão "cancelar inscrição" super fácil de encontrar. :)

Desculpe, fiquei muito ocupado no trabalho. Vou tentar dar uma olhada em algumas semanas. Várias bibliotecas fazem isso, então deve ser possível 😁

@mroderick se não gostar dos comentários, ignore-os. Remover ativamente comentários que ajudariam outros usuários não ajuda em nada. Digamos que você remova os comentários e acabe com usuários semelhantes vindo e comentando repetidamente, o que, por sua vez, acabaria com o thread sendo bloqueado.

Editar: Você também pode usar o botão "cancelar inscrição" super fácil de encontrar. :)

Eu sou um mantenedor deste projeto e tento ler todos os comentários.

Não posso ignorar os comentários ou cancelar a inscrição de um problema porque as pessoas decidem não seguir as regras estabelecidas, ignorar a orientação oferecida e sequestrar o problema original para seus próprios fins. É minha responsabilidade tentar resolver os problemas de maneira educada, diplomática e eficiente. Os problemas de sequestro tornam mais difícil do que o necessário para dar suporte à comunidade.

Por favor me ajude a ajudar você e o resto da comunidade.

Este problema foi marcado automaticamente como obsoleto porque não teve atividades recentes. Ele será fechado se nenhuma outra atividade ocorrer. Obrigado por suas contribuições.

Bot ruim.

@ jshado1 você acha que esse problema deveria permanecer aberto?

Vejo que @ jshado1 diz que isso costumava funcionar bem, mas acho que nunca funcionou em javascript não transpilado vanilla. Porque não deveria. Ele pode funcionar ao transpilar módulos usando Babel / Webpack ou similar, porque você apenas emula módulos e não cria um objeto somente leitura no tempo de execução (quais são os módulos). A cláusula throw foi adicionada por mim, porque _contaria_ um pouco mais tarde, quando você tentasse alterar o imutável. No entanto, os tempos de execução / carregadores de módulo, como esm mudam um pouco o campo.

Se você acha que o comportamento está errado, sugiro apenas editar node_modules/sinon/lib/sinon/spy.js , remover a cláusula throws e relatar de volta. Sem ressentimentos. Promessa: unicórnio:: arco-íris:

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

Se você tiver como alvo commonjs mas gravando importações / exportações de módulo ES, o TS ainda tentará fornecer o comportamento do módulo ES.

Este código efetivamente não é ES legal, uma vez que está tentando modificar (indiretamente por meio de sinon.stub ) uma propriedade somente leitura (as propriedades de algo importado com import * as name não são mutáveis). Isso nunca deveria ter funcionado.

O que é basicamente o que venho dizendo. Então, fechando, como os resultados disso são inteiramente dependentes de você usar uma etapa de transpilação, como o transpiler faz essa etapa, etc. as exportações dos Módulos ES são imutáveis ​​(não os objetos reais vinculados por essas exportações, é claro).

@mroderick @ fatso83 desculpe, eu nunca tive essa folga e tenho sido criticado no trabalho desde então. Já se passaram vários meses, mas se não me falha a memória, eu tinha um exemplo de trabalho _muito_ rudimentar (e sujo) para confirmar que funcionou (mas na verdade _provavelmente_ não deveria ter funcionado). MAS, acho que não é esse o caminho a seguir, porque acredito que existe / será uma maneira oficial de fazer isso por meio de carregadores ems: https://github.com/nodejs/node/blob/master/doc/api/esm .md # loaders

Eles estão atualmente instáveis ​​(declarado explicitamente para serem alterados em breve), então provavelmente espere até que fiquem mais estáveis. Mas, uma vez que o façam, acho que esse é o caminho a percorrer.

Atualização: Isso está sendo discutido atualmente em nodejs / node # 36396.

Acho que minha proposta neste comentário tornaria isso muito simples. Um usuário poderia fornecer um mapa manualmente, e o carregador esm poderia usá-lo para substituir:

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

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

e / ou o carregador esm pode procurar uma correspondência simulada com base no nome do arquivo (exemplo rápido n sujo):

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

if (mockFile) // …

@ jshado1 Obrigado por fornecer esse link. O problema vinculado é essencialmente sobre tentar encontrar uma maneira padronizada de lidar com o problema de substituir dependências no _nível do link_, que é semelhante ao que ferramentas como rewire e proxyquire fazem (que descrevemos neste tutorial em nossa página inicial ) . Em qualquer caso, isso não é algo que a Sinon deve ou irá resolver, pois está fora do escopo e como resolvê-lo dependerá inteiramente do seu ambiente.

Esta página foi útil?
0 / 5 - 0 avaliações