node.js中的模块机制

模块机制

在学习模块机制的时候,可以结合es6中的模块化来理解。

1.什么是模块

(1).模块是啥?

在js中的模块化开发中,模块其实就是文件。
模块和文件是一一对应的。
一个模块就是一个文件。反之,一个文件对应于一个模块。

模块是Node.js应用程序的基本组成部分。

(2).为什么需要模块

以前,我们的js都是在浏览器端来运行的。
我们的代码,通常会写成这个样子的:
在这里插入图片描述
但是,现在不是在浏览中来运行js,而是在node环境中来运行js。
我们的代码都是js代码,根本就没有html。

如果编写如下代码,只会出错:
在这里插入图片描述
实际上,以前,在浏览器端,js文件也不能相互引用。之所以不影响最终的开发,只是因为它借助了html文件来引入。

在服务端情况就完全不一样。如果我们不能在js文件中引入js文件,开发将无法开展。

为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。

(3).js模块化发展简史

在这里插入图片描述

在node.js中,一般都使用commonjs的模块化
在浏览器端,一般都使用es6的模块化方案

基于此,我们必须要掌握两种模块化方案:

  • CommonJS
  • Es6的模块化

模块化在服务端是必须的,这是在js文件中引入js文件的唯一方式。

在浏览器端,模块化主要解决如下两大问题:

  • 避免全局变量污染
  • 更好的实现文件依赖

(4).具体表现为哪些文件?

在node中,如下三种文件都可以作为模块来引入
js文件,以.js作为后缀的
Json文件,以.json为后缀的
基于C/C++的json扩展文件,以.node为后缀的。

回顾一下,请问,在浏览器端,哪些文件可以作为模块引入?
js文件
css文件
图片文件
vue文件

2.Node.js常见模块

在node中,模块有不同的表现形式,其使用方式也有差异。

基本上,我们可以将node.js中的模块分为两种:
核心模块(系统模块)
用户模块

(1).核心模块

核心模块,也叫系统模块,是node.js自带,只要安装了node.js,它就已经具备了这些模块。
是可以直接引入并使用的。
系统模块在源代码中已经编译了,以二进制文件存在,模块引入时可以直接加到内存。
常见的核心模块有http、fs、path、url。

比如:
在这里插入图片描述

提示:如果你安装了webstorm,并使用它来编辑代码,运行代码。就有这么一个文件夹。
核心模块是我们学习的重点。

(2).用户模块

所有非核心模块,都属于用户模块。
实际上,用户模块,有可以分为两种:

  • 第三方模块
  • 自定义模块

通常来说,第三方模块也是自定义模块,只不过这个模块更为通用,强大,然后将其开源了,发布到npm社区,所有的开发人员都可以下载使用的

3.载入模块

Node.js默认是使用CommonJS规范,就包含两个东西:

  • require方法,用于载入模块
  • module.exports对象,用于导出模块

在node.js中,要载入模块,必须要使用requrie方法。

格式:const 模块 = require(模块名);

在使用require的时候,需要分成如下三种情况来讨论:
核心模块
第三方模块
自定义模块

(1).核心模块

这是最简单的,因为核心模块是node自带。只需要传入模块的名称即可。
如:在这里插入图片描述

注意,常量的名称可以是随意的,但是为了语义,尽量和模块名称保持一致。
不能再加任何和路径相关的写法,否则就出错了:
在这里插入图片描述

(2).第三方模块

属于用户模块,是非核心。
所以,必须要分两步完成:

  • 先下载
  • 然后使用require引入

比如,有一个非常知名的第三点工具库–

第一步,使用npm 下载之,如下:

在这里插入图片描述

第二步,引入使用,如下:
在这里插入图片描述

lodash官网:https://lodash.com/
在这里插入图片描述

除了,需要安装之外,引入的方式是一致的,只需要写上模块名即可。千万不要画蛇添足,加任何路径的写法。

注意:第三方模块和核心模块的引入写法是一模一样的,但是其原理是有区别的。
核心模块是已经被编译好了,本身就存在于内存中。
第三方模块,其实是放在当前的node_modules文件夹中的。

关于node_modules文件夹的查找机制:
首先,会在当前目录查找node_modules,如果有,就用这个来查找对应的模块,如果没有node_modules这个目录,继续向上一级目录,重复这个过程,直到根目录(windows下就是磁盘目录),如果仍然没有找到,就报错。

在使用npm命令安装的时候,也会有这种机制。在使用npm 命令时候,没有携带–save或者–save-dev选项的时候,就会使用这种查找机制。

(3).自定义模块

需要分成两步:
第一步,需要定义一个模块
第二步,引入自定义模块

第一步,定义一个模块
此处,使用一个空文件来作为一个模块。如下:在这里插入图片描述

第二步,使用require引入,如下:

在这里插入图片描述

注意:
对于自定义模块,必须要使用相对路径来引入,必须是使用./或者…/开头。否则报错:
在这里插入图片描述
文件的后缀名是可以省略的,包括js后缀和json后缀。如下:
在这里插入图片描述

一旦省略了后缀,引入机制有些变化,依照 目录 ->.js-> .json-> .node 的顺序进行查找,如果所有模块路径都找不到该文件,则抛出异常。
如果require的是文件夹名称,默认会引入该文件夹下的index.js文件,如下:
在这里插入图片描述

还需要注意:针对核心模块和第三方模块,千万不要画蛇添足加上.js后缀。

基于Commonjs的require引入,这些所有的原理和细节,es6中的import同样遵循。

4.自定义模块实现

(1).使用module.exports导出模块

在开发中,会经常需要使用自定义模块。
它的整体的过程如下:
在这里插入图片描述

重点是创建模块,和导出模块。
可以和es6中的export进行对比。
在CommonJS规范中,导出模块使用的module.exports对象。

换言之,module.exports 是一个全局变量。可以直接在js文件中对其赋值。
在使用require方法引入一个模块的时候,返回的就是module.exports。
module.exports默认是空对象。
所以,针对一个空js文件,引入之后的结果是{}。

所以,在导出模块的时候,就可以直接给module.exports赋值即可。如下:

在这里插入图片描述
再比如:
在这里插入图片描述

(2).exports对象

在CommonJS中,导出模块是通过module.exports来实现的。
在CommonJS中,使用requrie方法,得到的结果就是module.exports。
在CommonJS中,给module.exports起了一个别名—exports。

所以,在有些地方,它是使用exports来导出的。如下:
在这里插入图片描述

如果这么写:
在这里插入图片描述

这种写法是错误的。

所谓的起别名,就是 相当于,定义了exports对象,然后将module.exports的值赋给它。
好比是执行了如下代码:
exports = module.exports

如果,你做了如下操作:
exports = {
add,
sub,
}
这就意味着,exports指向了新的对象,不再指向module.exports,二者毫无关系。
而require方法真正返回的module.exports。

这么写为什么可以?
在这里插入图片描述

因为,此时只是给exports对象添加了新的属性,和module.exports还是指向同一个对象,相当于给module.exports添加了属性。

注意:
自己在导出模块的时候,尽量使用module.exports
如果看到别人的代码,要理解exports的作用及用法

强调一下:
CommonJS主要是node平台上使用。
Es6的模块化主要是浏览器端开发来使用。

但是,

  • 在浏览器端,其实也是可以使用CommonJS规范的,尤其是基于webpack的开发。
  • 在不久的将来,在node中,也是可以直接使用es6的import和export。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值