Sinon: Das Ausspionieren des ESM-Standardexports schlägt fehl/unerklärlicherweise blockiert

Erstellt am 2. Mai 2020  ·  21Kommentare  ·  Quelle: sinonjs/sinon

Beschreibe den Fehler
Zuvor funktionierte eine Kombination von import * as foo from 'someModule' + spy(foo, 'default') problemlos (und wurde sogar in den Problemen dieses manuellen Wurf blockiert.

Erwartetes Verhalten
Sinon, um den Standardexport auszuspionieren.

Kontext (bitte füllen Sie die folgenden Informationen aus):

  • Bibliotheksversion: 9.0.2

Zusätzlicher Kontext
Ich nehme an, dies ist, um TypeError: Cannot assign to read only property zu vermeiden

Dies kann jedoch mit der alten Schule __defineGetter__ umgangen werden

Hilfreichster Kommentar

@mroderick, wenn dir die Kommentare nicht gefallen, ignoriere sie. Das aktive Entfernen von Kommentaren, die anderen Benutzern helfen würden, ist überhaupt nicht hilfreich. Nehmen wir an, Sie entfernen die Kommentare, dann werden Sie immer wieder von ähnlichen Benutzern kommen und kommentieren, was wiederum dazu führen würde, dass der Thread gesperrt wird.

Bearbeiten: Sie können auch den super einfach zu findenden "Abmelden"-Button verwenden. :)

Ich bin ein Betreuer dieses Projekts und versuche, alle Kommentare zu lesen.

Ich kann Kommentare nicht ignorieren oder mich von einer Ausgabe abmelden, weil die Leute beschließen, nicht nach den festgelegten Regeln zu spielen, die angebotenen Anleitungen zu ignorieren und die ursprüngliche Ausgabe für ihre eigenen Zwecke zu kapern. Es liegt in meiner Verantwortung, Probleme höflich, taktvoll und effizient zu lösen. Hijacking-Probleme machen es schwieriger als nötig, die Community zu unterstützen.

Bitte helfen Sie mir, Ihnen und dem Rest der Community zu helfen.

Alle 21 Kommentare

Es gibt tatsächlich keine Erwähnung von __defineGetter__ in dieser alten Ausgabe, nur Object.defineProperty, und dann nur, um mit transpilierten Webpack-Modulen umzugehen, nicht mit tatsächlichen ECMAScript-Modulen. Aber ich sage nicht, dass es nicht funktioniert

Könnten Sie ein einfaches Vanille-Javascript-Beispiel posten, in dem Sie die (nicht standardmäßigen) Exporte eines importierten ES-Moduls überschreiben können? Sie benötigen zwei Dateien some-module.mjs und file-that-overwrites.mjs , um dies zu testen, und sie müssen die .mjs Erweiterung für Node haben, um die import Syntax zu aktivieren.

Diese Testsuite dokumentiert das aktuelle Verhalten von Sinon.

FYI-Stub funktioniert nicht für [email protected]+ hier

@fatso83 das alte Problem tut es tatsächlich nicht (aber ich habe es nicht gesagt 😜).

Was ich meine ist, Sinon gibt einen Fehler aus, wenn ein ESM erkannt wird, weil später der Code Object.defineProperty(object, property, methodDesc) mit TypeError: Cannot assign to read only property 'default' fehlschlägt. __defineGetter__ würde jedoch nicht fehlschlagen:

object.__defineGetter__(property, methodDesc.value);

Buuuut, als ich versuchte, den Sinon-Code zu ändern und auszuführen, bekam ich einen undefinierten Fehler bei __defineGetter__ (vielleicht ein strikter Modus oder so?).

Ich denke also vielleicht einen anderen Weg, z. B. das Objekt (mit neuen Werten) neu zu erstellen, anstatt seine Eigenschaften zu überschreiben. Komplexer, aber dann zumindest machbar.

FYI-Stub funktioniert nicht für [email protected]+ hier

Gleiches Problem hier letzte funktionierende Version 3.8.3

@zorji und @aelbore : Ich habe keine Ahnung, warum du in diesem Thread Wir unterstützen Typescript nicht und haben dies auch nie gesagt, obwohl es natürlich funktionieren sollte, aber die Details hängen von Ihrem Transpilationsschritt ab.

Ich denke also vielleicht einen anderen Weg, z. B. das Objekt (mit neuen Werten) neu zu erstellen, anstatt seine Eigenschaften zu überschreiben. Komplexer, aber dann zumindest machbar.

Ist es? Ein ES-Modul ist ein statisches Feature, das zur Laufzeit, AFAIK, gebunden ist und nicht geändert werden kann.

importierte Features in der Datei verfügbar sind, handelt es sich um schreibgeschützte Ansichten des exportierten Features. Sie können die importierte Variable nicht ändern, aber Sie können dennoch Eigenschaften ähnlich wie const ändern. Darüber hinaus werden diese Features als Live-Bindungen importiert, d. h. ihr Wert kann sich ändern, auch wenn Sie die Bindung im Gegensatz zu const nicht ändern können.

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

Ich freue mich darauf zu sehen, ob Sie damit etwas erreichen können, aber ich wäre überrascht, wenn Sie (oder jemand!)

Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivität hatte. Es wird geschlossen, wenn keine weitere Aktivität stattfindet. Vielen Dank für Ihre Beiträge.

Schlechter Bot. Kann man dieses blöde Ding abschalten?

@OmgImAlexis Glaubst du, es gibt einen Grund, dieses Problem offen zu halten?

Leute, bitte versucht, das Thema auf den Punkt zu bringen und nur das zu diskutieren, was im ursprünglichen Beitrag erwähnt wurde.

Für die Betreuer ist es schon eine Herausforderung genug, unsere unbezahlte Freizeit damit zu verbringen, freie Software zu unterstützen, ohne sich gleichzeitig durch orthogonale Themen in derselben Ausgabe bewegen zu müssen.

Wir freuen uns, dass Sinon (ein JavaScript-Tool) auch in der TypeScript-Community nützlich sein kann. Wie @fatso83 sagte, unterstützen wir jedoch kein Typescript .

Alle weiteren nicht zum Thema gehörenden Kommentare zu TypeScript in dieser Ausgabe werden gelöscht.

Alle weiteren nicht zum Thema gehörenden Kommentare zu TypeScript in dieser Ausgabe werden gelöscht.

@mroderick, wenn dir die Kommentare nicht gefallen, ignoriere sie. Das aktive Entfernen von Kommentaren, die anderen Benutzern helfen würden, ist überhaupt nicht hilfreich. Nehmen wir an, Sie entfernen die Kommentare, dann werden Sie immer wieder von ähnlichen Benutzern kommen und kommentieren, was wiederum dazu führen würde, dass der Thread gesperrt wird.

Bearbeiten: Sie können auch den super einfach zu findenden "Abmelden"-Button verwenden. :)

Entschuldigung, ich war sehr beschäftigt bei der Arbeit. Ich versuche in ein paar Wochen mal reinzuschauen. Das schaffen mehrere Bibliotheken, also muss es möglich sein

@mroderick, wenn dir die Kommentare nicht gefallen, ignoriere sie. Das aktive Entfernen von Kommentaren, die anderen Benutzern helfen würden, ist überhaupt nicht hilfreich. Nehmen wir an, Sie entfernen die Kommentare, dann werden Sie immer wieder von ähnlichen Benutzern kommen und kommentieren, was wiederum dazu führen würde, dass der Thread gesperrt wird.

Bearbeiten: Sie können auch den super einfach zu findenden "Abmelden"-Button verwenden. :)

Ich bin ein Betreuer dieses Projekts und versuche, alle Kommentare zu lesen.

Ich kann Kommentare nicht ignorieren oder mich von einer Ausgabe abmelden, weil die Leute beschließen, nicht nach den festgelegten Regeln zu spielen, die angebotenen Anleitungen zu ignorieren und die ursprüngliche Ausgabe für ihre eigenen Zwecke zu kapern. Es liegt in meiner Verantwortung, Probleme höflich, taktvoll und effizient zu lösen. Hijacking-Probleme machen es schwieriger als nötig, die Community zu unterstützen.

Bitte helfen Sie mir, Ihnen und dem Rest der Community zu helfen.

Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivität hatte. Es wird geschlossen, wenn keine weitere Aktivität stattfindet. Vielen Dank für Ihre Beiträge.

Schlechter Bot.

@jshado1 meinst du, dieses Problem sollte offen bleiben?

Ich sehe, dass @jshado1 sagt, dass dies früher gut funktioniert hat, aber ich glaube nicht, dass dies jemals in nicht transpiliertem Javascript funktioniert hat. Weil es nicht sollte. Es kann beim Transpilieren von Modulen mit Babel/Webpack oder ähnlichem funktionieren, da Sie nur Module emulieren und in der Laufzeit kein schreibgeschütztes Objekt erstellen (welche Module sind es). Die Throw-Klausel wurde von mir hinzugefügt, weil sie etwas später _sonst Throw_ würde, wenn Sie versuchten, das Unveränderliche zu ändern. Laufzeit-/Modullader wie esm ändern das Feld jedoch ein wenig.

Wenn Sie der Meinung sind, dass das Verhalten falsch ist, schlage ich vor, einfach node_modules/sinon/lib/sinon/spy.js bearbeiten, die throws-Klausel zu entfernen und Bericht zu erstatten. Keine harten Gefühle. Versprechen :Einhorn: :Regenbogen:

Um @RyanCavanaugh zu zitieren (https://github.com/microsoft/TypeScript/issues/38568#issuecomment-628860591)

Wenn Sie auf commonjs abzielen, aber ES-Modul-Importe/-Exporte schreiben, wird TS trotzdem versuchen, Ihnen das ES-Modul-Verhalten zu geben.

Dieser Code ist effektiv kein legales ES, da er versucht (indirekt über sinon.stub ) eine schreibgeschützte Eigenschaft zu ändern (die Eigenschaften von etwas, das mit import * as name importiert wurde, sind nicht veränderbar). Es hätte nie funktionieren dürfen.

Was ich im Grunde gesagt habe. Zum Schluss also, da die Ergebnisse davon völlig davon abhängen, ob Sie einen Transpilationsschritt verwenden, wie der Transpiler diesen Schritt durchführt usw. Wenn er versucht, ein Ergebnis zu erzielen, das in gewisser Weise der ESM-Spezifikation entspricht, _sollte es nicht funktionieren_ wie die Exporte der ES-Module sind unveränderlich (natürlich nicht die tatsächlichen Objekte, die an diese Exporte gebunden sind).

@mroderick @fatso83 Entschuldigung, ich hatte diese Zeit nie frei und wurde seitdem bei der Arbeit zugeschlagen. Es ist mehrere Monate her, aber wenn die Erinnerung reicht, hatte ich damals ein _sehr_ rudimentäres (und schmutziges AF) Arbeitsbeispiel, um zu bestätigen, dass es funktioniert hat (aber tatsächlich _wahrscheinlich_ nicht hätte sein sollen). ABER, ich denke, das ist nicht der richtige Weg, denn ich glaube, es gibt / wird einen offiziellen Weg geben, dies über ems-Loader zu tun: https://github.com/nodejs/node/blob/master/doc/api/esm .md#loader

Diese sind derzeit instabil (wird ausdrücklich angegeben, dass sie bald geändert werden), also warten Sie wahrscheinlich, bis sie stabiler werden. Aber sobald sie es tun, denke ich, dass das der richtige Weg ist.

Update: Dies wird derzeit in nodejs/node#36396 diskutiert.

Ich denke, mein Vorschlag in diesem Kommentar würde dies sehr einfach machen. Ein Benutzer könnte manuell eine Karte bereitstellen, und der esm-Loader könnte diese verwenden, um Folgendes zu ersetzen:

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

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

und/oder der esm-Loader könnte basierend auf dem Dateinamen nach einer Scheinübereinstimmung suchen (schnelles und schmutziges Beispiel):

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

if (mockFile) // …

@jshado1 Danke für die Bereitstellung dieses Links. Bei dem verlinkten Problem geht es im Wesentlichen darum, einen standardisierten Weg zu finden, um das Problem des Ersetzens von Abhängigkeiten auf der _Link-Ebene_ zu ersetzen, ähnlich wie bei Tools wie Rewire und Proxyquire (die wir in dieser Anleitung auf unserer Homepage beschreiben ). . In jedem Fall sollte oder wird Sinon dies nicht lösen, da es außerhalb des Anwendungsbereichs liegt und die Lösung vollständig von Ihrer Umgebung abhängt.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

OscarF picture OscarF  ·  4Kommentare

brettz9 picture brettz9  ·  3Kommentare

fearphage picture fearphage  ·  4Kommentare

JakobJingleheimer picture JakobJingleheimer  ·  3Kommentare

NathanHazout picture NathanHazout  ·  3Kommentare