EDIT: panduan cepat untuk memulai: https://jestjs.io/docs/en/ecmascript-modules
Dukungan ESM tidak akan ditandai dalam rilis Node 12 mendatang (mungkin tidak sebelum April https://github.com/nodejs/node/pull/29866#issuecomment-574055057) dan sudah tidak ditandai di Node 13.2, jadi saya pikir itu waktu untuk mengevaluasi bagaimana kami dapat menambahkan dukungan asli di Jest. Saya akan mencoba membuat daftar fitur mana yang saat ini disediakan oleh Jest yang dipengaruhi oleh dukungan ESM, dan bagaimana kami dapat menyelesaikan/menyelidikinya.
Ada masalah #4842, tapi saya pikir itu lebih merupakan masalah diskusi, sementara masalah ini akan diarahkan untuk benar-benar menerapkan dukungan dan lebih cocok untuk dilacak bagi mereka yang hanya ingin mendapatkan status implementasi saat ini. Setiap komentar yang ditambahkan ke masalah ini _not_ terkait dengan bagaimana kami dapat menerapkan dukungan untuk fitur yang disebutkan di bawah ini akan ditandai sebagai spam - harap arahkan solusi/diskusi apa pun ke masalah yang terpisah. Juga jangan ragu untuk memberi tahu kami jika ada sesuatu yang terkait dengan fitur ESM yang hilang dari daftar!
Harap dicatat bahwa Jest akan menggunakan vm
API (https://nodejs.org/api/vm.html) dan pada saat penulisan (node v13.6) bagian ESM dari API ini masih ditandai ( --experimental-vm-modules
). Jadi mengatakan ESM tidak ditandai adalah sedikit keliru saat ini. Tapi saya pikir kita harus mulai bereksperimen dan berpotensi memberikan umpan balik ke Modul WG .
Terakhir, saya menulis masalah ini sebagian besar untuk orang-orang yang akan menerapkan dukungan, jadi ini akan menjadi level rendah dan spesifik untuk cara kerja Jest. Untuk orang-orang yang _hanya_ ingin tahu apakah dukungan telah masuk atau tidak, saya sarankan menggunakan "pemberitahuan khusus" GH yang luar biasa dan hanya berlangganan pemberitahuan saat penutupan/pembukaan kembali.
Kami mencapai kotak pasir dengan menjalankan skrip dalam vm.Context
(baik disediakan oleh JSDOM atau API inti simpul). Kita perlu melakukan hal yang sama untuk ESM, tetapi kita memerlukan akses ke context
selama konstruksi modul, bukan hanya saat menjalankan modul. Saya telah membuka #9428 yang menambahkan API yang diperlukan ke JestEnvironment
.
expect
, test
, beforeEach
dll masih akan ditambahkan sebagai global, tidak ada yang berubah di sini. jasmine
global juga akan tetap ada.
jest
properti "global"Ini tidak benar-benar global - itu disuntikkan ke dalam lingkup modul. Karena ruang lingkup modul hilang di ESM, kita perlu memindahkannya ke suatu tempat. Menambahkannya ke import.meta
tampaknya wajar - ada opsi bernama initializeImportMeta
yang dapat kita gunakan.
EDIT: Solusi di sini adalah mengambilnya melalui import {jest} from '@jest/globals'
. Kami mungkin masih menambahkannya melalui import.meta
di masa mendatang, tetapi ini sudah cukup untuk saat ini.
jest.(do|un)mock
Karena ESM memiliki "tahapan" yang berbeda saat mengevaluasi modul, jest.mock
tidak akan berfungsi untuk impor statis. Ini dapat bekerja untuk impor dinamis, jadi saya pikir kita hanya perlu memperjelas dokumen tentang apa yang didukungnya dan apa yang tidak.
jest.mock
panggilan diangkat, tetapi itu tidak membantu dalam ESM. Kami mungkin mempertimbangkan untuk mengubah import 'thing'
menjadi import('thing')
yang seharusnya memungkinkan pengangkatan berfungsi, tetapi kemudian menjadi asinkron. Menggunakan await
mungkin merupakan kebutuhan untuk pendekatan semacam itu. Saya juga berpikir itu cukup invasif untuk menjamin opsi terpisah. Sesuatu untuk didiskusikan - kita tidak perlu mendukung semua yang jest.mock
dapat lakukan untuk rilis awal.
jest.requireActual
Tidak yakin bagaimana seharusnya berperilaku di ESM. Haruskah kita memberikan jest.importActual
dan membiarkan requireActual
mengevaluasi CJS
?
import.meta
Node memiliki url
sebagai satu-satunya propertinya (setidaknya untuk saat ini). Kita perlu memastikan itu diisi di Jest juga. Kami menyediakan identifier
alih-alih filename
ketika membangun modul jadi saya tidak berpikir itu akan terjadi secara otomatis, tetapi url
pada dasarnya filename
dilewatkan meskipun pathToFileURL
.
Ada juga PR terbuka untuk import.meta.resolve
: https://github.com/nodejs/node/pull/31032
import thing from 'thing'
Ini sebenarnya cukup mudah, kita hanya perlu mengimplementasikan linker
mana kita juga dapat mengubah sumber sebelum mengembalikannya, artinya kita tidak memerlukan API pemuat (yang belum ada). Ini memungkinkan kita untuk mengembalikan tiruan juga (walaupun itu harus berasal dari direktori __mocks__
).
import('thing')
Pada dasarnya sama seperti di atas, tetapi diteruskan sebagai importModuleDynamically
saat membuat modul. Juga akan mendukung jest.mock
, jest.resetModules
dll lebih bersih, jadi kemungkinan besar akan digunakan sedikit.
Ini juga dapat dilakukan untuk vm.Script
melalui opsi yang sama.
Saat ini kesalahan runtime (misalnya modul tidak ditemukan), tapi itu belum tentu benar dengan ESM. Apakah itu penting bagi kita? Kami harus memverifikasi kesalahan masih terlihat bagus.
module.createRequire
Kita perlu menangani ini untuk orang yang ingin menggunakan CJS dari ESM. Saya telah membuka #9426 untuk melacak ini secara terpisah karena penerapannya tidak terlalu terkait dengan dukungan ESM.
EDIT: Diimplementasikan di #9469
module.syncBuiltinESMExports
https://nodejs.org/api/modules.html#modules_module_syncbuiltinesmexports. Apakah kita peduli tentang itu, atau hanya membuatnya tidak cukup? Tidak yakin seperti apa use case di Jest. Bermain-main dengan builtin sudah memecahkan kotak pasir dan saya rasa ini tidak masalah.
EDIT: # 9469 membuat ini menjadi no-op. Saya pikir itu baik-baik saja?
Memeriksa bidang type
di package.json
modul tampaknya masuk akal: https://nodejs.org/api/esm.html#esm_enabling. Haruskah kita juga memiliki flag konfigurasi sendiri? Juga perlu menghormati akhiran file.
https://github.com/nodejs/modules/issues/393
moduleNameMapper
Tidak yakin apakah ini berdampak pada apa pun. Saya _think_ tidak karena kita sendiri yang akan menghubungkan modul-modul tersebut. Perlu penyelidikan, meskipun.
EDIT: Ini semua logika resolusi, yang kami kendalikan. Jadi tidak ada perubahan di sini.
jest.config.mjs
Melalui #9291 kami mendukung jest.config.cjs
- apakah kami perlu melakukan sesuatu yang khusus untuk .mjs
? Mungkin menggunakan import('path/to/configFile.mjs')
yang berarti harus asinkron. Apakah ini masalah? Mungkin layak untuk membuat resolusi konfigurasi async
di Jest 25 jadi itu bukan pemblokir untuk dukungan tambahan ESM di Jest 25.
EDIT: #9431
Node mendukung ekspor paket , yang agak memetakan ke moduleNameMapper
Jest, tetapi juga menyediakan fitur enkapsulasi. Mudah-mudahan resolve
akan mengimplementasikan ini, tetapi jika tidak, kita perlu melakukan sesuatu. Mungkin cukup untuk menggunakan opsi pathFilter
? Tidak yakin.
https://nodejs.org/api/esm.html#esm_experimental_json_modules. Apakah kita perlu peduli? Mungkin, terutama untuk json
. Ini sepele bagi kami untuk mendukung import thing from './package.json'
karena kami mengontrol fase penautan, tetapi kami mungkin tidak melakukannya secara default karena akan berbeda dari node default. Haruskah kita memaksa orang untuk mendefinisikan transformasi untuk itu?
Apakah itu penting? Saya tidak berpikir itu terpengaruh karena kami masih dapat mengubah sumber dengan babel (mungkin akan bingung dengan pernyataan import
, mungkin tidak) dan cakupan V8 pasti tidak peduli. Kita harus memverifikasi sekalipun.
Ini sama sekali bukan pemblokir karena resolusi sinkronisasi akan berfungsi dengan baik. Tapi kami _can_ menggunakan resolusi async sekarang, yang sangat bagus. Saya ingin tahu apakah kita harus melihat hanya menggunakan modul resolve
dari npm lagi, karena sudah mendukung async. Lihat #9505.
Mirip dengan di atas, tidak memblokir, tetapi alangkah baiknya untuk mendukungnya. Mungkin membuat @jest/transformer
lebih bermanfaat di lingkungan lain juga. Lihat #9504.
Karena #5163 kami memiliki opsi extraGlobals
sebagai solusi - solusi tersebut tidak lagi dapat dijalankan di ESM. Saya telah membuka dan mengeluarkan simpul di sini: https://github.com/nodejs/node/issues/31658
Saya telah mendapatkan dukungan yang sangat mendasar dengan #9772. Saya hanya menguji kasus yang paling sederhana, dan ada banyak batasan yang diketahui (terutama tidak ada dukungan objek jest
dan semantik yang rusak saat mencampur CJS dan ESM), tetapi setidaknya itu _something_. Itu akan keluar di rilis Jest berikutnya (semoga segera, hanya diblokir oleh #9806)
25.4.0 telah dirilis dengan dukungan pertama. Selain #9772 yang disebutkan di atas, saya juga menyertakan #9842. Dalam _theory_ pencampuran CJS dan ESM harus bekerja dengan benar sekarang (🤞).
Satu fitur utama yang hilang adalah mendukung objek jest
. Saya belum memutuskan apakah kita harus tetap menggunakan import.meta
atau meminta orang untuk mengimpornya melalui import {jest} from '@jest/globals'
. Umpan balik dihargai!
Saya belum menulis dokumen untuk ini, tetapi untuk mengaktifkannya Anda perlu melakukan 3 hal
import
pernyataan (set transform: {}
di config atau memastikan babel
tidak mengubah file ke CJS, seperti menghindari modules
opsi ke preset-env)node@^12.16.0 || >=13.2.0
dengan flag --experimental-vm-modules
jest-environment-node
atau jest-environment-jsdom-sixteen
Silakan mencobanya dan berikan umpan balik! Jika melaporkan bug, alangkah baiknya jika Anda juga dapat menyertakan cara menjalankan kode yang sama (dikurangi kode khusus pengujian apa pun) berjalan di Node.js. Saya telah membaca https://nodejs.org/api/esm.html _a lot_ selama beberapa minggu terakhir, tetapi saya mungkin melewatkan sesuatu.
Satu fitur utama yang hilang adalah mendukung objek lelucon. Saya belum memutuskan apakah kita harus menempelkannya ke import.meta atau mengharuskan orang untuk mengimpornya melalui import {jest} dari '@jest/globals'.
Untuk kasus penggunaan TypeScript, lebih baik memiliki impor eksplisit.
Yup, saya telah menambahkan (dan mengembalikan sementara) paket @jest/globals
yang mendukung ini, sehingga akan tersedia terlepas dari itu. Saya ingin tahu apakah masuk akal untuk _also_ mengeksposnya di import.meta
. Saat ini condong ke arah tidak melakukannya, terutama karena lebih mudah untuk menambahkan daripada menghapus nanti (dan saya pribadi bukan penggemar global)
+1 untuk impor eksplisit, ini sedikit lebih bertele-tele tetapi lebih mudah dipahami
Saya mendapatkan ini di Node 13.2 & Jest 25.4: ES Modules are only supported if your test environment has the
getVmContext function
Apa yang saya lewatkan?
@zandaqo Oh maaf, lupa poin itu. Ditambahkan di atas, tapi itu
Jalankan pengujian Anda dengan
jest-environment-node
ataujest-environment-jsdom-sixteen
ReferenceError: jest is not defined
Saya menduga ini karena @jest/globals
hilang
Ya, seperti yang disebutkan ini hanya akan berfungsi jika Anda tidak menggunakan objek jest
.
Mock juga mungkin rusak, belum diuji
Saya telah mengkompilasi proyek yang sangat mendasar dari apa yang saya lihat di direktori tes e2e ( e2e/native-esm/__tests__/native-esm.test.js
) dan dalam masalah ini. Dan sayangnya saya masih tidak bisa membuatnya bekerja Adakah yang bisa memeriksanya?
https://drive.google.com/file/d/1vyDZjsVKOTu6j55QA11GjO9E7kM5WX8_/view?usp=sharing
Menjalankan contoh skrip (hanya mengimpor fungsi double
dan mencetak double(2)
):
npm run main
> [email protected] main /Users/ilya/Projects/jest-esm
> node src/main.js
(node:16961) ExperimentalWarning: The ESM module loader is experimental.
4
Menjalankan lelucon hanya dengan satu tes untuk fungsi ganda:
npm run test
> [email protected] test /Users/ilya/Projects/jest-esm
> jest
FAIL __tests__/native-esm.test.js
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/Users/ilya/Projects/jest-esm/__tests__/native-esm.test.js:8
import {double} from '../src/index.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime._execModule (node_modules/jest-runtime/build/index.js:1074:58)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.542s
Ran all test suites.
Anda perlu menjalankan node dengan --experimental-vm-modules
dan nama yang Anda ajukan .mjs
atau "type": "module"
di package.json
.
EDIT: Anda mungkin memiliki yang terakhir karena berfungsi di luar Jest untuk Anda, hanya melewatkan flag eksperimental ke Node
@SimenB oh wow ada --experimental-vm-modules
DAN --experimental-modules
. Saya bingung dengan kenyataan bahwa --experimental-modules
tidak diperlukan mulai dari beberapa versi node 13. Terima kasih!
TLDR: node --experimental-vm-modules node_modules/jest/bin/jest.js
bekerja untuk saya
Ya, dari OP
Harap dicatat bahwa Jest akan menggunakan
vm
API (https://nodejs.org/api/vm.html) dan pada saat penulisan (node v13.6) bagian ESM dari API ini masih ditandai (--experimental-vm-modules
). Jadi mengatakan ESM tidak ditandai adalah sedikit keliru saat ini.
Luar biasa bahwa itu bekerja untuk Anda!
(Saya akan menandai komentar ini sebagai terselesaikan)
@SimenB Terima kasih untuk ini! Dua masalah yang saya lihat sejauh ini.
ReferenceError: module is not defined
dalam file paket CJSJadi saya pikir ini mungkin tidak diterapkan dengan benar?
Pernyataan impor dapat mereferensikan modul ES atau modul CommonJS
Ini berfungsi dengan baik saat menjalankan aplikasi. Ekspor bernama dari CJS hanya dapat diimpor dengan menggunakan createRequire, tetapi ekspor default hanya dapat diimpor.
Ketika saya tidak menemukan kesalahan di atas, saya menemukan yang ini:
TypeError: _vm(...).SyntheticModule is not a constructor
at Runtime._importCoreModule (node_modules/jest-runtime/build/index.js:1198:12)
targets: { node: 12 }
dan 2 plugin: babel-plugin-transform-import-meta
dan rewire-exports
. (Mencoba menghapus plugin import-meta
tetapi mendapat kesalahan saat mengatakan untuk menambahkannya kembali.)testEnvironment: "node"
adalah satu-satunya konfigurasinode --experimental-vm-modules node_modules/jest/bin/jest.js
Jika repo reproduksi akan membantu, beri tahu saya.
Terima kasih @aldeed!
Saya akan membahas masalah 1, yang memang terlihat seperti bug. EDIT: Harus diperbaiki melalui #9850
Masalah 2 membutuhkan node 12.16.0: https://nodejs.org/docs/latest-v12.x/api/vm.html#vm_class_vm_syntheticmodule
Saya akan mengubah centang di Jest (saat ini memeriksa vm.SourceTextModule
yang tersedia di lebih banyak versi, tetapi kami juga membutuhkan SyntheticModule
).
Dikonfirmasi bahwa berjalan dengan 12.16.0 memperbaiki masalah saya 2. Akan menguji ulang masalah 1 setelah perbaikan itu dirilis. Jika tidak, menunggu objek jest
untuk pengujian lebih lanjut, dan saya setuju bahwa itu harus diimpor.
Kerja yang luar biasa, @SimenB! Saya mencoba ini pada proyek kecil tetapi mengalami masalah dengan impor dinamis. Ini adalah kesalahan yang saya lihat:
Module status must not be unlinked or linkingError [ERR_VM_MODULE_STATUS]: Module status must not be unlinked or linking
Jika saya menghapus impor dinamis maka tes akan berjalan (tetapi gagal karena alasan lain, tentu saja). Tes yang sama saat ini bekerja dengan Mocha (yang mengirimkan dukungan ESM baru-baru ini).
Jika membantu, impor dinamis yang dimaksud dapat dilihat di sini: https://github.com/beejunk/firn.js/blob/switch-to-jest/lib/renderPage.js#L43 -L55
File tes ada di sini: https://github.com/beejunk/firn.js/blob/switch-to-jest/test/build.test.js. Versi Mocha yang berfungsi dapat dilihat di cabang master.
Beri tahu saya jika ada info lain yang berguna bagi saya.
Terima kasih @beejunk! Saya bertanya-tanya apakah mungkin ada kondisi balapan antara import
s yang mengimpor modul yang sama sebelum ditautkan sepenuhnya. _Sepertinya_ itulah yang Anda lakukan di sini. Saya akan memperbaikinya hari ini, terima kasih atas laporannya!
EDIT: Diperbaiki di #9858. Menyalin perbaikan ke repo Anda:
Adakah yang berhasil membuatnya bekerja dengan TypeScript? node --experimental-vm-modules node_modules/jest/bin/jest.js
mengembalikan SyntaxError: Cannot use import statement outside a module
, meskipun package.json
memiliki "type": "module"
.
babel.config.cjs
module.exports = {
presets: [
'@babel/preset-typescript',
],
};
jest.config.cjs
module.exports = {
testEnvironment: 'jest-environment-node',
transform: {},
};
@ dandv Anda pada dasarnya memukul kasus ini: https://github.com/facebook/jest/pull/9772/files#r407255029
Bisakah Anda membuka masalah terpisah? Perlu mencari tahu apa yang harus dilakukan dengan ekstensi non-js
@SimenB : #9860. Terima kasih telah melihat.
@aldeed @beejunk 25.5.0 telah dirilis dengan perbaikan untuk masalah Anda. Jauhkan laporan bug datang
Oh, tambahan itu termasuk dukungan untuk import { jest } from '@jest/globals'
bagi yang menunggu itu 👍
Terima kasih atas kerja cepat untuk semua ini, @SimenB! Saya pikir saya telah mengalami masalah lain.
Saya telah bereksperimen dengan menggunakan params kueri di jalur impor sebagai cara untuk menghilangkan cache modul di server pengembangan. Idenya adalah memiliki file watcher yang mendeteksi perubahan dalam komponen dan kemudian memperbarui jalur impor dengan parameter kueri arbitrer sehingga kode baru segera ditarik pada pemuatan halaman berikutnya tanpa harus me-restart server. Ini berfungsi saat menjalankan server dev. Namun, Jest melempar kesalahan berikut:
Cannot find module '/path/to/project/components/BasePage.js?cache=0' from 'renderPage.js'
Berikut adalah contoh di mana parameter kueri digunakan: https://github.com/beejunk/firn.js/blob/switch-to-jest/lib/renderPage.js#L55 -L56
Jika saya menghapus params kueri maka tes akan lulus, meskipun tidak secara konsisten. Jika saya menjalankan satu suite (misalnya, npm test -- test/build.test.js
) tes lulus, tetapi jika saya menjalankan semua tes sekaligus mereka akan gagal sebagian besar waktu dengan kesalahan ambigu. Saya masih menggali masalah dengan tes yang tidak konsisten, tetapi saya pikir saya akan melaporkan masalah param kueri terlebih dahulu.
Terima kasih atas laporannya @beejunk. #6282 seharusnya menangani ini, tetapi itu juga ingin meneruskan kueri ke transformer dan sejenisnya, yang tidak kita perlukan di sini. Jadi mungkin masuk akal untuk hanya mendukung kueri secara internal di runtime untuk saat ini, dan biarkan #6282 hanya berurusan dengan meneruskan kueri itu.
Saya telah menambahkan sedikit kode untuk membuat cache modul bervariasi berdasarkan kueri: https://github.com/facebook/jest/blob/d425a49bd575e7167bc786f3c4f2833589091fa1/packages/jest-runtime/src/index.ts#L330 -L334
Tetapi tidak ada kode yang pernah memanggilnya dengan kueri. Saya pikir kita harus bisa melakukan resolvePath.split('?')
dan semua harus bekerja.
Mengenai kesalahan yang tidak konsisten, saya akan melihat apakah repo itu mereproduksinya. Saya belum menguji kode ESM dengan tes secara paralel, hanya satu tes. Saya tidak yakin mengapa itu akan memengaruhi banyak hal, tetapi siapa yang tahu
@beejunk masalah kueri diperbaiki di 25.5.1. Saya belum punya waktu untuk menyelidiki masalah lainnya
Saya memiliki masalah yang menurut saya mungkin terkait dengan ini namun tidak diperbaiki di 25.X
.
Saya akan mencoba merangkum escenario di bawah ini:
{ default: generator } = require(path.resolve(f))
f
tidak ditranspilasikan yang menyebabkan "kesalahan impor pengenal yang tidak terduga".Ini juga terjadi jika saya mencoba dengan import()
Karena Anda menyebutkan transpilasi; jika Anda memiliki pengaturan yang mengubah import
menjadi require
masalah ini bukan tempat yang benar - masalah ini tentang dukungan asli.
Yang mengatakan - Anda tidak dapat require
ESM, dan saya belum dapat menambahkan dukungan untuk import()
dari CJS karena Node tidak memiliki API untuk itu. Dukungan untuk itu telah mendarat di Node master, tetapi belum dirilis: https://github.com/nodejs/node/pull/32985. Seperti yang dapat dilihat di PR rilis terkait, itu akan datang di 13.14.0 dan 14.1.0. Pada saat itu saya akan menerapkan dukungan untuk itu 👍
Anda seharusnya dapat menggunakan file setup .mjs
.
@SimenB Ini bagus, tampaknya berfungsi di beberapa file pengujian sekarang! Ini sedikit proses untuk menyelesaikan perbedaan antara impor Babel dan Node di setiap file, menambahkan impor lelucon, dll., jadi saya mungkin menemukan lebih banyak masalah saat saya melakukannya di ratusan file pengujian.
Beberapa hal yang lebih banyak pertanyaan:
import()
dari cjs, apakah itu juga memungkinkan file konfigurasi Jest diberi nama jest.config.js
? Saat ini hanya berfungsi untuk saya ketika bernama jest.config.cjs
dan menggunakan module.exports =
(kesalahan adalah TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]: A dynamic import callback was not specified
)node/no-extraneous-import
karena bukan merupakan paket yang terdaftar di package-lock
. Apakah ada alasan untuk konvensi penamaan ini? Apakah mungkin menggunakan jest
tanpa @
? Sangat mudah untuk mengabaikan aturan tetapi saya hanya ingin tahu.jest
global berbeda dari magic fns seperti test
, describe
, before
, dll.? Haruskah semua itu diimpor sekarang juga?--experimental-vm-modules
? Agak membuat ini tampak tidak standar jika tidak hanya bekerja dengan perintah jest
. Jika Anda tidak dapat mengirimkan flag secara langsung, mungkin Anda dapat mengatur/mengubah variabel env NODE_OPTIONS
?apakah itu juga memungkinkan file konfigurasi Jest diberi nama jest.config.js?
Itu dapat dinamai .js
jika package.json
memiliki type: 'module'
. Jika tidak, untuk menggunakan ESM dalam file konfigurasi, itu perlu diberi nama .mjs
. Lihat https://nodejs.org/api/esm.html#esm_enabling. Perhatikan bahwa file konfigurasi berjalan di luar Jest, jadi di sana kita tidak memiliki banyak kendali. Saat ini, kami tidak mendukung konfigurasi async, tetapi await
melakukan janji yang diekspor akan menjadi masalah sepele, sambutan PR #8357 terhenti.
Saya sangat terkejut Anda mendapatkan A dynamic import callback was not specified
, kami tidak memuat file konfigurasi di vm... Bisakah Anda membuka masalah terpisah?
Nama "@jest/globals" gagal dalam aturan eslint
node/no-extraneous-import
karena bukan merupakan paket yang terdaftar dipackage-lock
. Apakah ada alasan untuk konvensi penamaan ini? Apakah mungkin menggunakanjest
tanpa@
? Sangat mudah untuk mengabaikan aturan tetapi saya hanya ingin tahu.
Anda harus menambahkan devDependency
pada @jest/globals
. Paket itu sendiri hanyalah definisi tipe. Ini adalah paket terpisah dari jest
sehingga definisi tipe bekerja dengan benar, dan jadi kami dapat membuat kesalahan jika dimuat di luar runtime Jest.
Saat ini saya tidak memiliki rencana untuk mengubahnya, tetapi kami mungkin dapat menghentikan paket itu dan mengekspor jenisnya dari jest
. Itu adalah perubahan besar, jadi mari kita lihat nanti
Pertanyaan terkait, mengapa
jest
global berbeda dari magic fns sepertitest
,describe
,before
, dll.? Haruskah semua itu diimpor sekarang juga?
jest
seperti objek require
atau module
dari CJS karena unik per file, sebenarnya bukan global (yaitu globalThis.jest === undefined
). Itu memungkinkan jest.mock('../../file.js')
dll bekerja dengan benar relatif terhadap file yang disuntikkannya. Anda dapat memilih untuk juga mengimpor global yang sebenarnya, tetapi mereka masih tersedia sebagai globalThis.expect
dll.
Ketika ini selesai, apakah mungkin bagi Jest untuk menyetel flag
--experimental-vm-modules
?
Saya pikir kita akan menunggu node untuk menghapus tandanya daripada mengaturnya secara diam-diam - mereka ditandai karena suatu alasan, API mungkin berubah di beberapa titik. Kami dapat menambahkan opsi yang mengatur NODE_OPTIONS
Saya kira, tidak yakin apakah itu mengubah runtime saat ini? Terlepas dari itu, tidak ada rencana saat ini untuk itu.
Saya sekarang tampaknya mendapatkan kesalahan yang sedikit berbeda dari sebelumnya ketika mencoba ini pada Node yang lebih lama, tetapi tidak ada kesalahan yang jelas bahwa versi Node minimum adalah masalahnya. Apakah mudah menambahkan centang untuk versi minimum dengan pesan kesalahan yang lebih bermanfaat?
Ya, saya akan menambahkan pesan kesalahan yang lebih baik bersama dengan beberapa dokumentasi setelah implementasinya sedikit stabil. Melihat implementasinya dijaga oleh bendera eksperimental, saya tidak berpikir siapa pun akan tersandung karenanya.
@SimenB , saya memperbarui Jest ke 25.5.2 dan sekarang semua tes lulus. Parameter kueri berfungsi dan kesalahan intermiten yang saya lihat sebelumnya tidak lagi terjadi. Terima kasih lagi untuk semua pekerjaan Anda!
Oke, saya melihat kesalahan lagi pada pengujian terakhir saya, jadi itu masih terjadi. Saya akan melihat apakah saya dapat menemukan cara untuk secara konsisten mereproduksi dan melaporkan kembali.
Saya yakin saya telah menemukan cara yang konsisten untuk mereproduksi masalah. Inilah cabang tempat saya bekerja: https://github.com/beejunk/firn.js/tree/switch-to-jest
Untuk mereproduksi:
/tmp/jest_rs
secara manual.npm test
tiga kali. Dua putaran pertama harus berhasil. Namun, putaran ketiga harus gagal.Ini adalah jejak tumpukan yang saya lihat ketika kesalahan terjadi:
Error:
at invariant (/home/brian/Projects/firn.js/node_modules/jest-runtime/build/index.js:1866:11)
at Runtime.loadEsmModule (/home/brian/Projects/firn.js/node_modules/jest-runtime/build/index.js:480:7)
at Runtime.linkModules (/home/brian/Projects/firn.js/node_modules/jest-runtime/build/index.js:548:19)
at importModuleDynamicallyWrapper (internal/vm/module.js:397:21)
at htmPreactPath (internal/process/esm_loader.js:31:14)
at renderPage (/home/brian/Projects/firn.js/lib/renderPage.js:53:15)
at map (/home/brian/Projects/firn.js/lib/build.js:43:12)
at Array.map (<anonymous>)
at build (/home/brian/Projects/firn.js/lib/build.js:36:43)
at Object.<anonymous> (/home/brian/Projects/firn.js/test/build.test.js:57:5)
Kesalahan tampaknya berasal dari impor dinamis. Tidak ada pesan kesalahan, jadi saya tidak sepenuhnya yakin apa yang terjadi.
Catatan tambahan: Jika saya menghapus cache Jest dan memperbarui skrip pengujian dengan menambahkan --no-cache
, maka saya tidak dapat mereproduksi masalah.
Heh, saya malas di sana dan tidak memberikan pesan kesalahan yang tepat. Masalahnya adalah lingkungan pengujian telah diruntuhkan, jadi saya kira ada await
hilang di suatu tempat. Tidak melihat apa pun yang melihat melalui kode Anda, jadi saya harus menggali lagi
@SimenB Ini adalah reproduksi masalah konfigurasi ESM itu: https://github.com/facebook/jest/issues/9935
@SimenB Saya telah membuat contoh minimal untuk mereproduksi kesalahan Jest yang saya sebutkan di atas saat menggunakan impor dinamis:
Terima kasih atas reproduksi yang luar biasa @beejunk! Saya telah menghabiskan lebih banyak waktu yang saya akui di sini, tanpa benar-benar memahami apakah itu bug di Jest atau di Node.js. Saya telah mereproduksi perilaku hanya menggunakan modul inti simpul dan melaporkannya ke hulu, jadi mari kita lihat apa yang mereka katakan: https://github.com/nodejs/node/issues/33216
Terima kasih telah memeriksanya, @SimenB. Tes tampaknya lulus secara konsisten jika saya menambahkan flag --no-cache
, yang baik untuk kasus penggunaan saya. Saya menghargai semua pekerjaan!
Ya, saya perhatikan itu juga. Saya pikir ini semacam masalah waktu - tanpa cache, semuanya cukup lambat untuk berfungsi.
@SimenB Terima kasih telah menyelesaikan #9935. Saya menyebutkan kekhawatiran kedua di sana, yang menurut saya masih valid. Ketika type: "module"
, jest --init
masih menghasilkan file konfigurasi dengan module.exports
di dalamnya. Ini relatif kecil untuk diubah secara manual jika Anda tahu apa yang Anda lakukan, tetapi saya pikir jika ESM tidak ditandai di Node dan banyak orang mulai melakukan proyek ESM, itu akan mulai terlihat lebih seperti bug yang membingungkan (yaitu, jalur bahagia dari jest --init && jest
pada proyek ESM baru akan menimbulkan kesalahan). Haruskah saya mengirimkan masalah berbeda secara khusus tentang meningkatkan logika init?
@aldeed apakah kamu yakin? Pengujian sekarang memberi saya file mjs
dengan export default
di dalamnya. Saya kira kita bisa menghasilkan js
dan bukan mjs
, tapi tetap saja. Ini menggunakan sintaks ESM
@SimenB Yah saya yakin sampai Anda bertanya. Saya mencobanya dan Anda benar. Mungkin saya awalnya melakukannya dengan versi Node atau Jest yang lebih lama? Mengabaikan.
Ini luar biasa! Baru saja mengerjakan ulang tes di salah satu perpustakaan saya untuk menggunakan Modul ES dan membuang Babel. Terima kasih @SimenB!
Deteksi apakah suatu file seharusnya menjadi mode ESM atau CJS
Omong-omong, ada banyak paket berorientasi browser/bundler yang menggunakan sintaks "module":"<path to es module>"
untuk menunjukkan ekspor modul ES mereka. Mungkin bijaksana untuk memiliki beberapa cara untuk menentukan cara menyelesaikan paket yang diberikan terlepas dari pengaturan paket itu sendiri. Sesuatu seperti moduleNameMapper
tetapi untuk menentukan apakah itu CJS atau ESM.
hai @SimenB , setelah masalah ini ditutup, itu berarti ts-jest
juga dapat membatalkan commonjs
kan? Apakah ekstensi file diperlukan untuk mengubah dari sisi transformator agar berfungsi dengan esm?
Misalnya sekarang ts-jest
mengkompilasi ts
ke js
untuk commonjs
, apakah esm
memerlukan ekstensi file mjs
saat mengkompilasi dari ts
ke js
?
@zandaqo kami tidak akan mendukung bidang modules
, kami akan mengikuti spesifikasi node dan menggunakan exports
: #9771. Anda dapat memasang resolver Anda sendiri untuk mendukung modules
jika Anda mau, meskipun: https://jestjs.io/docs/en/configuration#resolver -string. Kami mungkin menambahkan beberapa opsi lain ( mainFields
, seperti webpack mungkin?), tetapi itu akan datang lebih jauh ketika implementasinya stabil dan kami memiliki lebih sedikit yang tidak diketahui yang tidak diketahui
@ahnpnl #9860
Ciao guys!
Hanya sebuah pertanyaan: posting blog menyebutkan bahwa, karena modul ES6 statis, mereka tidak dapat diejek; jadi, sebenarnya, tidak ada cara untuk mengejek modul A yang diimpor oleh modul B di ES6?
@gabrieledarrigo saya menggunakan moduleNameMapper
untuk itu, misalnya:
"moduleNameMapper": {
"moduleA": "<rootDir>/test/moduleA-mock.js"
},
@gabrieledarrigo Anda bisa melakukannya
jest.mock('the-thing-i-want-to-mock', () => /* do whatever in here */);
let importedThing;
beforeAll(async () => {
importedThing = await import('thing-that-imports-mocked-module');
});
Jadi Anda hanya perlu membuat impor non-statis dan ejekan akan berfungsi.
Saya tidak yakin itu berfungsi sekarang, karena saya belum memasang resolusi tiruan di jalur kode ESM. Akan melakukannya di beberapa titik segera. Tapi itu _mungkin_ akan menjadi cara kami mendokumentasikan tiruan modul untuk ESM asli.
Seperti yang disebutkan dalam pot blog, kami akan mendokumentasikan pola-pola ini di beberapa titik, kami hanya perlu mencari tahu
Satu ide yang kami miliki adalah menunggu level teratas menunggu, kemudian kami dapat melakukan ini dengan plugin babel.
@SimenB Pertama-tama, terima kasih atas pekerjaan yang luar biasa di sini :)
Saya sebenarnya menghadapi masalah ketika saya ingin membuat customEnvironment yang diperluas dari jest-environment-node
. Saya perlu mengimpor implementasi server saya di sana, yang ditulis sebagai esm. Tapi sepertinya, lingkungan harus didefinisikan sebagai cjs
.
Pertanyaan saya adalah, apakah ada opsi untuk mendefinisikan testEnvironment khusus sebagai esm untuk dapat mengimpor modul server saya? Terima kasih atas sarannya.
@kuka-radovan bisakah Anda membuka permintaan fitur terpisah untuk itu?
PEMBARUAN: Masalah ini sekarang dilacak di https://github.com/facebook/jest/issues/10025
@SimenB Terima kasih atas saran jest.mock
atas. Kebetulan saya mengonversi beberapa file yang membutuhkannya hari ini. Saya dapat mengonfirmasi bahwa contoh Anda berfungsi ketika modul yang diejek adalah paket node_modules
, tetapi itu tidak berfungsi untuk saya yang mengejek modul dalam proyek yang sama.
Berikut ini contoh sederhana:
// main.js
import secondary from "./secondary.js";
export default function main() {
return secondary();
}
// secondary.js
export default function secondary() {
return true;
}
// test.js
import { jest } from "@jest/globals";
jest.mock("./secondary.js");
let main;
let secondary;
beforeAll(async () => {
({ default: main } = await import("./main.js"));
({ default: secondary } = await import("./secondary.js"));
});
test("works", () => {
secondary.mockReturnValueOnce(false); // TypeError: Cannot read property 'mockReturnValueOnce' of undefined
expect(main()).toBe(false);
});
Pola yang sama persis berfungsi ketika "./secondary.js"
adalah nama paket. (Saya pikir paket yang saya coba dengan ekspor CommonJS, jika itu penting.)
Bercanda 26.0.1 dengan Node 12.16.3
Ada ide, atau haruskah saya mengirimkan edisi terpisah sepenuhnya?
EDIT: transform: {}
dalam konfigurasi, jadi tidak ada Babel sama sekali
EDIT 2: Ini juga tidak berfungsi:
jest.mock("./secondary.js", () => ({
default: jest.fn()
}));
Pekerjaan luar biasa dalam hal ini.
Namun, kecuali saya melakukan sesuatu yang salah, sepertinya tidak mungkin untuk menggunakan import()
dalam file pengujian CJS.
Saya menjalankan Jest dengan node --experimental-vm-modules node_modules/jest/bin/jest.js
dan memiliki testEnvironment: 'node', transform: {}
di jest.config.js
. Ini ada di Node 14.2.0.
Ekspresi impor menghasilkan kesalahan:
TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]:
A dynamic import callback was not specified.
Apakah ini batasan yang diketahui saat ini? Saya melihat https://github.com/nodejs/node/pull/32985 kini telah mendarat di Node 14.1.0.
Ya, saya belum sempat menerapkannya. Saya mungkin akan mendaratkannya akhir pekan ini.
@aldeed bisakah Anda membuka masalah terpisah? Saya harus melalui dan memastikan ejekan adalah bagian dari resolusi, dan contoh Anda tampak seperti kasus uji yang bagus
@SimenB Terima kasih atas balasan cepatnya. Aku akan mengawasinya saat mendarat.
Melihat import
dalam skrip mungkin dikembalikan karena regresi (https://github.com/nodejs/node/issues/33166), mari tunda sampai selesai
Saya mengalami masalah saat mencoba menggunakan ini dengan file uji .mjs
. Jika saya memiliki __tests__/my-test.mjs
, saya mendapatkan
$ yarn test
yarn run v1.22.4
$ node --experimental-vm-modules node_modules/jest/bin/jest.js
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In C:\Users\Domenic\Dropbox\Programming\WIP\remember-to-eat
1 file checked.
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 0 matches
testPathIgnorePatterns: \\node_modules\\ - 1 match
testRegex: - 0 matches
Pattern: - 0 matches
error Command failed with exit code 1.
Jika saya menambahkan
"testMatch": ["**/__tests__/**/*.mjs"]
ke package.json saya, saya mendapatkan
$ yarn test
yarn run v1.22.4
$ node --experimental-vm-modules node_modules/jest/bin/jest.js
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In C:\Users\Domenic\Dropbox\Programming\WIP\remember-to-eat
1 file checked.
testMatch: **/__tests__/**/*.mjs - 0 matches
testPathIgnorePatterns: \\node_modules\\ - 1 match
testRegex: - 0 matches
Pattern: - 0 matches
error Command failed with exit code 1.
Namun jika saya menghapus "testMatch"
dan kemudian mengganti nama file saya menjadi __tests__/my-test.js
, itu berfungsi.
Saya ingin dapat menggunakan ekstensi .mjs secara konsisten dalam proyek saya. Apakah itu mungkin dengan Jest?
@domenic saya juga mengalami ini. Solusinya adalah menambahkan ke config "moduleFileExtensions": ["js", "mjs"]
(selain "testMatch"
).
Lihatlah, dan moduleFileExtensions
memang diperlukan.
Jest mendapatkan daftar semua file dalam proyek dengan menjalankan hasteFS.getAllFiles()
sini:
hasteFS
dibuat sebagai bagian dari HasteMap
dengan konfigurasi extensions
:
Namun, saya rasa tidak perlu menentukan moduleFileExtensions
dalam kasus ini. Kami sudah memaksa .snap
untuk ditemukan, haruskah kami memaksa ekstensi JS yang terkenal juga? Mereka adalah (dari atas kepalaku) js
, mjs
, cjs
, jsx
, ts
dan tsx
? Itu akan membuat perayapan lebih lambat, tetapi saya tidak berpikir itu memiliki dampak yang besar. Saya mungkin salah meskipun? Sebagai default, seharusnya tidak lebih lambat karena hanya cjs
dan mjs
yang belum menjadi bagian dari pola default, tetapi untuk orang yang memiliki pola khusus, hal itu mungkin memperlambat segalanya?
Ya, akan ideal jika, setidaknya dalam mode modul ES, .mjs hanya berfungsi, tanpa harus menambahkan moduleFileExtensions atau memodifikasi testMatch default.
Akan lebih baik jika saya dapat mengecualikan file .js; ketika saya mencoba itu saya dapatkan
Validation Error:
moduleFileExtensions must include 'js':
but instead received:
["mjs"]
Please change your configuration to include 'js'.
Saya bertanya-tanya apakah masuk akal untuk memiliki beberapa "mode ESM" yang akan menambahkan ekstensi file node esm dan juga membantu kompilasi-ke-js menggunakan esm untuk ikut serta (#9860).
Tanpa js
beberapa hal rusak secara internal yang kami muat di dalam kotak pasir (karena menggunakan implementasi require
dll). Kami mungkin harus memperbaikinya sehingga pengguna tidak dapat merusak kami.
Mengenai perlambatan, itu sudah cukup lambat pada proyek-proyek besar, tetapi saya tidak tahu bahwa jumlah ekstensi berdampak sebesar itu. Tapi saya setuju mjs dan cjs harus ditambahkan sebagai default. Menentukan moduleFileExtensions: ['js']
akan mengesampingkan default dan mempercepatnya, bukan? Jadi mungkin hanya mendokumentasikannya sebagai tweak kinerja.
Terima kasih untuk semua pekerjaan ini! Hal ini tentu menakjubkan. Saya mengikuti 3 langkah ( "type": "module"
pada package.json saya, "testEnvironment": "jest-environment-node"
dalam konfigurasi lelucon saya dan --experimental-vm-modules
pada CLI) dan tampaknya juga berfungsi dengan baik
Tapi kemudian saya mencoba membaca dan menggunakan import.meta
seperti yang dijelaskan dalam dokumen Node.js (dan yang tampaknya sudah diterapkan dilihat dari kotak centang) untuk membuat __dirname
, tetapi sepertinya import.meta
gagal:
console.log(import.meta);
SyntaxError: [PATH]/files.test.js: Support for the experimental syntax 'importMeta' isn't currently enabled (31:20):
Add @babel/plugin-syntax-import-meta (https://git.io/vbKK6) to the 'plugins' section of your Babel config to enable parsing.
Saya tidak punya babel dan saya pikir babel tertinggal dengan pekerjaan ini. Saya akan kembali untuk melaporkan jika saya dapat memperbaikinya tanpa menginstal babel.
Node.js v14.3.0, Jest v25.5.4
Saya menemukan solusi untuk saat ini. Karena saya menjalankan skrip dari direktori yang sama tempat file saya berada di library saya , saya hanya dapat melakukan:
const __dirname = process.cwd();
const __filename = __dirname + "/files.test.js";
Saya akan mengikuti repo ini jika ada pembaruan, sekali lagi terima kasih telah melakukan ini!
Anda harus secara eksplisit memilih keluar dari Babel dengan menggunakan transform: {}
sebagai konfigurasi
@SimenB Saya dapat mengonfirmasi bahwa menambahkan transform: {}
berhasil, terima kasih! Saya salah memahami poin itu sebagai "jangan tambahkan transformasi" dan bukan sebagai "ambil transformasi" sebagaimana dimaksud.
BTW, pengujian telah berubah dari 2,4 detik menjadi hanya 1,3 detik dan mereka secara konsisten merasa lebih cepat.
Node 12 telah dirilis dengan ESM yang tidak ditandai (https://nodejs.org/en/blog/release/v12.17.0/). Seperti yang dicatat dalam OP, penggunaan APIs Jest _not_ unflagged
@SimenB Saya membahas utas ini beberapa kali tetapi saya masih macet (menggunakan simpul 12.17).
Saat menjalankan Jest 26.0.1 saya mendapatkan kesalahan ini:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /app/tests/setup.js
require() of ES modules is not supported.
require() of /app/tests/setup.js from /app/node_modules/@jest/transform/build/ScriptTransformer.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename setup.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /app/package.json.
Saya memiliki transform: {},
dan berjalan dengan node --experimental-vm-modules node_modules/jest/bin/jest.js
.
Apa yang saya lewatkan?
@aldarund tidak yakin, bisakah Anda mengumpulkan reproduksi minimal?
@SimenB inilah repo minimal untuk ditiru, jalankan saja yarn test
https://github.com/aledalgrande/jest-example - Saya sudah mencoba dengan Node 13/14 dan hasilnya sama. Tampak bagi saya bahwa alur untuk pengaturan global belum diperbarui agar berfungsi dengan ESM.
juga, kamu menyebut orang lain
~Tidak @simenB , tetapi @aledalgrande Anda tampaknya memiliki segalanya yang benar di sini dari apa yang saya coba, lihat proyek saya sepenuhnya berjalan di ESM untuk perbandingan (konfigurasi lelucon di package.json
).~
~Untuk men-debug-nya jika memungkinkan, saya sarankan untuk menyederhanakan konfigurasi lelucon Anda menjadi _only_ memiliki dua properti yang relevan, bahkan mungkin di package.json
terlebih dahulu. Kemudian tambahkan setiap properti lain yang saat ini Anda miliki untuk melihat mana yang berfungsi/tidak berfungsi.~
Ah komentar kedua menyebutkan globalSetup
dan bukan tes normal, nvm komentar saya kalau begitu. Jika saya menghapus kunci globalSetup
di Jest, maka tes berjalan seperti yang diharapkan dalam contoh itu, tetapi kunci globalSetup
tidak berfungsi seperti yang Anda katakan.
Aha, saya sudah lupa tentang penyiapan dan pembongkaran global. Bisa diperbaiki 👍
Hai @SimenB , saya lagi. Apakah ekspor bernama didukung? Dengan Node.js saya dapat mengimpor dan menggunakan paket seperti ini:
import { customAlphabet } from "nanoid";
Namun, ketika mencoba melakukan tes, kode yang sama memberikan kesalahan ini:
SyntaxError: The requested module 'nanoid' does not provide an export named 'customAlphabet'
Untuk pengujian, saya dapat mengubah kode menjadi ini dan berfungsi:
import nanoid from "nanoid";
const { customAlphabet } = nanoid;
Tetapi kemudian versi Node.js berhenti berfungsi karena sebenarnya tidak ada olahraga default (tetapi untuk beberapa alasan ekspor default berfungsi dengan Jest):
SyntaxError: The requested module 'nanoid' does not provide an export named 'default'
Kode yang diterbitkan (repo tampaknya sedang berubah sekarang) nanoid
berakhir seperti ini, tanpa ekspor default:
export { nanoid, customAlphabet, customRandom, urlAlphabet, random }
Jest hanya menggunakan titik masuk "utama". "ekspor" belum dipertimbangkan. Anda cukup mengimpor versi commonjs yang hanya memiliki ekspor default.
Ah, begitu, package.json
sepertinya menyertakan ini:
"main": "index.cjs",
"module": "index.js",
"exports": {
"./package.json": "./package.json",
".": {
"require": "./index.cjs",
"import": "./index.js",
"browser": "./index.browser.js"
},
...
}
...
Jadi mungkin Node.js menemukan versi modul, sementara Jest menggunakan versi CommonJS yang tidak memiliki nama ekspor, bukan?
Saya akan menunggu sampai Package Exports
diperiksa dan kemudian mengujinya, terima kasih untuk semua pekerjaan lagi! Menandai 2 komentar ini sebagai diselesaikan sampai saat itu. Tes yang saya maksud adalah yang ini .
Saya meninjau kembali ini untuk melihat cara kerjanya - ditingkatkan ke Jest 26.0.1 dan node 14.4. Setel package.json ke tipe modul, setel transform ke {}
, env ke jest-environment-node
dan jalankan dengan node --experimental-vm-modules
. Sekarang saya mendapatkan kesalahan baru ini:
ES Modules are only supported if your test environment has the `getVmContext` function
Saya tidak dapat menemukan info tentang ini kecuali changelog dari Jest yang mengatakan getVmContext
telah ditambahkan beberapa waktu lalu.
Ada ide?
Bisakah Anda membagikan bagian yang relevan dari package.json
@cyberwombat ? Termasuk skrip peluncuran yang Anda gunakan untuk Jest.
Untuk referensi, ini adalah tampilan saya di proyek yang sedang berjalan :
{
...
"type": "module",
"scripts": {
...
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
},
"jest": {
"transform": {},
"testEnvironment": "jest-environment-node"
},
...
Kemudian luncurkan dengan npm test
@franciscop Milik saya pada dasarnya sama. Simpul 14.4.0. Aku bisa menjalankan milikmu dengan baik. Saya akan menyelami hal-hal untuk melihat perbedaannya.
package.json
{
"type": "module",
"devDependencies": {
"jest": "^26.0.1",
},
}
jest.config.js
export default {
testEnvironment: 'jest-environment-node',
setupFilesAfterEnv: ['./test/bootstrap.js'],
testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/config/', '/<rootDir>/src/'],
testRegex: '(\\.|/)(test|spec)\\.[jt]sx?$',
transform: {
// '^.+\\.jsx?$': 'babel-jest' // esm someday
},
transformIgnorePatterns: [],
modulePaths: [
'<rootDir>/test',
'<rootDir>/src',
'<rootDir>'
]
}
Naskah:
node --experimental-vm-modules node_modules/jest/bin/jest.js
Tidak yakin, tapi saya akan mencoba untuk bekerja sebaliknya. Hapus semuanya kecuali transform: {}
dan testEnvironment: 'jest-environment-node'
, dan mulai tambahkan setiap opsi hingga Anda melihat mana yang memicu kesalahan sebelumnya. Saya secara khusus menduga transformIgnorePatterns
_might_ bertentangan dengan transform
, tetapi saya tidak begitu akrab dengan opsi lelucon.
Halo semuanya! Saya mengalami beberapa masalah saat menggunakan Jest untuk menguji aplikasi Express. Lebih detail di sini . Tidak yakin apakah itu berguna untuk apa yang Anda lakukan/lacak di sini :roll_eyes:
@ x80486 Saya mengalami masalah yang sama persis kemarin . Saya telah menjawab di StackOverflow dengan penjelasan yang lebih panjang dari pemahaman saya.
Sunting: Saya menyembunyikan komentar saya sebelumnya karena tampaknya mungkin relevan, "exports"
tampaknya populer, sangat mungkin dari artikel ini tentang paket hibrida .
exports
dilacak di #9771
@franciscop ok masalah terpecahkan - ternyata ada konflik dalam paket - saya telah menginstal serverless-bundle
yang menyebabkan ES Modules are only supported if your test environment has the
getVmContext function
kesalahan. Saya tidak yakin mengapa - saya akan menganggap menginstalnya tidak akan menyebabkan konflik berjalan dengan bercanda tetapi ternyata memang demikian.
@franciscop Saya pikir alasan mengapa masalah terkait pkg.exports
mulai muncul sekarang adalah karena fitur itu tidak ditandai di Node.js 14.x
dan beberapa pengelola paket (seperti saya untuk uuid
) dimulai menambahkan bidang pkg.exports
. Jadi, sementara Anda memerlukan tanda baris perintah untuk mengaktifkan fitur itu di Node.js 12.x
Anda mendapatkan perilaku itu secara default sekarang.
Butuh beberapa saat bagi seluruh ekosistem untuk beradaptasi, jadi terima kasih telah melaporkan masalah seputar topik itu!
Bagi mereka yang memposting tentang exports
, jika telah hilang di utas panjang masalah ini, masalah tertutup saya tentangnya (https://github.com/facebook/jest/issues/9565) memiliki contoh dari solusi moduleNameMapper
di dalamnya.
Masalah globalSetup
dilaporkan pada bulan Mei kemungkinan masih ada (Jest 26.1.0)? Mendapatkan kesalahan yang sama seperti pada contoh repo @aledalgrande menyediakan:
$ git clone [email protected]:aledalgrande/jest-example.git
$ cd jest-example
$ npm test
> @ test /Users/asko/Temp/jest-example
> node --experimental-vm-modules node_modules/jest/bin/jest.js --config=./jest.config.js
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/asko/Temp/jest-example/tests/setup.js
require() of ES modules is not supported.
require() of /Users/asko/Temp/jest-example/tests/setup.js from /Users/asko/Temp/jest-example/node_modules/@jest/transform/build/ScriptTransformer.js
Tidak terburu-buru. Memeriksa CHANGELOG
dan tidak menyebutkan perbaikan untuk globalSetup/globalTeardown dengan ES6.
Node.js 14.4.0, Bercanda 26.1.0
Pembaruan (13-Agustus-20):
Masih tidak mungkin, Node.js 14.7.0, Jest 26.4.0
Pendapat sampingan tetapi apakah masalah ini harus menjadi masalah yang disematkan karena itu fokus untuk lelucon saat ini?
Adakah pemikiran tentang apa yang perlu dilakukan untuk mengkonsumsi reporter uji yang ditulis dalam modul ES?...
dengan versi lelucon terbaru, saya mendapatkan kesalahan yang pada dasarnya mengatakan testScheduler mengharapkan reporter khusus dalam format commonjs.untuk melihat kesalahan
~/projects/esw-ts/lib/dist/test/testReporter.js:1
impor os dari 'os';
^^^^^^
SyntaxError: Tidak dapat menggunakan pernyataan impor di luar modul
di wrapSafe (internal/modules/cjs/loader.js:1116:16)
di Module._compile (internal/modules/cjs/loader.js:1164:27)
di Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
di Module.load (internal/modules/cjs/loader.js:1049:32)
di Function.Module._load (internal/modules/cjs/loader.js:937:14)
di Module.require (internal/modules/cjs/loader.js:1089:19)
di membutuhkan (internal/modules/cjs/helpers.js:73:18)
di /Users/manish.gowardipe/Desktop/projects/esw-ts/lib/node_modules/@jest/core/build/TestScheduler.js:418:65
di Array.forEach (
di TestScheduler._addCustomReporters (/Users/manish.gowardipe/Desktop/projects/esw-ts/lib/node_modules/@jest/core/build/TestScheduler.js:411:15)
Hai, saya ingin menguji dukungan Asli untuk Modul ES di proyek kecil saya, tetapi saya baru mengenal NodeJS dan saya tersesat dalam Masalah ini, saya mohon bimbingannya.
node --version
: v14.5.0yarn jest --version
: 26.1.0package.json
{
"jest": {
"transform": {},
"testEnvironment": "jest-environment-node"
}
}
markov.test.js
const fs = require("fs");
const Markov = require("./markov.mjs");
// import fs from "fs";
// import Markov from "./markov.mjs";
const file = fs.readFileSync("text.txt", "utf8");
const markov = new Markov(file.toString());
test("Generates sentence with especified words", () => {
expect(markov.makeSentence(8).length).toBe(8);
});
Saya menjalankan yarn jest .
dan itu memberi saya kesalahan ini:
Saya mencoba dengan node node_modules/jest/bin/jest.js .
dan itu memberi saya kesalahan yang sama.
@pepetorres1998 Utas ini tentang menjalankan Jest dengan modul esm asli yang melibatkan menjalankan sesuatu dengan flag/opsi tertentu - lihat komentar di atas untuk mengetahui apa yang harus dilakukan (dan atur "ketik": "modul" di package.json). Sejujurnya meskipun pada titik ini belum cukup siap untuk prime time jadi jika Anda membutuhkan proyek Anda untuk bekerja, saya mungkin tetap menggunakan Babel. Ada sejumlah masalah yang tidak dicentang yang merupakan penghenti pertunjukan nyata. Saya dengan gembira mencoba untuk beralih beberapa minggu yang lalu dan kembali menangis ke Babel.
Apakah ada orang lain yang mendapatkan ReferenceError: jest is not defined
ketika mencoba melakukan hal-hal seperti jest.setTimeout(...)
dalam file pengujian dengan pengaturan ini? Mencoba mencari tahu apakah ini terkait dengan lingkungan modul es, versi simpul, versi lelucon, atau kombinasi dari hal-hal itu. (Saat ini menggunakan node v14.5.0, jest 26.1.0, lingkungan jest-environment-node)
EDIT
Saya sekarang melihat kotak centang yang tidak dicentang dalam deskripsi masalah untuk properti 'global' lelucon. 🙃
@bdentino Saya pikir Anda dapat mencoba mengimpornya secara eksplisit import {jest} from '@jest/globals';
25.4.0 telah dirilis dengan dukungan pertama. Selain #9772 yang disebutkan di atas, saya juga menyertakan #9842. Dalam _theory_ pencampuran CJS dan ESM harus bekerja dengan benar sekarang (🤞).
Satu fitur utama yang hilang adalah mendukung objek
jest
. Saya belum memutuskan apakah kita harus tetap menggunakanimport.meta
atau meminta orang untuk mengimpornya melaluiimport {jest} from '@jest/globals'
. Umpan balik dihargai!Saya belum menulis dokumen untuk ini, tetapi untuk mengaktifkannya Anda perlu melakukan 3 hal
- pastikan Anda tidak menjalankan transformasi diri
import
pernyataan (settransform: {}
di config atau memastikanbabel
tidak mengubah file ke CJS, seperti menghindarimodules
opsi ke preset-env)- Jalankan
node@^12.16.0 || >=13.2.0
dengan flag--experimental-vm-modules
- Jalankan pengujian Anda dengan
jest-environment-node
ataujest-environment-jsdom-sixteen
Silakan mencobanya dan berikan umpan balik! Jika melaporkan bug, alangkah baiknya jika Anda juga dapat menyertakan cara menjalankan kode yang sama (dikurangi kode khusus pengujian apa pun) berjalan di Node.js. Saya telah membaca https://nodejs.org/api/esm.html _a lot_ selama beberapa minggu terakhir, tetapi saya mungkin melewatkan sesuatu.
@SimenB
Utas ini menjadi sangat besar, dan saya pikir mereka yang ingin memulai dengan bercanda / menggunakan modul ES - akan kesulitan menemukan dan memahami pedoman dasar untuk mulai melakukannya.
Apakah ada penjelasan formal dalam dokumen tentang menambahkan lelucon ke proyek modul ES (atau 'mulai cepat')?
@aldeed Mengenai masalah Anda dengan modul mengejek dari proyek yang sama, apakah Anda menemukan perbaikan? Saya mengalami masalah yang sama persis
(Btw, kami juga menggunakan reactioncommerce, jadi bersorak untuk itu haha)
@guilhermetelles tidak, dan itu dilacak di https://github.com/facebook/jest/issues/10025 sekarang.
Saya menggunakan Jest 26.1.0, node
versi 14.6.0 dengan --experimental-vm-modules
, tapi saya masih melihat ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING
saat menggunakan import()
di dalam CommonJS . Haruskah saya mencoba membuat repro minimal dan membuka masalah baru?
Selain itu, apakah ada cara mudah untuk yarn link
salinan paket jest
ke dalam proyek sekarang karena Jest menggunakan yarn berry? Saya ingin mencoba master
berjaga-jaga jika ini diterapkan oleh yang belum dirilis. Saya mencoba melakukan sesuatu seperti path/to/facebook/jest/.yarn/releases/yarn-sources.cjs link --all path/to/jest
, tetapi itu akan gagal. Menjalankan sesuatu seperti cd node_modules; for p in jest*; do if [[ -d path/to/jest/packages/$p ]]; then rm -rf $p; ln -s path/to/jest/packages/$p; fi; done
secara manual juga tidak berfungsi, saya tidak yakin mengapa.
@vvanpo import()
di CJS dikembalikan di Node, Anda dapat mengikuti https://github.com/nodejs/node/issues/31860
Untuk menjalankan lokal, saya biasanya hanya menghapus jest
dari proyek yang ingin saya uji dan lakukan ../jest/jest
. Berpotensi nose ../jest/packages/jest/bin/jest.js
. Pastikan untuk menjalankan yarn
dan yarn build:js
terlebih dahulu. Jika instruksi ini tidak berfungsi (saya menulis dari memori di telepon di pesawat) silakan buka masalah (atau PR) sehingga kami dapat menulis ini dengan benar ke dalam file CONTRIBUTING.md
Apakah Anda berencana untuk mendukung impor siklik?
Jika saya memiliki file uji dummy yang hanya mengimpor satu dari dua file yang hanya mengimpor satu sama lain, saya mendapatkan RangeError: Maximum call stack size exceeded
. Jika saya menghapus salah satu impor, tes lulus. Repo yang mereproduksi masalah .
Hai! Saya mengatur ini di proyek node kosong dan itu bekerja dengan sangat baik, namun dalam pengaturan produksi kami, saya mendapatkan pesan kesalahan berikut ketika saya mencoba menjalankan tes:
ES Modules are only supported if your test environment has the 'getVmContext' function
Saya melihat orang lain mengalami masalah dalam balasan sebelumnya (oleh @cyberwombat ), tetapi paket yang mereka temukan sebagai pelakunya tidak ada dalam file package.json
. Bagaimana cara menyimpulkan paket (atau pengaturan) yang menyebabkan masalah? Saya telah mencoba secara sistematis menghapus setiap pengaturan lelucon yang tidak diperlukan untuk membuat ini berhasil, tetapi saya tidak berhasil.
UPDATE : Saya telah berhasil membuat kemajuan dengan membuat sedikit perubahan pada jest-runtime
. Saya menghentikan debugger di baris yang mencoba mengakses konteks VM dan sementara fungsinya benar-benar tidak ada, this.context
(yang seharusnya dikembalikan), jadi saya mengubah baris itu untuk mengakses properti secara langsung. Saya tahu ini mungkin tidak ideal, tapi mungkin @SimenB ini bisa memberi Anda gambaran tentang apa yang salah?
Terima kasih sebelumnya atas bantuan apa pun
Apakah Anda berencana untuk mendukung impor siklik?
Pastinya! Bisakah Anda membuka masalah terpisah?
@zsombro sepertinya Anda menjalankan beberapa versi lama dari lingkungan pengujian. Jika Anda menjalankan jest --show-config
, apa yang ditampilkan oleh testEnvironment
?
sepertinya Anda menjalankan beberapa versi lama dari lingkungan pengujian. Jika Anda menjalankan
jest --show-config
, apa yang ditampilkan olehtestEnvironment
?
@SimenB dikatakan sebagai berikut:
"testEnvironment": "/Users/zberki/git/project-name/node_modules/jest-environment-node/build/index.js",
"testEnvironmentOptions": {},
Saya baru saja mengaturnya ke jest-environment-node
berdasarkan instruksi Anda
Sebelum saya memulai proses ini, saya memutakhirkan lelucon menggunakan yarn add jest@latest
. Apakah saya harus memutakhirkan lingkungan secara terpisah?
UPDATE: Ternyata saya harus melakukannya. Saya menghapus node_modules
dan yarn.lock
untuk melakukan instalasi bersih dan masih tidak berhasil. Namun, jika saya menambahkannya secara manual dengan menggunakan yarn add -D jest-environment-node
sepertinya berhasil. Apakah ada cara yang lebih baik untuk mengelola ini? Saya melakukan proyek pengujian minimalis sebelum melakukan ini pada basis kode kami dan saya tidak perlu melakukan ini
yarn list jest-environemnt-node
(atau npm list jest-environemnt-node
) mungkin akan mencantumkan beberapa, tebakan saya
├─ [email protected]
│ └─ [email protected]
└─ [email protected]
versi 26.2.0
mungkin yang saya instal secara manual (setidaknya berdasarkan package.json
, yang berarti jest-config
telah menginstal versi yang tampaknya sudah usang?
Anda memiliki sesuatu yang lain menarik dalam versi lama jest-config
( react-scripts
mungkin (bagian dari create-react-app
)?). Masalah ini bukan tempat untuk membahasnya, tho
Tidak dapat menggunakan modul ES di globalSetup
mulai terasa sakit.
Dua poin:
SAYA:
"testEnvironment": "jest-environment-node",
di jest.config.jsonimport { jest } from '@jest/globals';
mana pun lelucon digunakan--experimental-vm-modules
dengan menjalankannya dengan NODE_OPTIONS='--experimental-vm-modules' yarn jest
Dan crash pada kode berikut:
jest.mock('../../some/other/path', () => ({
someOtherMethod: jest.fn().mockImplementation(…),
}));
dengan kesalahan berikut (disingkat - perhatikan "Objek yang diizinkan"!):
ReferenceError: src/foo/bar.spec.js: The module factory of `jest.mock()` is not allowed to reference any out-of-scope variables.
Invalid variable access: jest
Allowed objects: Array, …, jest, …, unescape.
Note: This is a precaution to guard against uninitialized mock variables. If it is ensured that the mock is required lazily, variable names prefixed with `mock` (case insensitive) are permitted.
Saya tidak dapat menggunakan Babel, karena mem-parsing impor dengan tidak benar yang saya perbaiki untuk dijalankan di Node 14 tanpa Babel:
-import { map } from 'lodash';
+import lodash from 'lodash';
+const { map } = lodash;
Yang sayangnya tidak diurai dengan benar oleh @babel/preset-env
, menghasilkan TypeError: Cannot destructure property 'map' of '_lodash.default' as it is undefined.
.
Dapatkah seseorang tolong bantu saya mengatasi masalah ini?
Sunting: Sepertinya Anda _can_ menggunakan Jest+Babel pada kode asli yang kompatibel dengan modul ES menggunakan impor CommonJS dengan melakukan perbaikan yang benar-benar menjijikkan ini:
jest.mock('common-js-module', () => ({
__esModule: false,
...jest.requireActual('common-js-module'),
}));
Cara ini,
import lodash from 'lodash';
const { map } = lodash;
dikonsumsi dengan sempurna oleh Node 14, dan kode yang dihasilkan dari menjalankan Jest+Babel,
var _lodash = _interopRequireDefault(require("lodash"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const {
map
} = _lodash.default;
juga berjalan.
kami telah berhasil mengonversi semua tes lelucon kami untuk menggunakan dan mengimpor kode ES6 kami, tetapi kami terjebak pada beberapa paket: yaitu puppeteer
dan uuid
Aplikasi hanya berfungsi jika kita mengimpornya ke dalam objek (seperti import uuid from 'uuid'
), tetapi pengujian tidak akan berjalan seperti ini. Namun, jika kita mengganti impor ini dengan sintaks dekonstruksi (seperti import { v4 } from 'uuid'
, maka sebaliknya: pengujian berhasil, tetapi aplikasi mengeluarkan pengecualian.
awalnya, kami mengikuti panduan dan mematikan setiap transformasi, tetapi kami juga mencoba membuat ruang kerja benang tempat kami menginstal babel dengan konfigurasi simpul minimal, tetapi ini tidak menyelesaikan (atau memperburuk) masalah khusus ini
Namun, jika kita mengganti import ini dengan sintaks dekonstruksi (seperti import { v4 } from 'uuid', maka sebaliknya: pengujian berhasil, tetapi aplikasi mengeluarkan pengecualian.
Kedengarannya seperti aplikasi Anda dikompilasi ke CommonJS dan tidak menggunakan modul dalam praktiknya. Dari ESM "asli" import uuid from 'uuid'
seharusnya tidak berfungsi karena uuid
tidak memiliki ekspor default dan memperlihatkan build ESM untuk node .
Hai @SimenB , menurut Anda beberapa dokumentasi awal tentang ini akan menjadi ide yang bagus?
@grantcarthew pasti! Saya berharap saya dapat menghabiskan lebih banyak waktu untuk ini dan menstabilkannya untuk Jest 27, tetapi saya ragu saya akan dapat melakukannya. Tetapi menulis halaman dokumen tentang apa yang ada sekarang (dan itu eksperimental) terdengar seperti ide yang bagus
@SimenB Saya tidak tahu apa status masalah saat ini dan apakah Jest seharusnya sudah bekerja dengan kasus saya atau tidak, tetapi mungkin itu dapat membantu Anda entah bagaimana.
Saya mencoba memuat perpustakaan khusus esm (ekstensinya adalah cjs tetapi tipenya adalah modul dan simpul tampaknya baik-baik saja dengan itu) tetapi Jest gagal memuatnya dengan benar dengan kesalahan:
C:\dev\codemirror-next-repro-cra\test-in-jest-esm\node_modules\style-mod\dist\style-mod.cjs:15
export var StyleModule = function StyleModule(spec, options) {
Di sini masalah yang awalnya saya buka https://github.com/codemirror/codemirror.next/issues/310 . Dan repro untuk Jest + ESM gagal dengan node 14.13.1 https://github.com/dubzzz/codemirror-next-repro-cra/tree/main/test-in-jest-esm
@dubzzz Anda tidak dapat memiliki ESM dalam file cjs
. Node juga gagal
$ node node_modules/style-mod/dist/style-mod.cjs
(node:48829) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/simen/repos/codemirror-next-repro-cra/test-in-jest-esm/node_modules/style-mod/dist/style-mod.cjs:15
export var StyleModule = function StyleModule(spec, options) {
^^^^^^
SyntaxError: Unexpected token 'export'
at wrapSafe (internal/modules/cjs/loader.js:1172:16)
at Module._compile (internal/modules/cjs/loader.js:1220:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1277:10)
at Module.load (internal/modules/cjs/loader.js:1105:32)
at Function.Module._load (internal/modules/cjs/loader.js:967:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
at internal/main/run_main_module.js:17:47
Ups maaf, saya mencoba terlalu cepat di sisi simpul. @nicolo-ribaudo sudah memberi tahu penulis lib tentang masalah ini.
Benar-benar terima kasih banyak atas jawaban cepat Anda.
Saya membuka PR untuk beberapa (cukup banyak rintisan) dokumen di sini: #10611. Saya tidak repot-repot menyebutkan fitur/bug yang hilang karena saya pikir itu akan sulit untuk disinkronkan dengan kenyataan, dan melihat masalah github adalah pendekatan yang lebih baik karena mereka (semoga…) mutakhir.
@Pomax sebagai edisi baru, tolong
Saya baru saja membuka #10620 yang menambahkan dukungan untuk import()
dari CJS. Diminta beberapa kali seperti https://github.com/facebook/jest/issues/9430#issuecomment -626054595
Halo. Cukup sulit bagi saya untuk dengan cepat merangkul seluruh cerita di balik ESM dalam simpul/bercanda, jadi, mungkin, saya menanyakan sesuatu yang jelas atau sudah dijawab. Apakah saya memahami dengan benar bahwa kasus berikut ini belum didukung? Atau, saya harap, saya melakukan sesuatu dengan cara yang tidak benar? Saya mengalaminya seperti import x from 'x'
berfungsi, tetapi perusakan import { sub } from 'x'
tidak.
paket.json:
{
"name": "jest-uuid",
"version": "1.0.0",
"type": "module",
"scripts": {
"test": "node --experimental-vm-modules node_modules/.bin/jest"
},
"devDependencies": {
"jest": "26.5.2"
},
"dependencies": {
"uuid": "8.3.1"
}
}
f.spec.js
import { v4 } from 'uuid';
test('', () => {});
tes npm
> npm test
> [email protected] test /Users/igoro/p/tmp/jest-uuid
> node --experimental-vm-modules node_modules/.bin/jest
FAIL ./f.spec.js
● Test suite failed to run
SyntaxError: The requested module 'uuid' does not provide an export named 'v4'
at jasmine2 (node_modules/jest-jasmine2/build/index.js:228:5)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.879 s
Ran all test suites.
(node:94492) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
npm ERR! Test failed. See above for more details.
Anda sedang menunggu #9771. Sebelum itu, Jest tidak tahu aman untuk memuat uuid
sebagai ESM (atau lebih tepatnya, file mana yang akan dimuat pada titik mana ia akan mengetahui bahwa itu adalah ESM)
Apakah ini akan mengikuti konvensi Node sendiri, di mana CJS hanya dapat dimuat sebagai namespace, atau akankah ini "meningkatkan" dengan mengizinkan sintaks yang sebenarnya tidak berfungsi di Node itu sendiri? (misalnya Node tidak mengizinkan import { readdirSync } from "fs-extra"
karena itu adalah paket CJS, tetapi itu mengizinkan import fs from "fs-extra";
yang kemudian dapat dibongkar menggunakan const { readdirSync } = fs
).
(misalnya Node tidak mengizinkan import { spawn } dari "child_process" karena itu adalah paket CJS, tetapi mengizinkan import child_process dari "child_process"; yang kemudian dapat dibongkar menggunakan const { spawn } = child_process;).
Ini adalah contoh yang tidak menguntungkan karena node menganggap "child_process" sebagai modul "builtin" (dan bukan CJS), jadi ekspor bernama berfungsi. Nodejs terbaru juga menggunakan heuristik untuk membuat banyak ekspor bernama berfungsi untuk modul CJS. Itu mungkin bagian tersulit untuk ditiru.
contoh diperbarui untuk menggunakan fs-extra
sebagai gantinya. Tetapi jika ekspor bernama ada di peta jalan Node untuk mendapatkan jurusan ini atau berikutnya, maka Jest mendahului itu masuk akal.
Itu seharusnya sudah diimplementasikan - Modul inti simpul memperlihatkan ekspor bernama, CJS "normal" tidak.
Nodejs terbaru juga menggunakan heuristik untuk membuat banyak ekspor bernama berfungsi untuk modul CJS. Itu mungkin bagian tersulit untuk ditiru.
Apakah Anda memiliki tautan ke PR yang menerapkannya? Kita harus mencoba untuk menirunya setidaknya
PR ada di sini: https://github.com/nodejs/node/pull/35249
Heuristik di baliknya diterbitkan sebagai cjs-module-lexer
(https://github.com/guybedford/cjs-module-lexer) tetapi @guybedford mungkin tahu lebih banyak tentang potensi penyimpangan.
Baru saja melihat ini dan sepertinya fs-extra
menggunakan pola ekspor seperti:
module.exports = {
// Export promiseified graceful-fs:
...require('./fs'),
// Export extra methods:
...require('./copy-sync'),
...require('./copy'),
...require('./empty'),
...require('./ensure'),
...require('./json'),
...require('./mkdirs'),
...require('./move-sync'),
...require('./move'),
...require('./output'),
...require('./path-exists'),
...require('./remove')
}
Saat ini ini bukan kasus analisis ekspor ulang yang kami deteksi, tetapi dimungkinkan untuk menambahkan ke cjs-module-lexer jika ini akan menjadi kasus yang berguna untuk menangani deteksi ekspor bernama.
Terima kasih @jkrems & @guybedford! Saya sudah membuka PR sekarang menggunakan modul itu: #10673
Dukungan fs-extra persis yang dijelaskan di https://github.com/facebook/jest/issues/9430#issuecomment -713204282 sekarang diterapkan di [email protected] , pelacakan hulu di https://github. com/nodejs/node/pull/35745.
_Update: menguji build ini, ia mendeteksi dengan benar semua fungsi fs-extra, tetapi sayangnya tidak mendeteksi fungsi asli Node.js karena tidak dapat dianalisis secara statis karena diisi oleh for loop._
feat: mendukung ekspor bernama dari CJS seperti yang disebut impor ESM #10673
Saya pikir ESM asli hanya mendukung pengimporan exports
modul CommonJS sebagai default
?
@trusktr tidak lagi: https://github.com/nodejs/node/pull/35249
Halo. Cukup sulit bagi saya untuk dengan cepat merangkul seluruh cerita di balik ESM dalam simpul/bercanda, jadi, mungkin, saya menanyakan sesuatu yang jelas atau sudah dijawab. Apakah saya memahami dengan benar bahwa kasus berikut ini belum didukung? Atau, saya harap, saya melakukan sesuatu dengan cara yang tidak benar? Saya mengalaminya seperti
import x from 'x'
berfungsi, tetapi perusakanimport { sub } from 'x'
tidak....
impor { v4 } dari 'uuid';
Modul ESM tidak mendukung pengrusakan impor, meskipun sintaksnya terlihat seperti itu. Agar ini berfungsi, 'ekspor v4' diperlukan. 'ekspor default' tidak akan cocok.
https://kentcdodds.com/blog/ kesalahpahaman-es6-modules-upgrading-babel-tears-and-a-solution
@sdwlig uuid
menyediakan ekspor bernama dan tidak memiliki default. Seharusnya berfungsi tetapi memuat esm dari paket dengan bidang "ekspor" belum didukung oleh lelucon. Commonjs dimuat sebagai gantinya yang hanya tersedia melalui ekspor default.
https://github.com/uuidjs/uuid/blob/master/src/index.js
Bisakah kami menambahkan dukungan referensi sendiri paket (#10883) ke ini?
Komentar yang paling membantu
Saya telah mendapatkan dukungan yang sangat mendasar dengan #9772. Saya hanya menguji kasus yang paling sederhana, dan ada banyak batasan yang diketahui (terutama tidak ada dukungan objek
jest
dan semantik yang rusak saat mencampur CJS dan ESM), tetapi setidaknya itu _something_. Itu akan keluar di rilis Jest berikutnya (semoga segera, hanya diblokir oleh #9806)