Melihat dari dekat Modul ES (ESM)

npm adalah manajer paket untuk platform JavaScript node.js. Ini menempatkan modul sehingga node dapat menemukannya, dan mengelola konflik ketergantungan dengan cerdas.

npm dapat dikonfigurasi untuk mendukung berbagai kasus penggunaan untuk menerbitkan, menemukan, menginstal, dan mengembangkan program node. Ia memiliki daftar perintah yang kuat.

npm 8 dirilis pada 7 Oktober 2021. Pada artikel ini, kita melihat npm 8, dan memprediksi apa itu npm 9.

Apa yang Baru di npm 8?

Tidak ada yang baru di npm 8. Tujuan rilis ini adalah untuk menghentikan dukungan untuk versi node lama dan menghapus dukungan untuk require('npm'). Tidak ada perubahan besar lainnya. Lebih khusus lagi, ini adalah perubahan:

  • Jatuhkan dukungan untuk node 10 dan 11.
  • Naikkan plafon dukungan di node 12 dan 14 ke LTS (^12.13.0/^14.15.0).
  • Jatuhkan dukungan ke require('npm').
  • Perbarui beberapa dependensi karena dukungan node10 dan node 11 yang hilang.

Ini sederhana dan jelas.

Jika Anda ingin mengupgrade ke npm 8, pastikan node.js Anda telah diupgrade ke versi >=12.0.0. nvm adalah cara sederhana untuk mengelola versi untuk node dan npm.

Apa yang Mungkin Baru di npm 9?

Request for Comments (RFC) adalah dokumen formal yang dirancang oleh Internet Engineering Task Force (IETF) yang menjelaskan spesifikasi teknologi tertentu. npm 8 adalah RFC yang diratifikasi, saat ini merupakan standar formal.

RRFC dari npm 8 menyebutkan saran untuk meningkatkan versi yang didukung ke ^12.20.0 || ^14.13.1 || >=16.0.0, yang akan menjadi perpindahan ke versi node.js yang mendukung modul bergaya ESM. Karena tidak membuat npm 8, ini mungkin menjadi fitur di npm 9.

CJS vs ESM

Kita telah membahas format modul JavaScript, seperti CJS, AMD, UMD, ESM, System, dan IIFE.

CommonJS (CJS) adalah standar yang digunakan oleh node.js untuk merangkum JavaScript dalam modul. CJS menggunakan fungsi require() dan module.exports.

  • require() adalah fungsi yang dapat digunakan untuk mengimpor simbol ke cakupan saat ini dari modul lain. Pernyataan require dapat digunakan di mana saja dalam kode, dan modul yang dirujuk dimuat dan diproses secara sinkron.
  • module.exports adalah objek yang dikembalikan oleh modul saat ini ketika diperlukan di modul lain.

ES Modules (ESM) menjadi standar resmi yang digunakan dalam JavaScript sejak ES2015. Ini banyak digunakan dalam pengembangan klien JavaScript. Itu juga diadopsi oleh TypeScript yang merupakan superset dengan tipe tambahan. ESM menggunakan pernyataan import dan export untuk menangani modul.

  • Direktif statis import dapat digunakan untuk membawa modul ke dalam cakupan saat ini. dinamis import() tersedia sejak pernyataan ES2020 .import dapat digunakan di mana saja dalam kode. Karena imports dimuat secara asinkron, disarankan untuk meletakkannya di bagian atas file.
  • Di sisi lain, arahan export dapat digunakan untuk membuat item menjadi publik secara eksplisit.

CJS adalah default untuk node

Seperti yang telah kami sebutkan, CJS adalah default untuk node. Mengikuti langkah-langkah yang dijelaskan dalam aplikasi React siap produksi, kami menggunakan Buat Aplikasi React sebagai contoh untuk mengeksplorasi cara kerja server node.

npx create-react-app react-esm
cd react-esm

Jalankan perintah npm run build, dan direktori build yang dihasilkan berisi kode yang akan diterapkan.

Express adalah kerangka aplikasi web Node.js yang minimal dan fleksibel untuk aplikasi web dan seluler. Server ekspres adalah pilihan populer untuk menyebarkan build produksi.

Karena Express adalah bagian dari Aplikasi Create React, tidak perlu menginstalnya lagi.

Siapkan file konfigurasi untuk server Express di server/index.js:

Kode di atas jelas dalam format CJS dengan pernyataan require (baris 1 dan baris 4).

Jalur 2 membuat server Ekspres.

Baris 5–8 melayani halaman web produksi.

Baris 10–12 memulai server Express di port, 8080.

Jalankan node server, dan antarmuka pengguna dapat diakses di http://localhost:8080.

Atur simpul untuk menjalankan ESM

Sekarang kita ubah kodenya menjadi import, bukan require().

Jalankan node server, dan kami melihat kesalahan berikut:

Peringatan pada baris 10 memberikan dua solusi:

  • Setel "type": "module" di package.json.
  • Ubah server/index.js menjadi server/index.mjs, dan jalankan node server/index.mjs.

Kedua solusi tersebut berhasil. Berikut adalah package.json yang dimodifikasi (baris 5):

Untuk file tanpa ekstensi, file tersebut diperlakukan sebagai modul CJS jika tidak ada "type", atau jenisnya disetel ke "commonjs" di induk package.json. Mereka diperlakukan sebagai modul ES, jika "type" diatur ke "module".

Selain itu, file yang diakhiri dengan .cjs diperlakukan sebagai modul CJS, dan file yang diakhiri dengan .mjs diperlakukan sebagai modul ES.

Kami menetapkan "type" ke "module", sekarang node memperlakukan file sebagai modul ES. Jalankan node server lagi:

Ia tidak mengeluh lagi tentang import. Tapi, apa masalahnya __dirname?

__dirname adalah variabel CJS, yang tidak tersedia di modul ES. Itu dapat direplikasi melalui import.meta.url.

Objek import.meta memperlihatkan metadata spesifik konteks ke modul JavaScript. Ini berisi informasi tentang modul, seperti URL modul.

Ubah server/index.js sebagai berikut:

Jalankan node server, dan modul ES berfungsi dengan sempurna.

Alternatifnya, kita dapat memiliki awalan node:, yang dalam hal ini akan melewati cache yang diperlukan. Misalnya, "node:path" (baris 4) dan "node:url" (baris 5) akan selalu mengembalikan modul "path" dan "url" bawaan.

Kami telah melihat beberapa perbedaan antara CJS dan ESM. Berikut daftar cara convert file CJS ke modul ES:

  • Tidak require, exports atau module.exports—Gunakan import atau export sebagai gantinya.
  • Tidak ada __filename atau __dirname—Gunakan import.meta.url sebagai gantinya.
  • Tidak Ada Pemuatan Modul JSON — Gunakan import.meta.url dengan fs sebagai gantinya.
  • Tidak Ada Pemuatan Modul Asli — Gunakan module.createRequire() atau process.dlopen sebagai gantinya.
  • Tidak require.resolve—Gunakan new URL('./local', import.meta.url) sebagai gantinya.
  • Tidak NODE_PATH — Gunakan symlink sebagai gantinya.
  • Tidak require.extensions — Jangan gunakan.
  • Tidak require.cache — Jangan gunakan.

Kesimpulan

npm 8 menghentikan dukungan untuk node 10 dan 11.

Apa pendapat Anda tentang npm 9? Haruskah ia menghentikan dukungan untuk versi node yang tidak mendukung modul ES?

Setelah berjuang dengan sintaksis yang berbeda untuk klien dan server JavaScript, bukankah menarik melihat ESM memperoleh aliran untuk digunakan bagi klien dan server?

Waktunya telah tiba untuk menggunakan modul bergaya ESM dalam aplikasi node.

Terima kasih sudah membaca. Saya harap ini bermanfaat. Jika Anda tertarik, lihat artikel Medium saya yang lain.