"require(x)"和import x之间的区别

aus*_*ive 82 import require node.js typescript

我刚刚开始研究一个与MongoDB交互的小节点项目.但是,我似乎无法正确导入相关的节点模块,即使我已正确安装它们npm.

例如,以下代码抛出并出错,告诉我"express没有默认导出":

import express from "express";
Run Code Online (Sandbox Code Playgroud)

但是,此代码有效:

const express = require("express");
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,import和variable/require方法的功能有何不同?我想解决困扰我项目进口的任何问题,因为它似乎可能会导致其他问题.

Alw*_*nny 79

即使在SO上,也有很多关于你的问题的在线资源.你可以在这里看到,但简单的答案,可以帮助我明白之间的差别require,并import使用Node.js的要求与ES6导入/导出

图片简单:

在此输入图像描述

  • 影响代码的最大区别是 CommonJS 模块中的导出是“计算的”,而 ESM 模块中的导出是静态的(预定义的)。JS 只需解析代码(尚未运行)即可确定 ESM 模块中的导出。在 commonJS 模块中,导出仅在模块实际运行时才知道,并且当模块初始化代码完成运行时,您会看到分配给“module.exports”的内容。在尝试使单个模块同时适用于 ESM 和 CommonJS 时,仅此差异就会造成兼容性问题。 (17认同)
  • 稍微多一点解释就好了...而是要求其他地方阅读答案... (11认同)
  • ESM 模块对捆绑器更友好,但对编码器的限制更大,因为您无法在 ESM 模块中进行计算导出。 (4认同)
  • “ESM”= ECMAScript 模块。我提到这一点是为了像我这样主要编程不是 JavaScript 的读者。以下是 JavaScript 中模块声明的快速概述 https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm (4认同)
  • >`你不能用 require 有选择地只加载你需要的部分:至少使用 Node.js 你**可以**用 `require` 有选择地只加载你需要的部分。对于[示例](https://nodejs.org/api/buffer.html#buffer):`const { Buffer } = require('node:buffer');`。 (4认同)

Ayo*_*Lee 50

require和之间的主要区别import是,它require会自动扫描node_modules以找到模块,但是import,它来自ES6,不会.但现在大多数人会用巴贝尔编译importexport,这将使import作用一样require,但未来的Node.js的版本可能支持import本身(实际上,实验版已经没有),并通过Node.js的判断笔录,import赢得了"支持node_modules,它基于ES6,并且必须指定模块的路径.

所以我建议你不要使用importbabel,但这个功能尚未确认,它可能会支持node_modules将来,谁会知道?

  • `import 不支持 node_modules` 你是什么意思? (5认同)
  • 啊啊啊啊。Babel 尚未安装在这个特定项目上,这使得一切都有意义。我认为 ES6 导入/导出已经可以使用了,但现在我明白 Babel 只是将所有内容更改为“require” (2认同)
  • `import` 和 `require` 都会扫描 `node_modules` 来查找语句指定的包。`require` 将包中分配给 `module.exports` 的任何内容加载到它分配给的变量中,如果没有声明左手,则加载到全局范围。但是,“import”只会按名称加载 es6 默认导出,除非所有导出都分配给别名:“import * as X from 'pkg'”。您也可以使用*对象解构*导入没有默认值的 es6 包:`import { X } from 'pkg'`。如果您将整个包(包括所有导出)导入到全局范围“import 'package'”,那么它的工作方式与“require”相同。 (2认同)

pra*_*nde 18

我会让它变得简单,

  • 导入和导出是 ES6 特性(下一代 JS)。
  • Require 是从其他文件导入代码的老派方法

主要区别在于require,整个 JS 文件被调用或包含。即使你不需要它的一部分。

var myObject = require('./otherFile.js'); //This JS file will be included fully.
Run Code Online (Sandbox Code Playgroud)

而在导入中,您只能提取所需的对象/函数/变量。

import { getDate }from './utils.js'; 
//Here I am only pulling getDate method from the file instead of importing full file
Run Code Online (Sandbox Code Playgroud)

另一个主要区别是您可以require在程序中的任何位置使用asimport应该始终位于文件顶部

编辑:在最新的节点版本中,您可以使用解构。它看起来像这样

const { getDate } = require('./date.js');
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过 `require` 使用对象解构,例如 `const { getDate } = require('./utils.js');` (4认同)
  • 你的整体解释太简单而且不准确。即使是关于在程序中的任何位置使用“require”而仅在文件顶部使用“import”的声明也掩盖了重要的细节。当您使用作用域为函数(或应用程序代码中的块作用域)而不是模块/文件的“require”时,这与 ES 模块等效(也称为“import”语法)。不过,这是一个异步操作,这种“动态导入”需要使用`.then()`或`await`关键字。 (2认同)

Vin*_*ius 13

这之间有很大的区别:

import express from "express";
Run Code Online (Sandbox Code Playgroud)

和这个:

import * as express from "express";
Run Code Online (Sandbox Code Playgroud)

从 CommonJS 到 ES6 的正确翻译

const express = require("express");
Run Code Online (Sandbox Code Playgroud)

第二次导入。

express基本上,这是因为在第一次导入中,您正在名为 的模块中查找导出express。第二个是导入带有 name 的整个express模块express​​。

  • 这就是给我“顿悟时刻”的原因。你解释的方式非常有道理 (2认同)

LaZ*_*Zza 12

新的 ES6:

'import' 应该与 'export' 关键字一起使用,以在 js 文件之间共享变量/数组/对象:

export default myObject;

//....in another file

import myObject from './otherFile.js';
Run Code Online (Sandbox Code Playgroud)

老学校:

“require”应该与“module.exports”一起使用

 module.exports = myObject;

//....in another file

var myObject = require('./otherFile.js');
Run Code Online (Sandbox Code Playgroud)


sai*_*gde 8

让我举一个包括带有require和import的快递模块的例子

-要求

var express = require('express');
Run Code Online (Sandbox Code Playgroud)

-进口

import * as  express from 'express';
Run Code Online (Sandbox Code Playgroud)

所以在使用上述任何一个语句后,我们将有一个名为'express'的变量.现在我们可以将'app'变量定义为,

var app = express(); 
Run Code Online (Sandbox Code Playgroud)

因此我们将'require'与'CommonJS'一起使用,'import'与'ES6'一起使用.

有关'require'和'import'的更多信息,请阅读以下链接.

require - 需要Node.js中的模块:你需要知道的一切

import - Node.js中ES6模块的更新

  • 这绝对是正确的答案。发帖者在使用 es6 `import` 语句时遇到问题,并且对 **express has no default export** 错误感到困惑。这个答案提供了解决方案。具有多个(甚至单个)导出但未定义“默认导出”的模块将需要将所有导出分配给命名变量,正如答案所解释的:“import * as无论来自'package';” (4认同)