“require(x)”和“;和“import x"

我刚刚开始研究一个小节点项目,它将与MongoDB接口。然而,我似乎不能正确地导入相关节点模块,即使我已经通过npm正确地安装了它们。

例如,下面的代码抛出一个错误,告诉我“express没有默认导出”:

import express from "express";

然而,这段代码可以工作:

const express = require("express");

我的问题是,import和variable/require方法的功能有什么不同?我想修复任何困扰我的项目上的导入,因为它似乎可能会导致更多的问题。

304061 次浏览

这个简单的图像将帮助你理解requireimport之间的区别。

enter image description here

除此之外,

使用require,你可以有选择地只加载你需要的片段,而使用import,你可以有选择地只加载你需要的片段,这可以节省内存。

对于require,加载是同步(一步一步地),另一方面,import可以是异步的(不需要等待之前的导入),因此它能表现得好一点吗 require

requireimport之间的主要区别是,require将自动扫描node_modules来查找模块,而来自ES6的import则不会。

大多数人使用巴别塔来编译importexport,这使得import的作用与require相同。

Node.js的未来版本可能会支持import本身(实际上是实验版本已经做到了),并且根据Node.js的注释判断,import不支持node_modules,它基于ES6,并且必须指定模块的路径。

所以我建议你不要在babel中使用import,但是这个特性还没有得到确认,将来可能会支持node_modules,谁知道呢?


作为参考,下面是babel如何将ES6的import语法转换为CommonJS的require语法的示例。

假设fileapp_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文件可以是这样的:

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

package.json文件中定义的build-server-file脚本是一个指令,用于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

巴别塔会将进口转化为:

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


var _get_year2 = _interopRequireDefault(_get_year);

并相应地处理对函数的所有引用。

让我举一个包含express模块的require &进口

需要

var express = require('express');

进口

import * as  express from 'express';

因此,在使用上述任何语句后,我们将拥有一个名为“express”的变量。现在我们可以将app变量定义为,

var app = express();

所以我们在'CommonJS'中使用'require',在'ES6'中使用'import'。

有关'require' &“import”,请阅读下面的链接。

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

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

新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');

我说得简单点,

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

主要区别是在需要中,整个JS文件被调用或包含。即使你根本不需要。

var myObject = require('./otherFile.js'); //This JS file will be included fully.

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

import { getDate }from './utils.js';
//Here I am only pulling getDate method from the file instead of importing full file

另一个主要区别是你可以在程序的任何地方使用require,而import应该总是在文件的顶部

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

const { getDate } = require('./date.js');

这两者之间有很大的区别:

import express from "express";

这:

import * as express from "express";

从CommonJS到ES6的正确翻译

const express = require("express");

第二个导入。

基本上,这是因为在第一个导入中,你在模块express中寻找名为express的导出。第二个是导入名称为express的整个express模块。

来自ES6import是对旧的CommonJs模块的更新,其中require来自CommonJs模块。接下来,我将区分语法差异但现在,让我们理解他们为什么更新这个。

require是在运行时执行的函数,这意味着它的行为和其他JavaScript函数一样,如果你在脚本中间定义它,脚本的上述部分不会识别它,或者如果你把它放在if语句中,它只会在if表达式为真时执行,或者如果你把它放在另一个函数中,它只会在函数执行时执行,等等。

另一方面,import在静态级别上执行,它有一些规则,它应该总是在根级别上,不应该在任何条件语句或函数中。由于JavaScript对导入进行静态分析,如果您这样做,它将抛出编译时错误。

这些优点是由于团队改变了导入包到ES6的方式。

当ES6更好的时候,node为什么还在使用CommonJs模块?

节点中有大量使用CommonJs模块的代码库,由于对ES6的多年支持,因此很难将其转换为ES6。但是有很多工具可以让我们在node中编写ES6代码,但是这些工具会把它转译成CommonJs。

语法差异:

Import完全取决于从包装中导出东西的方式。

如果在导出函数或变量时使用默认的导出方式。如CommondJs中的module.export = functionNameES6中的export default functionName,则导入将如下所示。

在CommonJs vs 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

如果多个函数像CommonJs中的module.exports = {functionName1, functionName2}ES6中的export functionName1 export functionName2那样被导出,则导入将如下所示。

const {functionName1, functionName2} = require("package/exampleFile"); // CommonJs


import {functionName1, functionName2} from "package/expampleFile.js"; // ES6.