Node.js 13.2.0 dilengkapi dengan dukungan ECMAScript untuk modul yang dikenal dengan sintaksis impor dan ekspornya. Sebelumnya, fungsi ini berada di belakang --experimental-modules
, yang tidak lagi diperlukan. Namun, implementasinya masih eksperimental dan dapat berubah.
Dari penerjemah: fitur yang ditunggu-tunggu ini akhirnya akan memungkinkan kita untuk menggunakan sintaksis modular standar yang sudah tersedia di peramban modern, dan sekarang juga di Node.js tanpa flag dan transpiler
Aktivasi
Node.js akan memproses kode sebagai modul ES dalam kasus berikut:
- File dengan ekstensi
.mjs
- File dengan ekstensi
.js
atau tanpa ekstensi sama sekali, asalkan paket package.json
paling dekat dengannya berisi nilai "type": "module"
- Kode melewati argumen
—-eval
atau STDIN, bersama dengan —-input-type=module
Dalam semua kasus lain, kode tersebut akan dianggap sebagai CommonJS. Ini berlaku untuk file .js
tanpa "type": "module"
di package.json
terdekat dan kode yang melewati baris perintah tanpa menentukan --input-type
. Ini dilakukan untuk menjaga kompatibilitas ke belakang. Namun, karena kita sekarang memiliki dua jenis modul, CommonJS dan ES, akan lebih baik untuk menentukan jenis modul secara eksplisit.
Anda dapat secara eksplisit menandai kode Anda sebagai CommonJS dengan fitur-fitur berikut:
- File dengan ekstensi
.cjs
- File dengan ekstensi
.js
atau tanpa ekstensi sama sekali, dengan ketentuan bahwa paket parent terdekat. package.json
berisi nilai "type": "“commonjs”"
- Kode dikirimkan melalui argumen
--eval
atau STDIN dengan flag eksplisit --input-type=commonjs
Untuk mempelajari lebih lanjut tentang fitur-fitur ini, lihat bagian dokumentasi "Cakupan Paket dan Ekstensi File" dan --input-type
Impor dan ekspor sintaksis
Dalam konteks modul ES, Anda dapat menggunakan import
, menunjuk ke file Javascript lainnya. Mereka dapat ditentukan dalam salah satu format berikut:
- URL relatif:
"./file.mjs"
- URL absolut
file://
c file://
, misalnya, "file:///opt/app/file.mjs"
- Nama Paket:
"es-module-package"
- Path ke file di dalam paket:
"es-module-package/lib/file.mjs"
Dalam impor, Anda dapat menggunakan default ( import _ from "es-module-package"
) dan nilai-nilai yang disebut ( import { shuffle } from "es-module-package"
), serta mengimpor semuanya sebagai satu namespace ( import * as fs from "fs"
). Semua paket Node.js bawaan, seperti fs
atau path
, mendukung ketiga jenis impor.
Impor yang mengarah ke kode CommonJS (yaitu, semua JavaScript saat ini yang ditulis untuk Node.js require
module.exports
dan module.exports
) hanya dapat menggunakan opsi default ( import _ from "commonjs-package"
).
Mengimpor format file lain seperti JSON dan WASM tetap bersifat eksperimental, dan masing-masing memerlukan flag --experimental-json-modules
dan --experimental-wasm-modules
. Namun, Anda dapat mengunduh file-file ini menggunakan module.createRequire
API, yang tersedia tanpa flag tambahan.
Dalam modul ES Anda, Anda dapat menggunakan kata kunci ekspor untuk mengekspor nilai default dan bernama.
Ekspresi dinamis dengan import()
dapat digunakan untuk memuat modul ES baik dari kode CommonJS atau ES. Perhatikan bahwa import()
tidak mengembalikan modul tetapi janjinya (Janji).
import.meta.url
tersedia di modul, yang berisi URL absolut dari modul ES saat ini.
File dan bidang "ketik" baru di package.json
Tambahkan "type": "module"
ke package.json dari proyek Anda, dan Node.js akan mulai menganggap semua file .js
proyek Anda sebagai modul ES.
Jika beberapa file proyek Anda masih menggunakan CommonJS dan Anda tidak dapat memigrasi seluruh proyek sekaligus, Anda bisa menggunakan ekstensi .cjs
untuk kode ini, atau meletakkannya di direktori terpisah dan menambahkan package.json
berisi { "type": "commonjs" }
, yang memberi tahu Node.js bahwa itu harus diperlakukan sebagai CommonJS.
Untuk setiap file yang diunduh, Node.js akan melihat package.json
di direktori yang berisi itu, lalu naik satu tingkat, dan seterusnya hingga mencapai direktori root. Mekanisme ini mirip dengan cara Babel .babelrc
file Babel .babelrc
. Pendekatan ini memungkinkan Node.js untuk menggunakan package.json
sebagai sumber dari berbagai metadata tentang paket dan konfigurasi, mirip dengan cara kerjanya di Babel dan alat-alat lainnya.
Kami merekomendasikan bahwa semua pengembang paket menentukan bidang type
, bahkan jika commonjs
ditulis di commonjs
.
Poin entri paket dan bidang "ekspor" di package.json
Sekarang kami memiliki dua bidang untuk menentukan titik masuk ke dalam paket: main
dan exports
. Bidang main
didukung oleh semua versi Node.js, tetapi kemampuannya terbatas: dengan itu Anda hanya dapat menetapkan satu titik masuk utama dalam paket. Bidang exports
baru juga memungkinkan Anda untuk menentukan titik masuk utama, serta jalur tambahan. Ini memberikan enkapsulasi tambahan untuk paket-paket di mana hanya jalur exports
eksplisit yang tersedia untuk impor dari luar paket. exports
berlaku untuk kedua jenis modul, CommonJS dan ES, tidak peduli apakah mereka digunakan melalui permintaan atau import
.
Fungsi ini akan memungkinkan impor tipe pkg/feature
untuk menunjuk ke jalur nyata seperti ./node_modules/pkg/esm/feature.js
. Juga, Node.js akan melempar kesalahan jika impor merujuk ke pkg/esm/feature.js
yang tidak ditentukan dalam exports
.
Tambahan, masih eksperimental, fitur, ekspor bersyarat menyediakan kemampuan untuk mengekspor file yang berbeda untuk lingkungan yang berbeda. Ini akan memungkinkan paket untuk memberikan kode CommonJS untuk memanggil wajib require("pkg")
dan kode modul ES untuk diimpor melalui import "pkg"
, meskipun menulis paket seperti itu bukan tanpa masalah lain . Anda dapat mengaktifkan ekspor bersyarat dengan —-experimental-conditional-exports
.
Penggaruk utama dari modul baru
Ekstensi file yang diperlukan
Saat menggunakan impor, Anda harus menentukan ekstensi file. Saat mengimpor file indeks dari direktori, Anda juga harus menentukan path untuk file tersebut, yaitu, "./startup/index.js".
Perilaku ini bertepatan dengan bagaimana impor bekerja di browser ketika mengakses server biasa tanpa konfigurasi tambahan.
module.exports
, exports
, module.exports
, __filename
, __dirname
Nilai-nilai ini dari CommonJS tidak tersedia dalam konteks modul ES. Namun, require
dapat diimpor ke modul ES melalui module.createRequire()
. Setara dengan __filename
dan __dirname
dapat diperoleh dari import.meta.url
.
Membuat paket
Saat ini, kami menyarankan agar penulis paket menggunakan modul CommonJS atau ES sepenuhnya untuk proyek Node.js mereka. Kelompok kerja modul untuk Node.js terus mencari cara untuk meningkatkan dukungan untuk paket ganda, dengan CommonJS untuk pengguna lama dan modul ES untuk yang baru. Ekspor bersyarat sekarang eksperimental dan kami berharap untuk meluncurkan fungsionalitas ini atau alternatifnya pada akhir Januari 2020, atau bahkan lebih awal.
Untuk mempelajari lebih lanjut tentang ini, lihat contoh dan rekomendasi kami untuk membuat paket Modul CommonJS / ES ganda.
Apa yang akan terjadi selanjutnya?
Loader. Pekerjaan berlanjut pada API untuk menulis loader kustom, untuk mengimplementasikan transpirasi modul dalam runtime, mendefinisikan kembali jalur impor (paket atau file individual), dan menginstruksikan kode. API eksperimental, tersedia di bawah —-experimental-loader
, akan mengalami perubahan signifikan sebelum kami menghapusnya dari flag.
Paket modul Dual CommonJS / ES. Kami ingin memberikan cara standar untuk menerbitkan paket yang dapat digunakan baik melalui persyaratan di CommonJS maupun melalui import
dalam modul ES. Kami memiliki informasi lebih lanjut tentang ini dalam dokumentasi . Kami berencana untuk menyelesaikan pekerjaan dan menarik dari bendera pada akhir Januari 2020, jika tidak sebelumnya.
Itu saja! Kami berharap dukungan ECMAScript untuk modul membawa Node.js lebih dekat ke standar JavaScript dan membawa fitur baru untuk kompatibilitas di seluruh ekosistem JavaScript. Alur kerja untuk meningkatkan dukungan modul sedang dilakukan secara publik di sini: https://github.com/nodejs/modules .