简介
Node.js的一个重要概念是,你想知道处理依赖性管理的方式。这种依赖性管理是Node.js核心体验的一部分。在这篇文章中,我们将学习依赖性管理的各种模式以及Nodejs如何加载依赖性。
因此,我们可以用一个js文件来编写我们的应用程序,以满足所有的需求,但这不是模块化的。Node.js使编写模块化代码变得非常简单。
在我们深入了解细节之前,首先要回答的问题是,模块。它是什么?以及我们为什么要关心它?
简单地说,模块是一种代码,我们把它组合在一起,以达到共享和重用的目的。因此,模块允许我们将应用程序的复杂性分解成小块。这可以帮助我们理解代码,直至发现和修复错误。如果你想了解更多关于JavaScript模块系统的信息,你可以查看这个帖子。
Node使用一种设施来要求某些行为。这是以CommonJS为基础的。简而言之,为了带来一个JavaScript文件,我们使用关键字require。
我假设你已经知道Nodejs的一些基本知识。如果你是Nodejs的新手,也可以查看我之前的文章《Node.js - Introduction》,了解一些背景信息。
设置应用程序
让我们从简单的开始。我为该项目创建了一个目录,使用npm init来初始化它,并创建了两个JavaScript文件(app.js和appMsg.js)。这就是项目的模样,我们将以此作为演示的起点。另外,你可以从帖子后面提到的git repo链接中下载最终代码。

在这一点上,两个.js文件都是空的。让我们更新appMsgs.js文件,并做如下修改。

我们可以看到module.exports 关键字的使用。这种语法用于暴露一个给定文件(appMsgs.js)的属性或对象,然后可以在另一个文件中使用,在我们的例子中,这将是app.js。
在这个系统中,每个文件都可以访问称为module.exports 。因此,我们在appMsgs.js文件中暴露了一些项目,现在让我们看看app.js如何使用(要求)这些属性。
现在要引用一个文件,我们使用require 关键字。当我们require ,它将返回一个对象,这个对象将代表那段模块化的代码,所以我们把它分配给一个变量appMsgs 变量,然后简单地在console.log 语句中使用属性。当我们执行这段代码时,我们可以看到下面的输出。
所以,这个 require ,就是执行JavaScript,让它构造一个对象,这个对象曾返回给我们有一些功能。
这可能是一个类的构造函数,或者是一个有一些元素的对象,或者是一些简单的属性。这有不同的模式,我们可以导出不止一个东西,甚至可以导出复杂的对象。
因此,通过管理require ,以及module.exports ,我们可以创建这些模块化的应用程序。
所需的功能加载代码并加载一次。所以,无论这里执行的是什么代码,这都不会再执行第二次了。所以,如果别人通过require ,要求得到这个对象,它就会得到一个缓存的版本。让我们看看其他一些方法。
我改变了代码,现在不是暴露一个对象,而是导出一个function 。当作为一个函数被调用时,这个代码每次都被执行。
接下来让我们看看它在app.js文件中是如何使用的。
我们可以不调用一个属性,而是直接执行它,就像一个函数。所以,这里的区别是,每次我们执行这段代码时,函数里面的代码都会被重新执行。
下面是我们运行代码时的输出。
所以,我们已经看到了module.exports 的两种模式以及它们的区别。另一种常见的模式,你要注意把它作为一个构造方法。让我们看看这个例子。

而这里是更新后的app.js文件。
所以,这在本质上是和你在JavaScript中创建一个伪类并允许你创建它的实例是一样的。
下面是这个变化的输出。
现在,让我们看看这些模式的另一个例子。
我创建了一个名为userRepo.js的新文件,如下所示。

而这里是app.js和这个变化的执行结果。

对单个文件使用require并不罕见,但还有一种模式你应该注意。接下来让我们看看文件夹的依赖性。
文件夹依赖性
我们将退一步理解Nodejs如何寻找依赖关系。还记得前面例子中的那行字吗?
Node仍然会寻找appMsgs.js文件,但也会寻找appMsgs这个目录,无论先找到哪一个,都会把它拉进来。
现在让我们看看代码。
我创建了一个名为logger的文件夹,在该文件夹中,我创建了一个index.js文件。
这里是index.js文件的代码。
这里是app.js文件,它需要这个模块。

因此,在我们的案例中,我们可以说。
而这将是完全有效的。但相反,只要说以下这句话就可以了。
由于没有logger.js,有一个logger目录,它将默认加载index.js作为我们logger的起点。这就是为什么我给了index.js这个名字,让我们看看执行这个代码的结果是什么。
那么,就其本身而言,你可能会想,为什么要费力地通过这个额外的步骤来创建一个文件夹和一个inex.js?
原因是你可能会把一个复杂的依赖关系放在一起,而这个依赖关系可能还有其他依赖的部分。需要记录器的调用者不需要知道有一堆其他的依赖关系。
这是一种封装形式,以便我们在构建更复杂的部分时,可以从多个文件中构建它们。然后在消费者方面,使用单个文件。这只是暗示,文件夹是管理这些依赖关系的好方法。
节点包管理器(NPM)
我们还想简单讨论的一件事是NPM。你可能已经知道它的目的。这带来了额外的功能,而且它的用法非常简单明了。
我们可以使用npm安装一个依赖项。
npm install underscore;
然后可以简单地在app.js中要求它,如下所示。
你可以看到我们如何使用underscore包所提供的功能。此外,当我们需要这个模块时,我们没有指定文件路径,我们只是使用它的名字,Nodejs将从你的应用程序中的node_modules文件夹中加载这个模块。

这里是执行时的输出。
小结
在这篇文章中,我们了解了Nodejs是如何管理其依赖关系的,并且我们看到了一些在我们的应用程序中使用的模式。你可以从这个Git资源库下载源代码。如果你有任何问题或意见,请告诉我。下次再见,祝你编码愉快
主题。
nodejs, 清洁代码, javascript