Sinon: Memata-matai ekspor default ESM gagal/diblokir secara misterius

Dibuat pada 2 Mei 2020  ·  21Komentar  ·  Sumber: sinonjs/sinon

Jelaskan bugnya
Sebelumnya, kombinasi import * as foo from 'someModule' + spy(foo, 'default') akan berfungsi dengan baik (dan bahkan terdaftar dalam masalah repo ini sebagai solusinya ); namun, sekarang ini secara eksplisit diblokir oleh lemparan manual .

Perilaku yang diharapkan
Sinon untuk memata-matai ekspor default.

Konteks (harap lengkapi informasi berikut):

  • Versi perpustakaan: 9.0.2

konteks tambahan
Saya kira ini untuk menghindari TypeError: Cannot assign to read only property

Namun, ini dapat diatasi dengan menggunakan old skool __defineGetter__

Komentar yang paling membantu

@mroderick jika Anda tidak menyukai komentarnya, abaikan saja. Menghapus komentar secara aktif yang akan membantu pengguna lain tidak membantu sama sekali. Katakanlah Anda menghapus komentar maka Anda hanya akan berakhir dengan pengguna serupa datang dan berkomentar lagi dan lagi yang pada gilirannya akan berakhir dengan utas dikunci.

Sunting: Anda juga dapat menggunakan tombol "berhenti berlangganan" yang sangat mudah ditemukan. :)

Saya pengelola proyek ini, dan mencoba membaca semua komentar.

Saya tidak dapat mengabaikan komentar atau berhenti berlangganan dari suatu masalah karena orang memutuskan untuk tidak bermain sesuai aturan yang ditetapkan, mengabaikan panduan yang ditawarkan, dan membajak masalah asli untuk tujuan mereka sendiri. Merupakan tanggung jawab saya untuk mencoba menyelesaikan masalah dengan cara yang sopan, bijaksana dan efisien. Masalah pembajakan membuatnya lebih sulit daripada yang seharusnya untuk mendukung komunitas.

Tolong bantu saya membantu Anda dan masyarakat lainnya.

Semua 21 komentar

Sebenarnya tidak disebutkan __defineGetter__ dalam edisi lama itu, hanya Object.defineProperty, dan kemudian hanya untuk menangani modul Webpack yang ditranspilasikan, bukan Modul ECMAScript yang sebenarnya. Tidak mengatakan itu tidak berhasil, meskipun

Bisakah Anda memposting beberapa contoh javascript vanilla langsung di mana Anda dapat menimpa ekspor (non-default) dari Modul ES yang diimpor? Anda memerlukan dua file some-module.mjs dan file-that-overwrites.mjs untuk menguji ini dan mereka harus memiliki ekstensi .mjs untuk Node untuk mengaktifkan sintaks import .

Test suite ini mendokumentasikan perilaku Sinon saat ini.

FYI rintisan tidak berfungsi untuk [email protected]+ di sini

@fatso83 masalah lama itu memang tidak (tapi saya tidak mengatakannya ).

Maksud saya, Sinon membuat kesalahan saat mendeteksi ESM karena nanti kode Object.defineProperty(object, property, methodDesc) akan gagal dengan TypeError: Cannot assign to read only property 'default' . Namun, __defineGetter__ tidak akan gagal:

object.__defineGetter__(property, methodDesc.value);

Buuuut, ketika saya mencoba memodifikasi kode Sinon dan menjalankannya, saya mendapatkan kesalahan yang tidak terdefinisi pada __defineGetter__ (mungkin mode ketat atau semacamnya?).

Jadi saya mungkin memikirkan cara yang berbeda, seperti membuat ulang objek (dengan nilai baru) alih-alih mengganti propertinya. Lebih kompleks, tapi setidaknya bisa dilakukan.

FYI rintisan tidak berfungsi untuk [email protected]+ di sini

Masalah yang sama di sini versi kerja terakhir 3.8.3

@zorji dan @aelbore : Saya tidak tahu mengapa Anda memposting di utas ini. Jika Anda melaporkan masalah baru, buat masalah terpisah dan ikuti langkah-langkah normal untuk pelaporan (cara memverifikasi, kode aktual, versi, dll). Kami tidak mendukung TypeScript dan tidak pernah mengatakannya, meskipun seharusnya berfungsi, tentu saja, tetapi detailnya akan tergantung pada langkah transpilasi Anda.

Jadi saya mungkin memikirkan cara yang berbeda, seperti membuat ulang objek (dengan nilai baru) alih-alih mengganti propertinya. Lebih kompleks, tapi setidaknya bisa dilakukan.

Apakah itu? Modul ES adalah fitur statis yang terikat saat runtime, AFAIK, dan Anda tidak dapat memodifikasinya.

fitur yang diimpor tersedia dalam file, mereka hanya membaca tampilan dari fitur yang diekspor. Anda tidak dapat mengubah variabel yang diimpor, tetapi Anda masih dapat mengubah properti yang mirip dengan const. Selain itu, fitur-fitur ini diimpor sebagai pengikatan langsung, yang berarti bahwa mereka dapat berubah nilainya bahkan jika Anda tidak dapat mengubah pengikatan tidak seperti const.

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

Menantikan untuk melihat apakah Anda bisa mendapatkan apa saja dengan ini, tetapi saya akan terkejut jika Anda (atau siapa pun!) melakukannya.

Masalah ini secara otomatis ditandai sebagai basi karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut yang terjadi. Terima kasih atas kontribusi Anda.

Bot buruk. Bisakah hal bodoh ini dimatikan?

@OmgImAlexis menurut Anda apakah ada alasan untuk membiarkan masalah ini tetap terbuka?

Teman-teman, tolong coba untuk menjaga masalah ini tetap pada intinya dan hanya membahas apa yang disebutkan dalam posting asli.

Cukup menantang bagi pengelola untuk menghabiskan waktu luang kami yang tidak dibayar untuk mendukung perangkat lunak gratis, tanpa juga harus menavigasi topik ortogonal dalam masalah yang sama.

Kami senang bahwa Sinon (alat JavaScript) juga dapat berguna dalam komunitas TypeScript. Namun, seperti yang dikatakan @fatso83 , kami tidak mendukung TypeScript .

Komentar di luar topik lebih lanjut tentang TypeScript dalam masalah ini akan dihapus.

Komentar di luar topik lebih lanjut tentang TypeScript dalam masalah ini akan dihapus.

@mroderick jika Anda tidak menyukai komentarnya, abaikan saja. Menghapus komentar secara aktif yang akan membantu pengguna lain tidak membantu sama sekali. Katakanlah Anda menghapus komentar maka Anda hanya akan berakhir dengan pengguna serupa datang dan berkomentar lagi dan lagi yang pada gilirannya akan berakhir dengan utas dikunci.

Sunting: Anda juga dapat menggunakan tombol "berhenti berlangganan" yang sangat mudah ditemukan. :)

Ack maaf, saya sangat sibuk di tempat kerja. Saya akan mencoba untuk melihat dalam beberapa minggu. Beberapa perpustakaan mencapai ini, jadi itu pasti mungkin 😁

@mroderick jika Anda tidak menyukai komentarnya, abaikan saja. Menghapus komentar secara aktif yang akan membantu pengguna lain tidak membantu sama sekali. Katakanlah Anda menghapus komentar maka Anda hanya akan berakhir dengan pengguna serupa datang dan berkomentar lagi dan lagi yang pada gilirannya akan berakhir dengan utas dikunci.

Sunting: Anda juga dapat menggunakan tombol "berhenti berlangganan" yang sangat mudah ditemukan. :)

Saya pengelola proyek ini, dan mencoba membaca semua komentar.

Saya tidak dapat mengabaikan komentar atau berhenti berlangganan dari suatu masalah karena orang memutuskan untuk tidak bermain sesuai aturan yang ditetapkan, mengabaikan panduan yang ditawarkan, dan membajak masalah asli untuk tujuan mereka sendiri. Merupakan tanggung jawab saya untuk mencoba menyelesaikan masalah dengan cara yang sopan, bijaksana dan efisien. Masalah pembajakan membuatnya lebih sulit daripada yang seharusnya untuk mendukung komunitas.

Tolong bantu saya membantu Anda dan masyarakat lainnya.

Masalah ini secara otomatis ditandai sebagai basi karena tidak ada aktivitas terbaru. Ini akan ditutup jika tidak ada aktivitas lebih lanjut yang terjadi. Terima kasih atas kontribusi Anda.

Bot buruk.

@ jshado1 menurut Anda masalah ini harus tetap terbuka?

Saya melihat bahwa @ jshado1 mengatakan ini dulu berfungsi dengan baik, tetapi saya rasa ini tidak pernah berhasil di javascript vanilla yang tidak ditranskripsi. Karena seharusnya tidak. Ini dapat bekerja saat mentranspilasikan modul menggunakan Babel/Webpack atau yang serupa, karena Anda hanya mengemulasi modul dan tidak benar-benar membuat objek hanya baca di runtime (modul mana). Klausa lemparan ditambahkan oleh saya, karena _sebaliknya akan melempar_ sedikit kemudian ketika Anda mencoba mengubah yang tidak dapat diubah. Runtimes/modul loader seperti esm mengubah bidangnya sedikit.

Jika menurut Anda perilakunya salah, saya sarankan hanya mengedit node_modules/sinon/lib/sinon/spy.js , hapus klausa lemparan dan laporkan kembali. Tidak ada perasaan sulit. Janji :unicorn: :pelangi:

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

Jika Anda menargetkan commonjs tetapi menulis impor/ekspor modul ES, TS masih akan mencoba memberi Anda perilaku modul ES.

Kode ini secara efektif bukan ES legal, karena kode ini mencoba memodifikasi (secara tidak langsung melalui sinon.stub ) properti hanya-baca (properti dari sesuatu yang diimpor dengan import * as name tidak dapat diubah). Seharusnya tidak pernah berhasil.

Yang pada dasarnya adalah apa yang saya katakan. Jadi penutup, karena hasil ini sepenuhnya tergantung pada Anda menggunakan langkah transpilasi, bagaimana transpiler melakukan langkah itu, dll. Jika mencoba membuat hasil yang agak sesuai dengan spesifikasi ESM, _seharusnya tidak berfungsi_ sebagai ekspor Modul ES tidak dapat diubah (bukan objek aktual yang terikat oleh ekspor tersebut, tentu saja).

@mroderick @fatso83 maaf saya tidak pernah mendapat waktu istirahat dan telah dibanting di tempat kerja sejak itu. Sudah beberapa bulan, tetapi jika ingatanku, saya memiliki _sangat_ contoh kerja yang belum sempurna (dan AF kotor) saat itu untuk mengonfirmasi bahwa itu berhasil (tetapi memang _mungkin_ tidak seharusnya). TAPI, saya pikir itu bukan cara yang harus dilakukan karena: Saya percaya ada/akan menjadi cara resmi untuk melakukan ini melalui pemuat ems: https://github.com/nodejs/node/blob/master/doc/api/esm .md#loaders

Ini saat ini tidak stabil (secara eksplisit dinyatakan akan segera diubah), jadi mungkin tunda sampai mereka menjadi lebih stabil. Tapi begitu mereka melakukannya, saya pikir itulah cara yang harus dilakukan.

Pembaruan: Ini sedang dibahas di nodejs/node#36396.

Saya pikir proposal saya di komentar ini akan membuat ini sangat sederhana. Seorang pengguna dapat menyediakan peta secara manual, dan pemuat esm dapat menggunakannya untuk menggantikan:

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

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

dan/atau, esm loader dapat mencari kecocokan tiruan berdasarkan nama file (contoh cepat dan kotor):

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

if (mockFile) // …

@ jshado1 Terima kasih telah menyediakan tautan itu. Masalah tertaut pada dasarnya adalah tentang mencoba menemukan cara standar untuk menangani masalah penggantian dependensi pada _link level_, yang mirip dengan apa yang dilakukan alat seperti rewire dan proxyquire (yang kami jelaskan dalam cara ini

Apakah halaman ini membantu?
0 / 5 - 0 peringkat