NodeJS berencana untuk mendukung modul impor / ekspor es6 (es2015)

275

Saya sudah mencari di seluruh internet tanpa jawaban yang jelas untuk ini.

Saat ini NodeJS hanya menggunakan sintaks CommonJS untuk memuat modul, dan jika Anda benar-benar ingin menggunakan sintaksis modul ES2015 standar, Anda harus mengubahnya terlebih dahulu atau menggunakan pemuat modul eksternal saat runtime.

Saat ini saya tidak terlalu positif untuk menggunakan salah satu dari kedua metode tersebut, apakah pengelola NodeJS bahkan berencana untuk mendukung modul ES2015 atau tidak? Saya belum menemukan petunjuk sama sekali tentang ini.

Saat ini NodeJS 6.x mengklaim mendukung 96% dari fitur ES2015, tetapi tidak ada referensi ke modul ( tautan dukungan NodeJS ES2105 ).

Apakah Anda tahu jika NodeJS akan mendukung modul ini di luar kotak, dalam waktu dekat?

Zorgatone
sumber
2
Untuk Googling node es2015 modules, perlihatkan berikut ini sebagai salah satu hasil teratas: github.com/nodejs/node/wiki/ES6-Module-Detection-in-Node .
Felix Kling
6
Secara pribadi saya akan memilih untuk menutup pertanyaan ini sebagai "terlalu lokal", tetapi alasan dekat itu tidak ada lagi. Katakanlah Node berhasil mengimplementasikan modul ES6 besok. Apakah Anda akan menghapus pertanyaan Anda karena itu tidak relevan lagi? Atau setidaknya Anda akan memperbaruinya? Saya tidak berpikir pertanyaan cocok untuk SO jika Anda sudah tahu bahwa itu akan usang atau perlu diperbarui "segera". Tapi itu hanya pendapat saya dan tampaknya ada orang lain yang berpikir sebaliknya, yang ok untuk saya :) (fwiw, pertanyaannya tentu saja penting dan menarik)
Felix Kling
2
Saya berharap ada tempat di Stack Universe untuk pertanyaan seperti ini. Secara teknis mungkin tidak cocok di sini, tetapi saya tidak tahu bahwa saya setuju bahwa itu benar-benar "berdasarkan pendapat" juga. OP sedang mencari jawaban spesifik untuk pertanyaan tertentu, tetapi salah satu yang akan (pada titik tertentu) ketinggalan jaman.
Wonko the Sane
5
Ungkapan alternatif dari pertanyaan ini: "Apa yang dimaksud dengan status node.js untuk modul ES6?" Jawaban atas banyak pertanyaan SO berubah seiring waktu seiring berkembangnya teknologi. Saya juga kesulitan menemukan jawabannya sampai saya mendarat di sini.
Joe Lapp
4
@FelixKling saya kira Anda ingin menutup pertanyaan ini akan menjadi keputusan yang sangat salah karena ini adalah masalah yang 211 orang sejauh ini cukup bermasalah untuk memilih.
Muhammad Umer

Jawaban:

302

Simpul 13.2.0 & Di Atas

NodeJS 13.2.0 sekarang mendukung Modul ES tanpa flag 🎉 Namun, implementasi masih ditandai sebagai eksperimental jadi gunakan dalam produksi dengan hati-hati.

Untuk mengaktifkan dukungan ESM di 13.2.0, tambahkan yang berikut ke Anda package.json:

{
  "type": "module"
}

Semua .js, .mjs(atau file tanpa ekstensi) akan diperlakukan sebagai ESM.

Ada sejumlah opsi berbeda selain seluruh package.jsonkeikutsertaan, yang semuanya dirinci dalam Dokumentasi untuk 13.2.0 .

Simpul 13.1.0 & Di Bawah

Mereka yang masih menggunakan versi Node yang lebih lama mungkin ingin mencoba esm module loader, yang merupakan implementasi siap dari Spesifikasi Modul ES untuk NodeJS:

node -r esm main.js

Pembaruan Lengkap ...

23 April 2019

Seorang PR baru-baru ini mendarat untuk mengubah cara Modul ES terdeteksi: https://github.com/nodejs/node/pull/26745

Itu masih di belakang --experimental-modulesbendera, tetapi ada perubahan besar dalam cara modul dapat dimuat:

  • package.typeyang bisa berupa moduleataucommonjs
    • type: "commonjs":
      • .js diurai sebagai commonjs
      • default untuk titik masuk tanpa ekstensi adalah commonjs
    • type: "module":
      • .js diuraikan sebagai esm
      • tidak mendukung memuat JSON atau Modul Asli secara default
      • default untuk titik masuk tanpa ekstensi adalah ESM
  • --type=[mode]untuk membiarkan Anda mengatur jenisnya pada titik masuk. Akan mengganti package.typeuntuk titik masuk.
  • Ekstensi file baru .cjs.
    • ini khusus untuk mendukung pengimporan commonjs dalam modulemode.
    • ini hanya di esm loader, loader commonjs tetap tidak tersentuh, tetapi ekstensi akan berfungsi di loader lama jika Anda menggunakan path file lengkap.
  • --es-module-specifier-resolution=[type]
    • pilihannya adalah explicit(standar) dannode
    • secara default loader kami tidak akan mengizinkan ekstensi opsional di impor, jalur untuk modul harus menyertakan ekstensi jika ada
    • secara default loader kami tidak akan memungkinkan untuk mengimpor direktori yang memiliki file indeks
    • pengembang dapat digunakan --es-module-specifier-resolution=nodeuntuk mengaktifkan algoritma resolusi specifier commonjs
    • Ini bukan "fitur" melainkan implementasi untuk eksperimen. Diharapkan untuk berubah sebelum bendera dihapus
  • --experimental-json-loader
    • satu-satunya cara untuk mengimpor json ketika "type": "module"
    • ketika memungkinkan semua import 'thing.json'akan melalui loader eksperimental independen dari mode
    • berdasarkan whatwg / html # 4315
  • Anda dapat menggunakan package.mainuntuk mengatur titik masuk untuk modul
    • ekstensi file yang digunakan di utama akan diselesaikan berdasarkan pada jenis modul

17 Januari 2019

Node 11.6.0 masih mencantumkan Modul ES sebagai percobaan, di belakang sebuah bendera.

13 September 2017

NodeJS 8.5.0 telah dirilis dengan dukungan untuk file mjs di belakang sebuah flag:

node --experimental-modules index.mjs

Rencana untuk ini adalah menghapus bendera untuk rilis LTS v10.0.

- Informasi yang Diperpanjang. Tetap di sini untuk keperluan sejarah -

8 September 2017

Cabang utama NodeJS telah diperbarui dengan dukungan awal untuk modul ESM:
https://github.com/nodejs/node/commit/c8a389e19f172edbada83f59944cad7cc802d9d5

Ini harus tersedia pada malam terakhir (ini dapat diinstal melalui nvm untuk berjalan di samping instalasi Anda yang ada):
https://nodejs.org/download/nightly/

Dan diaktifkan di belakang --experimental-modulesbendera:

package.json

{
  "name": "testing-mjs",
  "version": "1.0.0",
  "description": "",
  "main": "index.mjs" <-- Set this to be an mjs file
}

Lalu lari:

node --experimental-modules .

Februari 2017:

https://medium.com/@jasnell/an-update-on-es6-modules-in-node-js-42c958b890c#.6ye7mtn37

Orang-orang NodeJS telah memutuskan bahwa solusi yang paling buruk adalah dengan menggunakan .mjsekstensi file. Keuntungan dari ini adalah:

Dengan kata lain, diberikan dua file foo.jsdan bar.mjs, menggunakan import * from 'foo'akan memperlakukan foo.jssebagai CommonJS sementara import * from 'bar' akan memperlakukan bar.mjssebagai Modul ES6

Dan untuk garis waktu ...

Pada titik saat ini, masih ada sejumlah spesifikasi dan masalah implementasi yang perlu terjadi pada sisi ES6 dan Mesin Virtual sebelum Node.js bahkan dapat mulai mengerjakan implementasi yang didukung dari modul ES6. Pekerjaan sedang berlangsung tetapi akan memakan waktu - Saat ini kami sedang mencari di sekitar setahun setidaknya .

Oktober 2016:

Salah satu pengembang di Node.JS baru-baru ini menghadiri pertemuan TC-39 dan menulis artikel hebat tentang blocker untuk diterapkan untuk Node.JS:

https://hackernoon.com/node-js-tc-39-and-modules-a1118aecf95e

Dasar pengambilan dari itu adalah:

  • Modul ES dianalisis secara statis, CommonJS dievaluasi
  • Modul CommonJS memungkinkan ekspor patch-monyet, Modul ES saat ini tidak
  • Sulit untuk mendeteksi apa itu Modul ES dan apa yang CommonJS tanpa beberapa bentuk input pengguna, tetapi mereka berusaha.
  • *.mjs tampaknya solusi yang paling mungkin, kecuali mereka dapat secara akurat mendeteksi Modul ES tanpa input pengguna

- Jawaban Asli -

Ini telah menjadi kentang panas selama beberapa waktu. Intinya adalah bahwa ya, Node pada akhirnya akan mendukung sintaks ES2015 untuk mengimpor / mengekspor modul - kemungkinan besar ketika spesifikasi untuk memuat modul diselesaikan dan disepakati.

Berikut ini adalah ikhtisar yang baik tentang apa yang menahan NodeJS. Pada dasarnya, mereka perlu memastikan bahwa spesifikasi baru berfungsi untuk Node yang terutama bersyarat, pemuatan sinkron dan juga HTML yang terutama tidak sinkron.

Tidak ada yang tahu pasti sekarang, tapi saya membayangkan Node akan mendukung import/exportuntuk pembebanan statis, selain yang baru System.importuntuk pembebanan dinamis - sambil tetap menyimpan requirekode lawas.

Berikut adalah beberapa proposal tentang bagaimana Node dapat mencapai ini:

CodingIntrigue
sumber
38
Tentang .mjsekstensi: We have affectionately called these “Michael Jackson Script” files in the past. Kalau-kalau Anda mendengar seseorang berbicara tentang artis pop selama JS talk.
Jeewes
1
Saya tidak mengerti mengapa mengubah sintaks impor tidak cukup. Satu sintaks untuk mengimpor es (yang 'benar') dan satu untuk mengimpor cjs? Dengan kata lain, diberikan dua file foo.js dan bar.js, import * from 'foo'akan memperlakukan foo.js sebagai CommonJS import * as bar from 'bar'akan memperlakukan bar.js sebagai Modul ES6 Dapatkah seseorang menjelaskan?
Corey Alix
1
Sintaks @CoreyAlix umumnya tidak akan diubah untuk mendukung lingkungan. Ini benar-benar hanya mempengaruhi Node. Sintaksnya juga agak non-intuitif. Bagaimana cara mengakses ekspor di sintaks yang Anda ajukan?
CodingIntrigue
Agar lebih jelas, ini bukan proposal "saya", saya menyalin apa yang sudah dilakukan naskah. Untuk menjawab pertanyaan Anda, Anda mengakses ekspor dengan "bar": bar.foobar () impor {foo as Foo} dari "./foo" adalah mekanisme untuk mengidentifikasi modul ES6. var Foo = membutuhkan (“./ foo”) adalah mekanisme untuk mengidentifikasi modul CJS. Dalam naskah, keluaran commonjs terlihat seperti ini: var mod1_1 = membutuhkan ("./ mod1"); exports.mod1 = mod1; Output ES6 terlihat seperti ini: import {mod1} dari "./mod1"; export {mod1}
Corey Alix
1
Saya akan sangat menarik dalam pembaruan Node 10 untuk jawaban ini. Apakah fitur memotong, atau masih di belakang bendera?
dcorking