概述
在处理Node.js项目时,我们经常遇到需要在其他文件中重用我们的代码,或者将任何模块中存在的一些功能引入我们的代码。那么,为了实现这种代码模块化和模块的处理,我们必须知道如何在我们的程序中导入和导出模块。
介绍
模块的导入和导出有助于将复杂的长代码片段分解为称为模块的较小部分,以便于调试和管理,其中模块是封装在单个或多个文件中的代码块,以方便与应用程序相关的功能。导入和导出还有助于代码的可重用性,并将已创建的第三方模块(如:express、mongoose 等)的功能引入我们的项目。
Node.js主要有两个模块系统,即 CommonJS 模块和 ECMAScript 模块。CommonJS 是默认的模块系统。我们可以在这两个模块系统中以不同的方式进行导入和导出。
创建模块
在 CommonJS 脚本系统中,当我们创建一个 javascript 文件或扩展名为“.js”的文件时,该文件可以用作模块。类似地,在 ES6 脚本系统中,我们需要创建一个扩展名为“.mjs”的文件,使其成为一个模块。
导出模块
模块中的导出是通过 export 语句完成的,该语句告诉Node.js要导出哪段代码(即函数、文字、对象等)。
在 CommonJs 模块系统中,export语句中使用了 module.exports 对象。然而,在 ES6 (ECMAScript) 模块系统中,使用 export 对象而不是 module.exports。因此,无论将什么值分配给 module.exports 或 export,这些值都会作为模块公开。
在 ES6 中导入的语法:
export { msg1, msg2 }
导出文本的示例
message.js
// message.js
module.exports = 'Hello World!'
app.js
// app.js
const msg = require('./message.js')
console.log(msg)
输出:
PS C:\WebApp> node app.js
Hello World!
解释:
在这里,require() 函数在app.js中用于导入 message.js 模块,并在 require 函数的参数中使用模块的路径,即提供message.js。在上面的示例中,字符串文本是从 message.js 导出的。
注意:
在module.exports中,exports是一个对象,因此我们可以将属性或方法附加到exports对象。
通过导出对象导出属性
desc.js
// desc.js
module.exports.name = 'Sachin'
module.exports.age = 20
app.js
// app.js
const person = require('./desc.js')
console.log(person.name, ',', person.age)
输出:
PS C:\WebApp> node app.js
Sachin , 20
说明:
此处,name 和 age 是附加到导出对象的两个属性,是从desc.js导出的。
导出对象的导出方法
greeting.js
// greeting.js
module.exports.greet = function (name) {
console.log('Welcome', name)
}
app.js
// app.js
const msg = require('./greeting.js')
msg.greet('Sachin')
输出:
PS C:\WebApp> node app.js
Welcome sachin
说明:
在这里,greet 方法附加到导出对象,并从greeting.js导出。
导出函数
areaOfSquare.js
// areaOfSquare.js
function area(x) {
return x * x
}
module.exports = { area }
app.js
// app.js
const square = require('./areaOfSquare.js')
console.log(sqare.area(5))
输出:
PS C:\WebApp> node app.js
25
说明:
此处,功能区域是从areaOfSquare.js导出的。
导入模块
导入模块意味着将不同模块中存在的所需功能包含在当前程序中。
在 CommonJs 模块系统(默认模块系统)中,import 模块中使用了 require() 函数。然而,在 ES6 (ECMAScript) 模块系统中,使用 import 关键字而不是 require() 函数。
Node.js有三种类型的模块:
- 核心模块:这些是内置模块,如:
http、fs 等。 - 本地模块:
这些模块由程序员在本地创建。 - 第三方模块:
这些模块可在安装后使用 NPM(节点包管理器)使用,例如:express、mongoose 等。
在 ES6 中导入的语法:
import { msg1, msg2 } from 'module_name'
在 Node.js 中导入不同类型模块的语法和示例
导入核心模块
语法:
var test = require('module_name')
例:
var http = require('http')
导入本地模块
为了加载本地创建的模块,我们可以通过以下方式提供所需函数的路径。
使用绝对路径
语法:
var test = require('/<folder1>/<folder2>/.../module')
例:
var http = require('/lib/obj/util.js')
使用相对路径
我们还可以使用 ./ 或 .. 提供相对路径。/ 在 require 函数中,其中 (./) 单个点转换为当前目录,而 (../) double dots 转换为父目录。
语法:
var test = require('./module_name')
例:
var hello = require('../hello.js')
注意:
在上面的示例中,您可以删除.js扩展名,即,如果您不提供任何扩展名,则 Node 会搜索具有该module_name和.js扩展名的文件并加载它。
使用文件夹路径
您也可以仅按文件夹路径加载模块:
var test = require('./folder_name')
例:
var hello = require('./lib')
默认情况下,节点在该文件夹中查找index.js文件并加载它。否则,我们还可以在该文件夹中创建一个package.json文件,在其中我们可以定义默认情况下要加载的节点模块名称。
导入时解构语法
我们先来了解解构,它可以理解为构造的反义词。因此,在 JavaScript 的世界里,构建只是将数据组合成一个对象,而解构只是从对象中提取数据。在导入和解构时,我们需要命名导入,解构有助于在我们的程序中进行简洁的导入,从而节省内存并使程序更有效率。
例子:
details.js
// details.js
const FirstName = 'sachin'
const LastName = 'sahara'
export { FirstName, LastName }
app.js
// app.js
import { FirstName, LastName } from './details.js'
console.log(FirstName)
输出:
PS C:\WebApp> node app.js
sachin
结论
- 在 CommonJS 模块系统中,require() 函数包含模块,module.exports 用于导出模块。
- 在 ES6 或 ECMAScript 模块系统中,import 包含模块,export 用于导出模块。
- exports in module.exports 是一个对象,因此我们可以在导出时使用此特性将属性或方法附加到它。
- 导入是根据模块的类型完成的,即核心模块、本地模块或第三方模块。
- 通过重组,我们可以使导入更具可读性和简洁性,这也有助于提高程序的效率。