网易首页 > 网易号 > 正文 申请入驻

服务器端JavaScript运行环境Node.js的依赖性管理

0
分享至

【51CTO.com快译】众所周知,Node.js是一个基于Chrome V8引擎的服务器端JavaScript运行环境。它采用了一种事件驱动的、非阻塞式的I/O模式,运行起来既轻量级又高效。诚然,我们可以使用单个js文件,来编写出应用程序所涉及到的全部内容,但这样既不灵活,又不够模块化。而Node.js的出现,让模块化代码的编写变得非常简便。因此,对于Node.js的核心,我们需要理解和掌握的一个重要概念便是:依赖关系的管理。本文将和您一起探讨依赖项管理的各种模式,以及Nodejs是如何加载依赖项的。

在深入探讨细节之前,让我们首先弄清楚什么是模块。简而言之,模块是一段代码。为了共享和重用,我们需要将代码进行分组放置。通过模块,我们可以将复杂的应用程序分解到小块代码中。同时,模块也能够帮助我们理解程序代码的意图,并发现或修复各种错误。如果您想深入了解有关JavaScript模块系统的相关知识,请参见--https://hexquote.com/javascript-module-system/。

自2009年以来,CommonJS便实现了Javascript的模块化规范。它规范了模块的特性和各个模块之间的相互依赖性。由于每个文件都被当作一个模块(通常,module变量代表了当前模块),而且有自己的作用域,因此每个文件里面的变量、函数、以及类,都是私有的,且对于其他模块是不可见的。而模块的exports属性便是对外的接口。只有通过exports导出的属性,才能被其他模块识别和加载。而Node是基于CommonJs规范来实现模块的同步与加载。也就是说,我们可以通过在模块中调用require()方法,来接收模块的标识,并根据node的模块引入规则,引入其他模块,进而调用对应的属性和方法。

在此,我假设您已经掌握了Nodejs的上述基础知识。当然,如果您是一名Node.js的新手,则可以通过查看Node.js的相关简介(https://dzone.com/articles/nodejs-introduction),来了解更多背景信息。

设置应用

让我们从最简单的开始。假设我已经为某个项目创建了一个目录。通过运用npm init命令对其初始化后,我们将创建app.js和appMsg.js,两个JavaScript文件。下图展示了本项目的目录结构,我们将其作为管理的起点。如果您感兴趣的话,可以从文末给出的git存储库链接中,下载该项目的最终源代码。

默认情况下,这两个.js文件均为空。让我们通过如下更改,来更新appMsgs.js文件。

上面的代码段展示了module.exports关键字的用法。此语法用于公开给定文件(此处为appMsgs.js)中的属性或对象,以便能够在另一个文件(如本例中的app.js)中被直接使用到。

在该系统中,每个文件都可以访问到名为module.exports的文件。因此,我们在appMsgs.js文件中公开了一些项目,以方便观察app.js是如何使用(require)某些属性的。

显然,require关键字可以方便我们引用某个文件。也就是说,当我们执行require时,它将返回一个代表着模块化代码段的对象。因此,我们可以将其分配给一个appMsgs变量,然后在console.log的语句中简单地使用该属性。当代码被执行时,我们将看到如下输出:

该require通过执行JavaScript,构造出一个具有某种功能函数的对象,作为返回。它们既可能是一个类构造函数,又可以是其中包含了许多元素、或一些简单属性的对象。针对不同的模式,我们既可以导出多个对象,又可以导出那些复杂的对象。可见,通过require和module.exports,我们可以创建出模块化的应用程序。

值得注意的是,应用程序所需的功能函数只会仅加载代码一次。也就是说,无论执行了什么代码,它们都不会被执行第二次。那么,如果别的程序也要通过require来获取对象的话,它将只能获得该对象的缓存版本。

下面,让我们来看看导出的方式。

如上面代码段所示,我对前面的代码进行了更改。现在,我不再公布对象了,而是导出了一个功能函数(function)。该函数在每次被调用时,都需要执行该代码。

下面,让我们来看看如何在app.js文件中使用它:

除了调用某个属性,我们还可以像执行函数一样去执行它。因此,这里的区别主要是,每当我们执行该代码时,函数内部的代码都会被重新执行(re-executed)。

下面是我们重新运行该代码段的输出:

至此,我们已经看到了module.exports的两种模式,及其两者的区别。还有一个常见的模式是,将其用作构造器方法(constructor method)。下面,让我们再来看一个例子:

下面是更改过的app.js文件:

从本质上讲,这与您在JavaScript中创建伪类(pseudo-class),并且创建它的各种实例(instances)是一致的。

下面是更改后的输出:

接着,让我们接着讨论此类模式的另一个示例。如下代码段所示,我创建了一个名为userRepo.js的新文件。

下面是更改后的app.js文件。

下图是该更改被执行后的结果:

当然,针对单个文件都去使用require的情况并不常见。接下来,让我们再讨论另一种模式--文件夹的依赖性。

文件夹依赖性

为了弄清Node.js是如何查找依赖性的,让我们重温一下前面例子中的JavaScript代码:

var appMsgs = require(“ ./appMsgs”)

Node不但会查找appMsgs.js文件,而且会查找作为目录的appMsgs,并取出它的值。

我创建了一个名为logger的文件夹,并在其中创建了一个index.js文件,其内容如下面的代码段所示:

下面是require此模块的app.js文件:

可见,在本例中,我们可以写出这样的JavaScript代码:

var logger = require(“./logger/index.js”)

上述较长的路径形式肯定是正确的。但是,我们其实只需写出如下的JavaScript代码即可:

var logger = require(“./logger”)

由于没有logger.js,而只有logger目录,因此在默认情况下,Node将加载index.js作为logger的起点。我们可以通过如下命令,来验证其输出结果:

在此,您可能心生疑虑:我们为什么如此费尽周折地创建文件夹和index.js呢?其背后的原因在于:您可能会将一些复杂的依赖项放在一起,而这些依赖项也可能还有其他的依赖项。而对于需要logger的调用者(caller)而言,它们不需要知道其他依赖项的存在。

这便是一种封装形式(encapsulation)。我们完全可以在多个文件中,构建更为复杂的代码段;而在使用者(consumer)角度,它们只需使用一个文件足矣。可见,文件夹是管理此类依赖性关系的更好方法。

Node程序包管理器(NPM)

第三类值得我们探讨的依赖性管理是NPM。顾名思义,NPM是Node.js程序包的管理和分发工具,它相当于后端的Maven。它可以让Javascript开发者更加轻松地共享和共用代码段。

通常,我们可以使用如下npm命令,来安装依赖项:

npm install underscore;

如下代码段所示,我们也可以简单地在app.js中require它:

如您所见,我们可以通过underscore的软件包来使用各项功能。同理,当需要用到此类模块时,我们并没有指定文件的路径,而只需使用其名称即可。Node.js将会从您的应用程序的node_modules文件夹中,自动加载到其对应的模块。

下面是代码执行后的输出结果:

小结

综上所述,我们讨论了Node.js是如何管理其依赖性关系的。您可以从此Git存储库—https://github.com/jawadhasan/nodedependency处,下载上述示例的源代码。

原文标题:Node.js – Dependency Management,作者: Jawad Hasan Shani

【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
小米汽车宣布,再造一条智能生产线,预计产能75万

小米汽车宣布,再造一条智能生产线,预计产能75万

798守夜人
2024-05-20 15:59:09
动真格得了!北京、上海都开始严查电动车,有史以来最严的一次!

动真格得了!北京、上海都开始严查电动车,有史以来最严的一次!

嘿哥哥科技
2024-05-20 07:53:44
汪峰带李巧见家长,女方背5.5w包包,全程紧牵女方手或再次领证!

汪峰带李巧见家长,女方背5.5w包包,全程紧牵女方手或再次领证!

八卦爱侃娱
2024-05-18 10:26:14
哦豁!俄罗斯库什切夫斯克空军基地被锤爆,机场停有数十架战斗机

哦豁!俄罗斯库什切夫斯克空军基地被锤爆,机场停有数十架战斗机

娱宙观
2024-05-19 22:39:19
幼儿园抽签要带28份榴莲,妈妈果断选择请假,被带草莓家长内涵

幼儿园抽签要带28份榴莲,妈妈果断选择请假,被带草莓家长内涵

影孖看世界
2024-05-17 19:42:59
两大豪门再聚首!霍震霆全程礼让梁安琪惹争议,霍启山好绅士

两大豪门再聚首!霍震霆全程礼让梁安琪惹争议,霍启山好绅士

裕丰娱间说
2024-05-20 10:18:34
大反转!美国芯片企业欲重返中国市场,没想到却遇更严审查

大反转!美国芯片企业欲重返中国市场,没想到却遇更严审查

田间农人阿馋
2024-05-20 15:48:51
伊朗媒体称伊方证实与美举行间接谈判

伊朗媒体称伊方证实与美举行间接谈判

界面新闻
2024-05-19 16:46:46
媒体人:沈祥福随杨晨前往河南,高洪波外甥也将加入

媒体人:沈祥福随杨晨前往河南,高洪波外甥也将加入

懂球帝
2024-05-20 11:56:16
将军石华杰,履新职!

将军石华杰,履新职!

政知新媒体
2024-05-20 17:22:25
香港卫视未将破坏黄家驹墓碑男子打码,弟弟发文谴责破坏者

香港卫视未将破坏黄家驹墓碑男子打码,弟弟发文谴责破坏者

映射生活的身影
2024-05-19 19:58:29
物是人非渣叔2015年首战首发 昔日11人全不在队中

物是人非渣叔2015年首战首发 昔日11人全不在队中

直播吧
2024-05-19 22:28:49
赖清德下令转守为攻,话音刚落,岛内爆发激烈冲突,邱毅预感不妙

赖清德下令转守为攻,话音刚落,岛内爆发激烈冲突,邱毅预感不妙

大白话瞰世界
2024-05-19 10:34:19
刘湘,中国游泳冠军,魅力无人能挡

刘湘,中国游泳冠军,魅力无人能挡

洪瑞时光
2024-05-19 13:19:08
俄在库皮扬斯克方向攻击阿尔捷米夫卡,实现对哈尔科夫从东侧包夹

俄在库皮扬斯克方向攻击阿尔捷米夫卡,实现对哈尔科夫从东侧包夹

娱乐圈的哔哔王
2024-05-20 19:44:25
台媒独家爆料,大S的母亲近期主动联系曾悉心照料孩子们的保姆

台媒独家爆料,大S的母亲近期主动联系曾悉心照料孩子们的保姆

楚楚的留香
2024-05-20 13:23:26
乌军王牌飞行员阵亡备受关注!俄记者:他的战机是在与俄军空战中被击落的

乌军王牌飞行员阵亡备受关注!俄记者:他的战机是在与俄军空战中被击落的

环球网资讯
2024-05-20 06:48:21
北京,曾先生花费1590万购买了一套别墅,原房主仅将别墅过户给了曾先生

北京,曾先生花费1590万购买了一套别墅,原房主仅将别墅过户给了曾先生

科学发掘
2024-05-14 07:35:08
天津小伙要娶非洲黑美人,中国妈妈表示:无法接受!接下来怎么办

天津小伙要娶非洲黑美人,中国妈妈表示:无法接受!接下来怎么办

爱笑橡皮1e2k
2024-05-09 19:40:02
替罪羊大结局,康哥往宁哥的伤口上撒盐

替罪羊大结局,康哥往宁哥的伤口上撒盐

金昔说故事
2024-05-20 16:56:19
2024-05-20 20:28:49
Nodejs开发
Nodejs开发
分享只有程序员懂的干货
648文章数 824关注度
往期回顾 全部

科技要闻

理想 Q1营收同比增长36% 交付指引不及预期

头条要闻

3人因1只鹦鹉获刑 法院撤销一二审有罪判决发回重审

头条要闻

3人因1只鹦鹉获刑 法院撤销一二审有罪判决发回重审

体育要闻

8年半,讲不出再见

娱乐要闻

王俊凯现身蔡依林演唱会,牵手唱歌!

财经要闻

韵达快递乱象:管理以罚代管 新政落地难

汽车要闻

智驾升级/月底上市 问界新M7 MAX焕新版

态度原创

时尚
教育
数码
本地
军事航空

疗愈自我,从容远行

教育要闻

三年级面积问题,用一段16米的篱笆围一个养鸡场,面积是多少?

数码要闻

华为FreeBuds SE 2香芋紫与曜石黑新色来袭,引领无线耳机新潮流

本地新闻

强制开锁展铁腕 “交叉执行”勇亮剑

军事要闻

80万人逃离拉法 以战时内阁现分歧

无障碍浏览 进入关怀版