NodeJS prevede di supportare i moduli es6 (es2015) di importazione / esportazione


275

Ho cercato su Internet senza una risposta chiara per questo.

Attualmente NodeJS utilizza solo la sintassi CommonJS per caricare i moduli e se si desidera veramente utilizzare la sintassi dei moduli ES2015 standard, è necessario eseguirne prima la trasplicazione o utilizzare un caricatore di moduli esterno in fase di esecuzione.

Al momento non sono troppo positivo per usare uno di questi due metodi, i manutentori di NodeJS stanno pianificando di supportare i moduli ES2015 o no? Non ho trovato alcun suggerimento al riguardo.

Al momento NodeJS 6.x afferma di supportare il 96% delle funzionalità ES2015, ma non esiste alcun riferimento ai moduli ( collegamento di supporto NodeJS ES2105 ).

Sai se NodeJS supporterà questi moduli immediatamente, nel prossimo futuro?


2
Googling for node es2015 modules, mostra quanto segue come uno dei migliori risultati: github.com/nodejs/node/wiki/ES6-Module-Detection-in-Node .
Felix Kling,

6
Personalmente voterei per chiudere questa domanda come "troppo localizzata", ma quel motivo stretto non esiste più. Supponiamo che domani Node riesca a implementare i moduli ES6. Allora eliminerai la tua domanda, perché non è più pertinente? O lo aggiornerai almeno? Non penso che una domanda sia adatta a SO se sai già che sarà obsoleta o deve essere aggiornata "presto". Ma questa è solo la mia opinione e sembra che ci siano altri che pensano il contrario, il che è ok per me :) (prima, la domanda di per sé è ovviamente importante e interessante)
Felix Kling

2
Vorrei che ci fosse posto nell'Universo Stack per domande come questa, però. Potrebbe non essere tecnicamente adatto qui, ma non so che sono d'accordo sul fatto che sia davvero "basato sull'opinione". OP è alla ricerca di una risposta specifica a una domanda specifica, ma che sarà (ad un certo punto) obsoleta.
Wonko the Sane,

5
Frase alternativa di questa domanda: "Qual è lo stato del supporto node.js per i moduli ES6?" La risposta a molte domande SO cambia nel tempo man mano che la tecnologia si evolve. Anch'io ho avuto difficoltà a trovare la risposta fino a quando non sono atterrato qui.
Joe Lapp,

4
@FelixKling Immagino che voler chiudere questa domanda sarebbe stata una decisione molto sbagliata in quanto è un problema che 211 persone hanno finora trovato abbastanza problematico da votare.
Muhammad Umer

Risposte:


302

Nodo 13.2.0 e versioni successive

NodeJS 13.2.0 ora supporta i moduli ES senza un flag 🎉 Tuttavia, l'implementazione è ancora contrassegnata come sperimentale, quindi utilizzare in produzione con cautela.

Per abilitare il supporto ESM in 13.2.0, aggiungere quanto segue a package.json:

{
  "type": "module"
}

Tutti .js, .mjs(o file senza estensione) saranno trattati come ESM.

Esistono diverse opzioni diverse dall'intero package.jsonopt-in, tutte dettagliate nella Documentazione per 13.2.0 .

Nodo 13.1.0 e precedenti

Coloro che utilizzano ancora versioni precedenti di Node potrebbero voler provare il caricatore del modulo esm , che è un'implementazione pronta per la produzione delle specifiche dei moduli ES per NodeJS:

node -r esm main.js

Aggiornamenti dettagliati ...

23 aprile 2019

Un PR è recentemente arrivato per cambiare il modo in cui i moduli ES vengono rilevati: https://github.com/nodejs/node/pull/26745

È ancora dietro la --experimental-modulesbandiera, ma ci sono importanti cambiamenti nel modo in cui i moduli possono essere caricati:

  • package.typeche può essere moduleocommonjs
    • type: "commonjs":
      • .js viene analizzato come commonjs
      • l'impostazione predefinita per il punto di ingresso senza estensione è commonjs
    • type: "module":
      • .js viene analizzato come esm
      • non supporta il caricamento di JSON o Native Module per impostazione predefinita
      • il valore predefinito per il punto di ingresso senza estensione è esm
  • --type=[mode]per consentire di impostare il tipo sul punto di ingresso. Sostituirà il package.typepunto di ingresso.
  • Una nuova estensione di file .cjs.
    • questo è specificamente per supportare l'importazione di commonjs in modulemodalità.
    • questo è solo nel caricatore esm, il caricatore commonjs rimane intatto, ma l'estensione funzionerà nel vecchio caricatore se si utilizza il percorso completo del file.
  • --es-module-specifier-resolution=[type]
    • le opzioni sono explicit(impostazione predefinita) enode
    • per impostazione predefinita il nostro caricatore non consentirà estensioni opzionali nell'importazione, il percorso per un modulo deve includere l'estensione se ce n'è una
    • per impostazione predefinita, il nostro caricatore non consentirà l'importazione di directory con un file indice
    • gli sviluppatori possono utilizzare --es-module-specifier-resolution=nodeper abilitare l'algoritmo di risoluzione dell'identificatore commonjs
    • Questa non è una "caratteristica" ma piuttosto un'implementazione per la sperimentazione. Si prevede che cambi prima che il flag venga rimosso
  • --experimental-json-loader
    • l'unico modo per importare json quando "type": "module"
    • quando abilita tutto import 'thing.json'passerà attraverso il caricatore sperimentale indipendentemente dalla modalità
    • basato su whatwg / html # 4315
  • È possibile utilizzare package.mainper impostare un punto di ingresso per un modulo
    • le estensioni dei file utilizzate in main verranno risolte in base al tipo di modulo

17 gennaio 2019

Il nodo 11.6.0 elenca ancora i moduli ES come sperimentali, dietro una bandiera.

13 settembre 2017

NodeJS 8.5.0 è stato rilasciato con il supporto per i file mjs dietro un flag:

node --experimental-modules index.mjs

Il piano per questo è rimuovere il flag per la versione LTS v10.0.

- Informazioni obsolete. Tenuto qui per scopi storici

8 settembre 2017

La diramazione principale di NodeJS è stata aggiornata con il supporto iniziale per i moduli ESM:
https://github.com/nodejs/node/commit/c8a389e19f172edbada83f59944cad7cc802d9d5

Questo dovrebbe essere disponibile nelle ultime ore notturne (può essere installato tramite nvm per essere eseguito insieme all'installazione esistente):
https://nodejs.org/download/nightly/

E abilitato dietro la --experimental-modulesbandiera:

package.json

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

Quindi eseguire:

node --experimental-modules .

Febbraio 2017:

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

I ragazzi di NodeJS hanno deciso che la soluzione meno negativa è usare l' .mjsestensione del file. L'asporto da questo è:

In altre parole, dati due file foo.jse bar.mjs, usando import * from 'foo'tratterà foo.jscome CommonJS mentre import * from 'bar' tratteranno bar.mjscome un modulo ES6

E per quanto riguarda le tempistiche ...

Al momento attuale, ci sono ancora una serie di problemi di specifica e implementazione che devono accadere sul lato ES6 e sul lato Virtual Machine prima che Node.js possa persino iniziare a elaborare un'implementazione sostenibile dei moduli ES6. I lavori sono in corso ma ci vorrà del tempo: al momento stiamo guardando almeno un anno .

Ottobre 2016:

Uno degli sviluppatori di Node.JS ha recentemente partecipato a una riunione del TC-39 e ha scritto un superbo articolo sui bloccanti per l'implementazione di Node.JS:

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

Il take-away di base è:

  • I moduli ES vengono analizzati staticamente, vengono valutati CommonJS
  • I moduli CommonJS consentono esportazioni di patch per scimmie, mentre i moduli ES attualmente no
  • È difficile rilevare cos'è un modulo ES e cos'è CommonJS senza una qualche forma di input dell'utente, ma ci stanno provando.
  • *.mjs sembra la soluzione più probabile, a meno che non siano in grado di rilevare con precisione un modulo ES senza l'input dell'utente

- Risposta originale -

Questa è stata una patata bollente per un bel po 'di tempo. La linea di fondo è che sì, Node alla fine supporterà la sintassi ES2015 per l'importazione / esportazione di moduli - molto probabilmente quando le specifiche per il caricamento dei moduli saranno finalizzate e concordate.

Ecco una buona panoramica di ciò che regge NodeJS. In sostanza, devono assicurarsi che le nuove specifiche funzionino per Node, che è principalmente carico condizionale, sincrono e anche HTML che è principalmente asincrono.

Nessuno lo sa con certezza in questo momento, ma immagino che Node supporterà il import/exportcaricamento statico, oltre al nuovo System.importper il caricamento dinamico, mantenendo comunque il requirecodice legacy.

Ecco alcune proposte su come Node potrebbe raggiungere questo obiettivo:


38
A proposito di .mjsestensione: We have affectionately called these “Michael Jackson Script” files in the past. Nel caso in cui senti qualcuno parlare di artisti pop durante i discorsi di JS.
Jeewes,

1
Non vedo perché cambiare la sintassi di importazione non sia sufficiente. Una sintassi per importare es (quella "corretta") e una per importare i cjs? In altre parole, dati due file foo.js e bar.js, import * from 'foo'tratteranno foo.js come CommonJS import * as bar from 'bar'tratterà bar.js come un modulo ES6 Qualcuno può spiegare?
Corey Alix,

1
La sintassi di @CoreyAlix generalmente non verrà modificata per supportare un ambiente. Ciò influisce davvero solo sul nodo dopo tutto. Inoltre, la sintassi è un po 'non intuitiva. Come posso accedere alle esportazioni nella sintassi proposta?
CodingIntrigue

Per essere chiari, non è la "mia" proposta, sto copiando ciò che dattiloscritto sta già facendo. Per rispondere alla tua domanda, accedi alle esportazioni con "bar": bar.foobar () import {foo as Foo} da “./foo” è il meccanismo per identificare un modulo ES6. var Foo = request (“./ foo”) è il meccanismo per identificare il modulo CJS. In Typescript l'output di commonjs è simile al seguente: var mod1_1 = require ("./ mod1"); exports.mod1 = mod1; L'output ES6 è simile al seguente: import {mod1} da "./mod1"; export {mod1}
Corey Alix

1
Sarei davvero interessante in un aggiornamento del Nodo 10 a questa risposta. La funzione ha tagliato o è ancora dietro una bandiera?
Dal
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.