Ответ 1
Ответ, который помогает мне понять разницу между require
и import
заключается в использовании Node.js require и ES6 import/export, который включает в себя простую диаграмму:
Я только начал работать над небольшим узлом проекта, который будет взаимодействовать с MongoDB. Тем не менее, я не могу заставить соответствующие модули узла правильно импортировать, даже если я правильно установил их через npm
.
Например, следующий код выдает ошибку и сообщает, что "экспресс не имеет экспорта по умолчанию":
import express from "express";
Тем не менее, этот код работает:
const express = require("express");
Итак, мой вопрос: в чем разница в том, как работают методы import и variable/require? Я хотел бы исправить все, что мешает моему импорту в проекте, так как это может вызвать дополнительные проблемы в будущем.
Ответ, который помогает мне понять разницу между require
и import
заключается в использовании Node.js require и ES6 import/export, который включает в себя простую диаграмму:
Основное различие между 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
, кто бы знал?
Для справки ниже приведен пример того, как babel может преобразовать синтаксис import
ES6 в CommonJS, require
синтаксиса.
Скажем, файл app_es6.js
содержит этот импорт:
import format from 'date-fns/format';
Это директива для импорта функции форматирования из пакета узла date-fns.
Связанный файл package.json
может содержать что-то вроде этого:
"scripts": {
"start": "node app.js",
"build-server-file": "babel app_es6.js --out-file app.js",
"webpack": "webpack"
}
.babelrc
файл .babelrc
может выглядеть примерно так:
{
"presets": [
[
"env",
{
"targets":
{
"node": "current"
}
}
]
]
}
Этот скрипт build-server-file
определенный в файле package.json
является для babel директивой для анализа файла app_es6.js
и вывода файла app.js
После запуска сценария build-server-file
, если вы откроете app.js
и поищите импорт date-fns
, вы увидите, что он был преобразован в следующее:
var _format = require("date-fns/format");
var _format2 = _interopRequireDefault(_format);
Большая часть этого файла - пустяки для большинства людей, однако компьютеры это понимают.
Также для справки: в качестве примера того, как модуль может быть создан и импортирован в ваш проект, если вы установите date-fns
а затем откроете node_modules/date-fns/get_year/index.js
вы увидите, что он содержит:
var parse = require('../parse/index.js')
function getYear (dirtyDate) {
var date = parse(dirtyDate)
var year = date.getFullYear()
return year
}
module.exports = getYear
Используя описанный выше процесс babel, ваш файл app_es6.js
может содержать:
import getYear from 'date-fns/get_year';
// Which year is 2 July 2014?
var result = getYear(new Date(2014, 6, 2))
//=> 2014
И Babel будет конвертировать импорт в:
var _get_year = require("date-fns/get_year");
var _get_year2 = _interopRequireDefault(_get_year);
И обрабатывать все ссылки на функцию соответственно.
Позвольте мне привести пример для включения экспресс-модуля с помощью require & import
-require
var express = require('express');
-import
import * as express from 'express';
Таким образом, после использования любого из приведенных выше утверждений у нас будет переменная с именем "express". Теперь мы можем определить переменную app как:
var app = express();
Поэтому мы используем 'require' с 'CommonJS' и 'import' с 'ES6'.
Чтобы узнать больше о 'require' & 'import', прочитайте ссылки ниже.
require - Требование модулей в Node.js: все, что вам нужно знать
import - Обновление модулей ES6 в Node.js
Здесь нет ответа и больше похоже на комментарий, извините, но я не могу комментировать.
В узле 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 используется в ES6 (ExpressJs)