web-dev-qa-db-fra.com

L'utilisation de Node.js nécessite la importation / exportation ES6

Dans un projet sur lequel je collabore, nous avons deux choix sur le système de module que nous pouvons utiliser:

  1. Importation de modules avec require et exportation avec module.exports et exports.foo.
  2. Importation de modules avec ES6 import et exportation avec ES6 export

L'utilisation de l'un par rapport à l'autre présente-t-elle des avantages en termes de performances? Y a-t-il autre chose que nous devrions savoir si nous utilisions des modules ES6 sur Node?

792
kpimov

L'utilisation de l'un par rapport à l'autre présente-t-elle des avantages en termes de performances?

N'oubliez pas qu'il n'existe pas encore de moteur JavaScript prenant en charge de manière native les modules ES6. Vous avez dit vous-même que vous utilisiez Babel. Babel convertit import et export la déclaration en CommonJS (require/module.exports) par défaut. Ainsi, même si vous utilisez la syntaxe du module ES6, vous utiliserez CommonJS sous le capot si vous exécutez le code dans Node.

Il existe des différences techniques entre les modules CommonJS et ES6, par exemple. CommonJS vous permet de charger des modules de manière dynamique. ES6 ne permet pas cela, mais il y a une API en développement pour cela .

Puisque les modules ES6 font partie de la norme, je les utiliserais.

642
Felix Kling

Il y a plusieurs utilisations/capacités que vous pourriez vouloir considérer:

Exiger:

  • Vous pouvez avoir un chargement dynamique dans lequel le nom du module chargé n'est pas prédéfini/statique, ou dans lequel vous chargez conditionnellement un module uniquement s'il est "réellement requis" (en fonction de certains flux de code).
  • Le chargement est synchrone. Cela signifie que si vous avez plusieurs requires, ils sont chargés et traités un par un.

ES6 Importations:

  • Vous pouvez utiliser des importations nommées pour charger sélectivement uniquement les pièces dont vous avez besoin. Cela peut économiser de la mémoire.
  • L'importation peut être asynchrone (et dans ES6 Module Loader actuel, il l'est en fait) et peut être un peu plus performante.

De plus, le système de module Require n'est pas basé sur la norme. Il est très peu probable que cela devienne la norme maintenant que les modules ES6 existent. À l'avenir, les modules ES6 seront pris en charge de manière native dans diverses implémentations, ce qui sera avantageux en termes de performances.

156
Amit

Les principaux avantages sont syntaxiques:

  • Syntaxe plus déclarative/compacte
  • Les modules ES6 vont en principe rendre obsolètes UMD (Universal Module Definition) - ils suppriment essentiellement le schisme entre CommonJS et AMD (serveur contre navigateur).

Il est peu probable que vous constatiez des avantages en termes de performances avec les modules ES6. Vous aurez toujours besoin d'une bibliothèque supplémentaire pour regrouper les modules, même lorsque les fonctionnalités de ES6 sont entièrement prises en charge par le navigateur.

39
snozza

Y a-t-il des avantages en termes de performances à utiliser l'un sur l'autre?

La réponse actuelle est non, car aucun des moteurs de navigateur actuels n'implémente import/export à partir de la norme ES6.

Quelques tableaux comparatifs http://kangax.github.io/compat-table/es6/ ne tenez pas compte de cela, donc lorsque vous voyez presque tous les verts de Chrome, faites attention. Le mot clé import de ES6 n'a pas été pris en compte.

En d’autres termes, les moteurs de navigateur actuels, y compris la V8, ne peuvent pas importer un nouveau fichier JavaScript à partir du fichier JavaScript principal via une directive JavaScript.

(Nous sommes peut-être encore juste quelques bugs plus loin ou dans quelques années jusqu'à ce que V8 implémente cela conformément à la spécification ES6.)

Ce document est ce dont nous avons besoin, et ce document est ce à quoi nous devons obéir.

Et la norme ES6 stipulait que les dépendances de module devraient être présentes avant de lire le module, comme dans le langage de programmation C, où nous avions (en-têtes) .h fichiers.

Il s’agit d’une bonne structure bien testée, et je suis sûr que les experts qui ont créé la norme ES6 avaient cela à l’esprit.

C’est ce qui permet à Webpack ou à d’autres groupeurs de packages d’optimiser le bundle dans certains cas spéciaux et de réduire certaines dépendances inutiles du bundle. Mais dans les cas où nous avons des dépendances parfaites, cela n'arrivera jamais.

Il faudra un peu de temps pour que le support natif de import/export soit opérationnel et que le mot clé require ne disparaisse pas avant longtemps.

Qu'est-ce que require?

Ceci est node.js moyen de charger des modules. ( https://github.com/nodejs/node )

Le nœud utilise des méthodes au niveau du système pour lire les fichiers. Vous comptez essentiellement sur cela lorsque vous utilisez require. require se terminera par un appel système tel que uv_fs_open (dépend du système final, Linux, Mac, Windows) pour charger le fichier/module JavaScript.

Pour vérifier que cela est vrai, essayez d’utiliser Babel.js et vous verrez que le mot clé import sera converti en require.

enter image description here

32
prosti

L'utilisation de modules ES6 peut être utile pour "secouer les arbres"; c’est-à-dire permettre à Webpack 2, Rollup (ou à d’autres groupeurs) d’identifier les chemins de code non utilisés/importés et, par conséquent, de ne pas en faire le groupe résultant. Cela peut réduire considérablement la taille de son fichier en éliminant le code dont vous n’auriez jamais besoin, mais avec CommonJS, il est fourni par défaut car Webpack et al n’ont aucun moyen de savoir s’il est nécessaire ou non.

Ceci est fait en utilisant une analyse statique du chemin de code.

Par exemple, en utilisant:

import { somePart } 'of/a/package';

... donne à l'agent de groupement un indice que package.anotherPart n'est pas obligatoire (s'il n'est pas importé, il ne peut pas être utilisé - n'est-ce pas?), cela ne vous gênera donc pas.

Pour l'activer pour Webpack 2, vous devez vous assurer que votre transpiler ne crache pas de modules CommonJS. Si vous utilisez le plug-in es2015 avec babel, vous pouvez le désactiver dans votre .babelrc comme ceci:

{
  "presets": [
    ["es2015", { modules: false }],
  ]
}

Rollup et d'autres peuvent fonctionner différemment - affichez la documentation si cela vous intéresse.

28
Lee Benson

En ce qui concerne le chargement asynchrone ou peut-être paresseux, import () est beaucoup plus puissant. Nous voyons quand nous avons besoin du composant de manière asynchrone, puis nous utilisons import -le de manière asynchrone comme dans const variable en utilisant await.

const module = await import('./module.js');

Ou si vous voulez utiliser require() alors,

const converter = require('./converter');

La chose est import() est en réalité de nature asynchrone. Comme mentionné par neehar venugopal dans ReactConf , vous pouvez l'utiliser pour charger dynamiquement des composants réactifs pour une architecture côté client.

En outre, il est bien meilleur en matière de routage. C’est la seule chose qui rend le journal réseau nécessaire pour télécharger une partie nécessaire lorsque l’utilisateur se connecte à un site Web spécifique pour son composant spécifique. par exemple. page de connexion avant que le tableau de bord ne télécharge pas tous les composants du tableau de bord. En effet, ce qui est nécessaire, c’est-à-dire le composant de connexion actuel, ne sera téléchargé que.

Il en va de même pour export: ES6 export sont exactement les mêmes que pour CommonJS module.exports.

NOTE - Si vous développez un projet node.js, vous devez strictement utiliser require() en tant que noeud. générera une erreur d'exception sous la forme invalid token 'import' si vous utiliserez import. Donc, le noeud ne supporte pas les instructions d'import.

UPDATE - Comme suggéré par Dan Dascalesc : Depuis la v8.5.0 (sortie en septembre 2017), node --experimental-modules index.mjs vous permet d'utiliser import sans Babel. Vous pouvez (et devriez) aussi publier vos paquets npm en tant que ESModule natif, avec compatibilité ascendante pour l'ancien mode require.

Voir ceci pour plus de clairance où utiliser les importations asynchrones - https://www.youtube.com/watch?v=bb6RCrDaxhw

17
Meet Zaveri

La chose la plus importante à savoir est que les modules ES6 sont bien une norme officielle, contrairement aux modules CommonJS (Node.js).

En 2019, les modules ES6 sont pris en charge par 84% des navigateurs. Bien que Node.js les place derrière un drapeau - experimental-modules , il existe également un paquet de nœuds très pratique appelé esm , ce qui facilite l'intégration.

Un autre problème que vous rencontrerez probablement entre ces systèmes de modules est l’emplacement du code. Node.js suppose que la source est conservée dans un répertoire node_modules, tandis que la plupart des modules ES6 sont déployés dans une structure de répertoire à plat. Celles-ci ne sont pas faciles à réconcilier, mais vous pouvez le faire en piratant votre fichier package.json avec des scripts de pré et post-installation. Voici un exemple module isomorphique et un article expliquant comment cela fonctionne.

7
isysd

Personnellement, j'utilise import parce que nous pouvons importer les méthodes requises membres en utilisant import.

import {foo, bar} from "dep";

FileName: dep.js

export foo function(){};
export const bar = 22

Le mérite en revient à Paul Shan. Plus d'infos .

6
chandoo