Разница между "require(x)" и import x
Я только начал работать над небольшим проектом, который будет взаимодействовать с MongoDB. Тем не менее, я не могу заставить соответствующие модули узла правильно импортировать, даже если я правильно установил их через npm
,
Например, следующий код выдает ошибку и сообщает, что "экспресс не имеет экспорта по умолчанию":
import express from "express";
Тем не менее, этот код работает:
const express = require("express");
Итак, мой вопрос: в чем разница в том, как работают методы import и variable/require? Я хотел бы исправить все, что мешает моему импорту в проекте, так как это может вызвать дополнительные проблемы в будущем.
10 ответов
Есть много ресурсов в Интернете на ваш вопрос, даже на SO. Вы можете увидеть здесь, но простой ответ, который помогает мне понять разницу между require
а также import
использует Node.js по сравнению с ES6 импорт / экспорт
С простой картинкой:
Предоставлено: prosti
Основное различие между require
а также import
, в том, что require
будет автоматически сканировать node_modules
найти модули, но import
, который прибывает из ES6, не будет. Но сейчас большинство людей будут использовать Babel для компиляции import
а также export
, который сделает import
действовать так же, как require
, но будущая версия Node.js может поддерживать import
сам (на самом деле, экспериментальная версия уже сделала), и, судя по примечаниям Node.js, import
не будет поддерживать node_modules
, он основан на ES6 и должен указывать путь к модулю.
Поэтому я бы посоветовал вам не использовать import
с Babel, но эта функция еще не подтверждена, она может поддерживать node_modules
в будущем кто бы знал?
Позвольте мне привести пример для включения экспресс-модуля с require & import
-require
var express = require('express');
-Импортировать
import * as express from 'express';
Таким образом, после использования любого из приведенных выше утверждений у нас будет переменная с именем "express". Теперь мы можем определить переменную app как:
var app = express();
Поэтому мы используем 'require' с 'CommonJS' и 'import' с 'ES6'.
Чтобы узнать больше о 'require' & 'import', прочитайте ссылки ниже.
require - Требование модулей в Node.js: все, что вам нужно знать
import - Обновление модулей ES6 в Node.js
Я сделаю это просто,
- Импорт и экспорт - это функции ES6 (JS следующего поколения).
- Require - это старый метод импорта кода из других файлов.
Основная разница в том, что требуется, вызывается или импортируется весь JS-файл. Даже если вам не нужна какая-то его часть.
var myObject = require('./otherFile.js'); //This JS file will be imported fully.
В то время как при импорте вы можете извлекать только необходимые объекты / функции / переменные.
import { getDate }from './utils.js';
//Here I am only pulling getDate method from the file instead of importing full file
Еще одно важное отличие заключается в том, что вы можете использовать
require
в любом месте программы, где как
import
всегда должен быть вверху файла
новый ES6:
'import' следует использовать с ключевыми словами 'export' для обмена переменными / массивами / объектами между js файлами:
export default myObject;
//....in another file
import myObject from './otherFile.js';
старая школа:
'require' следует использовать с 'module.exports'
module.exports = myObject;
//....in another file
var myObject = require('./otherFile.js');
Между этим есть большая разница:
import express from "express";
и это:
import * as express from "express";
правильный перевод с CommonJS на ES6
const express = require("express");
это второй импорт.
По сути, это потому, что при первом импорте вы ищете экспорт в модуле с именем . Во-вторых, вы импортируете весь экспресс-модуль с именем
express
.
Эти инструменты относятся к разным поколениям.
существует только в CommonJS (способ, которым Node.js создан для импорта и экспорта модулей в приложении) и является ES6, т. е. новым инструментом, который может использовать как браузерный JavaScript, так и серверный JavaScript (Node.js).
В дополнение к этой исторической разнице существуют различия в использовании, где более гибкий, современный и мощный, чем .
Однако важно учитывать, что некоторые браузеры до сих пор не поддерживают ES6, поэтому перед его использованием может потребоваться компиляция.
require
использует , который является «старым» (но все еще действующим) синтаксисом для экспорта модуля, который может быть чем угодно, объектом, строкой и т. д.
использует оба, т. е. вы можете использоватьmodule.exports
иexport
, и это позволяет вам экспортировать различные фрагменты кода более или менее похожие наmodule.export
делал. Одним из преимуществ является то, что он может импортировать только части того, что было экспортировано:
Примеры:
Файл, который экспортирует:
// A.js file
// CommonJS syntax
module.exports = {
foo: function(){ return 'bar';},
baz: 123
}
// ES6 syntax
export function foo(){ return 'bar';}
export const baz = 123;
// or
function foo(){ return 'bar';}
const baz = 123;
export default {foo, baz};
Файл, который импортирует:
// B.js file
// CommonJS syntax
const A = require('./A.js');
const foo = A.foo;
const baz = A.baz;
// ES6 syntax
import * as A from './A.js';
const foo = A.foo;
const baz = A.baz;
// or only
import {foo, baz} from './A.js';
Когда вы используетеexport default
(синтаксис ES6) подразумевает, что вы экспортируете только одну вещь в файл. Если это объект,import
можно импортировать только куски. Но если это, например, функция, то вы можете просто использоватьimport foo from './A.js';
не нуждаясь{}
или* as foo
.
Здесь нет ответа и больше похоже на комментарий, извините, но я не могу комментировать.
В узле V10 вы можете использовать флаг --experimental-modules
сказать Nodejs, что вы хотите использовать import
, Но ваш сценарий входа должен заканчиваться .mjs
,
Обратите внимание, что это все еще экспериментальная вещь и не должна использоваться в производстве.
// main.mjs
import utils from './utils.js'
utils.print();
// utils.js
module.exports={
print:function(){console.log('print called')}
}
исходящий из является обновлением старого модуля, откуда он был получен. В дальнейшем я буду различать синтаксическую разницу, но пока давайте разберемся, почему они обновили это.
require
это функция, которая выполняется во время выполнения, что означает, что она ведет себя как другие функции JavaScript, если вы определяете ее в середине скрипта, указанная выше часть скрипта не распознает ее, или если вы поместите ее в оператор if, она будет выполняться только в том случае, если выражение if будет истинным, или если вы поместите его в другую функцию, оно будет выполняться только при выполнении функции и т. д.
С другой стороны,import
выполняется на статическом уровне, и у него есть некоторые правила, согласно которым он всегда должен находиться на корневом уровне и не должен находиться внутри каких-либо условных операторов или функций. Из-за статического анализа JavaScript для импорта он выдаст ошибки времени компиляции, если вы это сделаете.
Это были преимущества из-за того, что команда изменила способ импорта пакетов на .
Тогда почему node все еще использует модуль CommonJs, когда ES6 лучше?
Существует огромная кодовая база, использующая модуль CommonJs в узле, который очень сложно преобразовать в ES6 из-за его поддержки в течение многих лет. Но есть много инструментов, которые позволяют нам писать код ES6 в узле, но в дальнейшем эти инструменты транспилируют его в CommonJs.
Синтаксические различия:
Импорт полностью зависит от того, как вещи экспортируются из пакета.
Если при экспорте функции или переменной используется способ экспорта по умолчанию. нравитьсяmodule.export = functionName
вCommondJs
илиexport default functionName
в этом случае импорт будет таким.
Импорт в CommonJs против ES6
const functionName = require("package/exampleFile"); // CommonJs
import functionName from "package/expampleFile.js"; // ES6.
// here you can see that we need to add .js at the end of the file
Если несколько функций экспортируются, напримерmodule.exports = {functionName1, functionName2}
вCommonJs
илиexport functionName1 export functionName2
вES6
тогда импорт будет таким.
const {functionName1, functionName2} = require("package/exampleFile"); // CommonJs
import {functionName1, functionName2} from "package/expampleFile.js"; // ES6.
Другое отличие состоит в том, что импорт не может быть вызван условно, он запускается в начале файла, тогда как мы можем вызвать require условно и где угодно.