Node.js中模块化
模块分类
内置模块:Node.js官方停供,如fs,path,http等
自定义模块:用户创建的js文件
第三方模块:第三方开发出来的模块,使用需要下载
加载模块
使用require()方法,加载模块。(加载其他模块时,会执行被加载模块中的代码)
//加载内置模块
const fs = require('fs')
//加载自定义模块
const another = require('xxx.js')
//加载第三方模块
const moment = require('moment')
Node.js 中的模块作用域
在自定义模块中定义的变量,方法等成员,只能在当前模块访问,这种访问限制叫做模块作用域。(能够防止全局变量污染问题)
向外共享模块和其中的成员
(1)module对象
每个 .js 自定义模块中都有一个 module 对象,使用console.log(module)查看其内容:
(包含路径,文件名等)
(2)module.exports对象
在自定义模块中,使用 module.exports 对象,将模块内的成员共享出去。
其他模块使用require() 方法导入自定义模块时,得到的就是 module.exports 所指向的对象。
(3)export对象
为了简化向外共享成员的代码,Node 提供了 exports 对象。默认情况下,exports 和 module.exports 指向同一个对象。但是最终共享的结果是以 module.exports 指向的对象为准。
Node.js 中的模块化规范
遵循了CommonJS 模块化规范,CommonJS 规定了模块的特性和各模块之间如何相互依赖。规定如下:
- 模块内部module 变量代表当前模块。
- module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。
- 加载模块就是加载该模块的 module.exports 属性。使用require() 方法加载模块。
npm与包
Node.js 中的第三方模块又叫做包。
包是由第三方个人或团队开发出来的,免费供所有人使用。
包提供更方便的API,提高开发效率。
下载包网址:https://www.npmjs.com/
在项目中安装包的命令
npm install 完整包的名称(@加指定版本号)
简写: npm i 完整包的名称
注意:
(1)初次装包完成后,项目文件夹下多一个node_modules 的文件夹和 package-lock.json 的配置文件。
(2)node_modules 文件夹用来存放所有已安装到项目中的包。可以从这个目录中查找并加载包,使用require() 导入第三方包。
(3)package-lock.json 配置文件用来记录 node_modules 目录下的每一个包的下载信息,例如包的名字、版本号、下载地址等。
包管理配置文件
npm 规定在项目根目录中,必须提供一个叫做 package.json 的包管理配置文件。记录与项目有关的一些配置信息。例如:
项目的名称、版本号,还有项目中都用到了哪些包等
快速创建 package.json
在项目所在目录下执行:
npm init -y
package.json文件中有dependencies 节点,专门记录使用 npm install 命令安装了哪些包。
(在拿到去除node_modules的项目后,使用npm i 一次性安装所有的包)
devDependencies 节点记录开发阶段所用到的包,
dependencies 节点记录开发和上线都用到的包。
(安装包时加上 -D 或者 --save-dev 可以把包记录到devDependencies节点中)
卸载包
npm uninstall 包的名称
解决安装包速度慢的问题
使用淘宝NPM镜像来代替NPM,安装如下(具体可参照网络文章):
npm install -g cnpm --registry=https://registry.npm.taobao.org
模块加载机制
优先从缓存加载
模块第一次加载后被缓存,提高加载效率
内置模块加载机制
内置模块的加载优先级最高。假设在node_modules中有和内置模块同名的包,在使用时始终用的时内置模块
自定义模块加载机制
使用require()加载自定义模块时,必须以./或…/开头。
导入模块时如果忽略了拓展名,Node.js会一步一步尝试加载:
(1)按照文件名进行加载
(2)文件尾部加上.js再加载
(3)文件尾部加上.json再加载
(4)文件尾部加上.node再加载
(5)上述方法都加载不了,加载失败,终端报错
第三方模块加载机制
如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ‘./’ 或 ‘…/’ 开头,则 Node.js 会从当前模块的父目录开始,尝试从 /node_modules 文件夹中加载第三方模块。
(没有找到就但返回到上一层目录,直到文件根目录)
把目录作为模块导入
使用require()方法,把文件目录作为模块导入,加载的方式:
- 查找目录下package.json, 寻找main属性作为加载入口
- 如果没找到package.json,或者main入口不存在,则会加载目录下index.js文件
- 如果上面两步都失败了,终端报错:Error: Cannot find module ‘xxx’