Node的模块化
什么是模块化及好处?
我哦们可以把一些功能类是的代码或API封装到一个独立的模块中去。这样,我们在需要的时候,不必重新每次定义相同的方法,只需要简单调用即可;
模块化的好处:
1、方便维护、复用,防止了全局变量污染的问题。
2、独立的模块作用域
Node中如何实现模块化?
1、module:表示一个模块,所有自己定义的js文件都是属于模块。
2、require: 在一个JS文件中,如果需要其他模块中的功能,使用require就可以导入其他模块来使用。
3、exports : 在每一个模块中,使用exports,可以把当前模块的私有成员通过exports向外暴漏出去;
Node中模块化,主要解决的JS文件之间的相互依赖关系,以及全局变量污染的问题。
在Node中 global对象,就相当于浏览器中的window
Node中模块的分类:
1、核心模块
由Node官方提供的模块,已经被官方编译好打包到node的安装程序中,只要安装node就相当于拥有了全局可用的核心模块。例如: fs,http
如何使用? const 模块接收名称 = require('核心模块标识符')
2、第三方模块
那些非官方提供的,由第三方的团体,个人,公司开发出来的好用模块,上传到npm 官方网站。这些由NPM 托管的所有模块。
例如: moment
1)npm install moment --save
2) const moment = require('moment');
3) 根据moment文档提供的API使用。
3、用户自定义模块
用户自己写的所有的js文件,都是用户模块;
require导入其他模块的时候,都会执行模块中代码。
如何加载? require('../../路径标识符')
用户模块向外导出成员的两种方式:
1)使用global对象向外暴露成员
2)使用exports向外暴露成员
exports和module.exports的区别:
1、一个模块,最终向外暴露成员的时候,永远以module.exports指向的成员为准;
2、默认情况下,
module.exports指向一个空对象,同时exports也指向这个相同的空对象;
模块加载规则:
优先从缓存中加载
目的: 提高模块的加载效率,已经被加载过的模块会缓存到require.cache对象中;
1、核心模块加载规则
先从缓存中查找这个核心模块有没有被加载过,如果没有再真正去加载
2、用户模块加载规则
1) 先从缓存中尝试加载
2) 如果在加载用户模块的时候,并没有提供完整的文件后缀名,此时,Node会先严格按照给定的名称,去查找这个文件:
index -> index.js ->index.json -> index.node
3、第三方模块加载规则
1)先在当前目录下,查找有没有node_modules的文件夹;
2)如果有,则在node_modules目录中,根据require提供的第三方模块名称查找这个相同名称的文件夹;
3)如果有,在这个模块文件夹的目录中,查找一个叫做package.json的配置文件;
4)如果有,继续在这个文件中查找一个main属性
5)如果有main属性,则node 尝试加载这个属性指向的那个文件,如果这个文件被正确加载执行,第三方模块加载成功。
6)如果在package.json没有main属性或根本没有package.json文件。Node 会依次尝试加载第三方模块根目录中的index.js,index.json,index.node
7) 如果没有index相关的文件,或者根本没有这个第三方模块的文件夹,或者根本没有node_modules这一层目录,则会向上一层查找。根据1-6
8)如果在上一层的目录中,还是没有找到这个第三方模块,则继续向上翻目录并查找,直到查找到项目所在的磁盘根目录。如果最终也没有找到,则报错:
Can not find module ****
使用nodemon来自动重启Node服务
单纯使用node命令执行一个js代码,不会监听到代码的改变并自动重启服务器。此时,我们可以借助一个工具,叫做nodemon。
1)nodemon是一个使用Node开发出来的好用的前端工具。
能不能区分模块(一般都是项目本地安装)和工具(一般使用-g 全局安装)的概念
2)运行 npm i -g nodemon 全局安装工具
3)当全局安装完毕后,我们可以使用nodemon命令,来替代node命令,运行你的服务器js代码。
例如: node index.js 替换成 nodemon index.js