NodeJS prévoit de prendre en charge les modules d'import / export es6 (es2015)

275

J'ai cherché partout sur Internet sans réponse claire à cela.

Actuellement, NodeJS utilise uniquement la syntaxe CommonJS pour charger les modules, et si vous voulez vraiment utiliser la syntaxe des modules ES2015 standard, vous devez soit la transpiler au préalable, soit utiliser un chargeur de module externe lors de l'exécution.

Actuellement, je ne suis pas trop positif pour utiliser l'une de ces deux méthodes, les responsables de NodeJS prévoient-ils même de prendre en charge les modules ES2015 ou non? Je n'ai trouvé aucun indice à ce sujet.

Pour le moment, NodeJS 6.x prétend prendre en charge 96% des fonctionnalités ES2015, mais il n'y a aucune référence aux modules ( lien de support NodeJS ES2105 ).

Savez-vous si NodeJS prendra en charge ces modules prêts à l'emploi, dans un avenir proche?

Zorgatone
la source
2
Recherche sur Google node es2015 modules, affiche les résultats suivants comme l'un des meilleurs résultats: github.com/nodejs/node/wiki/ES6-Module-Detection-in-Node .
Felix Kling
6
Personnellement, je voterais pour clore cette question comme "trop ​​localisée", mais cette raison proche n'existe plus. Disons que Node parvient à implémenter les modules ES6 demain. Allez-vous supprimer votre question, car elle n'est plus pertinente? Ou allez-vous au moins le mettre à jour? Je ne pense pas qu'une question convienne à SO si vous savez déjà qu'elle sera obsolète ou doit être mise à jour "bientôt". Mais c'est juste mon opinion et il semble y en avoir d'autres qui pensent le contraire, ce qui est ok pour moi :) (fwiw, en soi la question est bien sûr importante et intéressante)
Felix Kling
2
J'aimerais qu'il y ait une place dans l'univers de pile pour des questions comme celle-ci, cependant. Il ne convient peut-être pas techniquement ici, mais je ne sais pas si je suis d'accord qu'il est vraiment "basé sur l'opinion" non plus. OP cherche une réponse spécifique à une question spécifique, mais qui sera (à un moment donné) dépassée.
Wonko the Sane
5
Formulation alternative de cette question: "Quel est l'état de la prise en charge de node.js pour les modules ES6?" La réponse à de nombreuses questions SO change avec le temps à mesure que la technologie évolue. Moi aussi, j'ai eu du mal à trouver la réponse jusqu'à ce que j'atterrisse ici.
Joe Lapp
4
@FelixKling je suppose que vous vouliez fermer cette question aurait été une très mauvaise décision car c'est un problème que 211 personnes ont jusqu'à présent jugé suffisamment problématique pour voter.
Muhammad Umer

Réponses:

302

Noeud 13.2.0 et supérieur

NodeJS 13.2.0 prend désormais en charge les modules ES sans indicateur 🎉 Cependant, l'implémentation est toujours marquée comme expérimentale, donc utilisez-la en production avec prudence.

Pour activer la prise en charge ESM dans 13.2.0, ajoutez ce qui suit à votre package.json:

{
  "type": "module"
}

Tous .js, .mjs(ou fichiers sans extension) seront traitées comme ESM.

Il existe un certain nombre d'options différentes, autres que l' package.jsonopt-in complet , qui sont toutes détaillées dans la documentation de 13.2.0 .

Noeud 13.1.0 et inférieur

Ceux qui utilisent encore des versions plus anciennes de Node peuvent vouloir essayer le chargeur de module esm , qui est une implémentation prête pour la production de la spécification ES Modules pour NodeJS:

node -r esm main.js

Mises à jour détaillées ...

23 avril 2019

Un PR a récemment atterri pour changer la façon dont les modules ES sont détectés: https://github.com/nodejs/node/pull/26745

C'est toujours derrière le --experimental-modulesdrapeau, mais il y a des changements majeurs dans la façon dont les modules peuvent être chargés:

  • package.typequi peut être soit moduleoucommonjs
    • type: "commonjs":
      • .js est analysé comme commonjs
      • par défaut pour le point d'entrée sans extension est commonjs
    • type: "module":
      • .js est analysé comme esm
      • ne prend pas en charge le chargement de JSON ou du module natif par défaut
      • par défaut pour le point d'entrée sans extension est esm
  • --type=[mode]pour vous permettre de définir le type sur le point d'entrée. Remplacera le package.typepoint d'entrée.
  • Une nouvelle extension de fichier .cjs.
    • c'est spécifiquement pour prendre en charge l'importation de commonjs dans le modulemode.
    • ce n'est que dans le chargeur esm, le chargeur commonjs reste intact, mais l'extension fonctionnera dans l'ancien chargeur si vous utilisez le chemin d'accès complet au fichier.
  • --es-module-specifier-resolution=[type]
    • les options sont explicit(par défaut) etnode
    • par défaut, notre chargeur ne permettra pas d'extensions optionnelles lors de l'importation, le chemin d'accès d'un module doit inclure l'extension s'il y en a une
    • par défaut, notre chargeur ne permettra pas d'importer des répertoires qui ont un fichier d'index
    • les développeurs peuvent utiliser --es-module-specifier-resolution=nodepour activer l'algorithme de résolution de spécificateur commonjs
    • Ce n'est pas une «fonctionnalité» mais plutôt une implémentation pour l'expérimentation. Il devrait changer avant la suppression du drapeau
  • --experimental-json-loader
    • la seule façon d'importer json lorsque "type": "module"
    • quand activer tout import 'thing.json'passera par le chargeur expérimental indépendant du mode
    • basé sur whatwg / html # 4315
  • Vous pouvez utiliser package.mainpour définir un point d'entrée pour un module
    • les extensions de fichiers utilisées dans main seront résolues en fonction du type de module

17 janvier 2019

Le nœud 11.6.0 répertorie toujours les modules ES comme expérimentaux, derrière un indicateur.

13 septembre 2017

NodeJS 8.5.0 a été publié avec la prise en charge des fichiers mjs derrière un indicateur:

node --experimental-modules index.mjs

Le plan pour cela est de supprimer l'indicateur de la version v10.0 LTS.

--Informations obsolètes. Conservé ici à des fins historiques -

8 septembre 2017

La branche principale NodeJS a été mise à jour avec la prise en charge initiale des modules ESM:
https://github.com/nodejs/node/commit/c8a389e19f172edbada83f59944cad7cc802d9d5

Celui-ci devrait être disponible dans la dernière nuit (il peut être installé via nvm pour fonctionner en parallèle de votre installation existante):
https://nodejs.org/download/nightly/

Et activé derrière le --experimental-modulesdrapeau:

package.json

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

Exécutez ensuite:

node --experimental-modules .

Février 2017:

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

Les gars de NodeJS ont décidé que la moins mauvaise solution était d'utiliser l' .mjsextension de fichier. Les enseignements à en tirer sont les suivants:

En d'autres termes, étant donné deux fichiers foo.jset bar.mjs, l'utilisation import * from 'foo'sera traitée foo.jscomme CommonJS tandis que import * from 'bar' sera bar.mjstraitée comme un module ES6

Et quant aux délais ...

À l'heure actuelle, il y a encore un certain nombre de problèmes de spécification et d'implémentation qui doivent se produire du côté ES6 et de la machine virtuelle avant que Node.js puisse même commencer à travailler sur une implémentation supportable des modules ES6. Les travaux sont en cours mais cela va prendre un certain temps - Nous envisageons actuellement environ un an au moins .

Octobre 2016:

L'un des développeurs de Node.JS a récemment assisté à une réunion TC-39 et a rédigé un superbe article sur les bloqueurs à implémenter pour Node.JS:

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

Le point à retenir de base est:

  • Les modules ES sont analysés statiquement, les CommonJS sont évalués
  • Les modules CommonJS permettent d'exporter des correctifs de singe, les modules ES ne le font pas actuellement
  • Il est difficile de détecter ce qu'est un module ES et ce qui est CommonJS sans une certaine forme d'entrée utilisateur, mais ils essaient.
  • *.mjs semble la solution la plus probable, à moins qu'ils ne puissent détecter avec précision un module ES sans intervention de l'utilisateur

- Réponse originale -

Cela a été une patate chaude pendant un certain temps. En fin de compte, oui, Node prendra éventuellement en charge la syntaxe ES2015 pour l'importation / exportation de modules - très probablement lorsque les spécifications pour le chargement des modules seront finalisées et acceptées.

Voici un bon aperçu de ce qui retient NodeJS. Essentiellement, ils doivent s'assurer que la nouvelle spécification fonctionne pour Node qui est principalement un chargement synchrone conditionnel et également pour HTML qui est principalement asynchrone.

Personne ne le sait pour le moment, mais j'imagine que Node prendra en charge import/exportle chargement statique, en plus du nouveau System.importpour le chargement dynamique - tout en conservant le requirecode hérité.

Voici quelques propositions sur la façon dont Node pourrait y parvenir:

CodageIntrigue
la source
38
A propos de l' .mjsextension: We have affectionately called these “Michael Jackson Script” files in the past. Juste au cas où vous entendriez quelqu'un parler des artistes pop lors de la conférence JS.
Jeewes
1
Je ne vois pas pourquoi changer la syntaxe d'importation ne suffit pas. Une syntaxe pour importer es (la «correcte») et une pour importer cjs? En d'autres termes, étant donné deux fichiers foo.js et bar.js, import * from 'foo'traitera foo.js comme CommonJS import * as bar from 'bar'traitera bar.js comme un module ES6. Quelqu'un peut-il expliquer?
Corey Alix
1
La syntaxe @CoreyAlix ne sera généralement pas modifiée afin de prendre en charge un environnement. Cela n'affecte vraiment Node qu'après tout. De plus, la syntaxe est un peu non intuitive. Comment accéder aux exportations dans la syntaxe que vous proposez?
CodingIntrigue
Pour être clair, ce n'est pas "ma" proposition, je copie ce que le tapuscrit fait déjà. Pour répondre à votre question, vous accédez aux exports avec "bar": bar.foobar () import {foo as Foo} de "./foo" est le mécanisme d'identification d'un module ES6. var Foo = require («./ foo») est le mécanisme d'identification du module CJS. Dans Typescript, la sortie commonjs ressemble à ceci: var mod1_1 = require ("./ mod1"); exports.mod1 = mod1; La sortie ES6 ressemble à ceci: import {mod1} de "./mod1"; export {mod1}
Corey Alix
1
Je serais vraiment intéressant dans une mise à jour de Node 10 à cette réponse. La caractéristique a-t-elle fait la coupe, ou est-elle toujours derrière un drapeau?
dcorking