557 votes

La différence entre "require(x)" et import x

Je viens de commencer à travailler sur un petit projet node qui va s'interfacer avec un MongoDB. Cependant, je n'arrive pas à importer correctement les modules node pertinents, bien que je les aie installés correctement par le biais de npm .

Par exemple, le code suivant jette une erreur, me disant que "express n'a pas d'exportation par défaut" :

import express from "express";

Cependant, ce code fonctionne :

const express = require("express");

Ma question est donc la suivante : quelle est la différence entre le fonctionnement de la méthode d'importation et celui de la méthode variable/require ? J'aimerais régler le problème de mes importations sur le projet, car il est susceptible de causer d'autres problèmes par la suite.

3 votes

Si vous n'incluez pas les définitions de typage pour express, la première forme n'aura pas de sens - dans ce cas, vous pouvez utiliser la deuxième forme, mais la variable express sera de type any . Vous pourriez inclure les définitions d'ici npmjs.com/package/@types/express

6 votes

0 votes

@Ryall c'est une question différente. Avis import x = require('x') n'est pas la même chose que var x = require('x') .

649voto

don't angry me Points 12817

La réponse qui m'aide à comprendre la différence entre require et import est Utilisation de Node.js require vs. import/export ES6 qui comprend un diagramme simple :

enter image description here

51 votes

La plus grande différence qui affecte le code est que les exportations dans les modules CommonJS sont "calculées", alors que les exportations dans un module ESM sont statiques (prédéfinies). JS peut déterminer les exportations dans un module ESM après avoir analysé le code (sans l'exécuter). Dans un module CommonJS, les exportations ne sont connues que lorsque le module s'exécute réellement et que vous voyez ce qui est attribué à module.exports lorsque le code d'initialisation du module a fini de s'exécuter. Cette seule différence crée des problèmes de compatibilité lorsqu'on essaie de faire fonctionner un seul module à la fois pour ESM et CommonJS.

4 votes

Les modules ESM sont plus conviviaux pour les bundlers, mais sont plus restrictifs pour les codeurs, car les modules ESM ne permettent pas d'avoir des exportations calculées.

160voto

Ayon Lee Points 410

La principale différence entre require et import c'est que require va automatiquement scanner node_modules pour trouver des modules, mais import qui provient de l'ES6, ne le fera pas.

La plupart des gens utilisent babel pour compiler import et export ce qui rend import agissent de la même manière que require .

La future version de Node.js pourrait supporter import lui-même (en fait, la version expérimentale le fait déjà ), et à en juger par les notes de Node.js, import ne supportera pas node_modules il est basé sur ES6, et doit spécifier le chemin du module.

Je vous suggère donc de ne pas utiliser import avec babel, mais cette fonctionnalité n'est pas encore confirmée, elle pourrait supporter node_modules dans le futur, qui le saurait ?


À titre de référence, voici un exemple de la façon dont babel peut convertir des fichiers ES6 import à la syntaxe de CommonJS require la syntaxe.

Disons que le fichier app_es6.js contient cette importation :

import format from 'date-fns/format';

Il s'agit d'une directive pour importer le format de l'ensemble des nœuds date-fns .

L'association package.json pourrait contenir quelque chose comme ceci :

"scripts": {
    "start": "node app.js",
    "build-server-file": "babel app_es6.js --out-file app.js",
    "webpack": "webpack"
}

Les .babelrc pourrait être quelque chose comme ceci :

{
    "presets": [
        [
            "env",
            {
                "targets":
                {
                    "node": "current"
                }
            }
        ]
    ]
}

Ce site build-server-file script défini dans le fichier package.json est une directive pour que babel analyse le fichier app_es6.js et de sortir le fichier app.js .

Après avoir exécuté le build-server-file script, si vous ouvrez app.js et cherchez le date-fns importé, vous verrez qu'il a été converti en ceci :

var _format = require("date-fns/format");

var _format2 = _interopRequireDefault(_format);

La plupart de ce fichier est un charabia pour la plupart des humains, mais les ordinateurs le comprennent.


Toujours pour référence, à titre d'exemple de la manière dont un module peut être créé et importé dans votre projet, si vous installez date-fns et ensuite ouvrir node_modules/date-fns/get_year/index.js vous pouvez voir qu'il contient :

var parse = require('../parse/index.js')

function getYear (dirtyDate) {
  var date = parse(dirtyDate)
  var year = date.getFullYear()
  return year
}

module.exports = getYear

En utilisant le processus babel ci-dessus, votre app_es6.js pourrait alors contenir :

import getYear from 'date-fns/get_year';

// Which year is 2 July 2014?
var result = getYear(new Date(2014, 6, 2))
//=> 2014

Et Babel convertirait les importations en :

var _get_year = require("date-fns/get_year");

var _get_year2 = _interopRequireDefault(_get_year);

Et traitez toutes les références à la fonction en conséquence.

2 votes

Aaaaahhhhhh. Babel n'a pas été installé sur ce projet particulier, ce qui donne un sens à tout ça. Je pensais que les importations/exportations ES6 étaient déjà fonctionnelles, mais je comprends maintenant que Babel ne fait que tout changer en require de toute façon

0 votes

S'en tenir aux exigences pour le moment. Vous pourrez toujours le changer dans le futur sans aucun problème.

6 votes

import won't support node_modules Qu'est-ce que tu voulais dire par là ?

63voto

saikiran_hegde Points 118

Laissez-moi vous donner un exemple pour inclure un module express avec require & import.

-requérir

var express = require('express');

-importation

import * as  express from 'express';

Ainsi, après avoir utilisé l'une des déclarations ci-dessus, nous aurons une variable appelée 'express' avec nous. Maintenant, nous pouvons définir la variable 'app' comme suit,

var app = express(); 

Nous utilisons donc 'require' avec 'CommonJS' et 'import' avec 'ES6'.

Pour plus d'informations sur 'require' et 'import', lisez les liens ci-dessous.

exiger - Modules obligatoires dans Node.js : tout ce que vous devez savoir

importation - Une mise à jour sur les modules ES6 dans Node.js

8 votes

C'est certainement la bonne réponse. Le poster avait un problème avec l'utilisation de l'es6. import et a été confondu par la express n'a pas d'exportation par défaut erreur. Cette réponse fournit la solution. Les modules avec des exportations multiples (et même uniques) qui ne définissent pas un fichier default export devra avoir toutes les exportations assignées à une variable nommée, comme l'explique la réponse : import * as whatever from 'package';

0 votes

D'accord, cela devrait être la première réponse. Pour modifier le commentaire précédent, vous pouvez vérifier le code du paquet dont vous dépendez dans le fichier node_modules (le point d'entrée sera répertorié sous son package.json main clé). Quelque chose comme module.export = whatever signifie que vous devrez probablement l'importer en tant que import * as whatever from 'package'; .

2voto

Tianpeng. Xia Points 7

Ce n'est pas une réponse mais plutôt un commentaire, désolé mais je ne peux pas commenter.

Dans le nœud V10, vous pouvez utiliser le drapeau --experimental-modules pour dire à Nodejs que vous voulez utiliser import . Mais votre entrée script devrait se terminer par .mjs .

Notez qu'il s'agit toujours d'un élément expérimental et que ne devrait pas être utilisé en production.

// main.mjs
import utils from './utils.js'
utils.print();

// utils.js
module.exports={
    print:function(){console.log('print called')}
}

Ref 1 - Nodejs Doc

Ref 2 - problème github

-3voto

Mukul Sharma Points 74

import est utilisé dans typescript(angular). require est utilisé dans ES6 (ExpressJs)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X