模块化开发中的模块分为三类:内置模块、自定义模块、第三方模块。这些模块会优先从缓存中加载。模块在第一次加载后会被缓存,所以多次调用require() 不会导致模块的代码被执行多次。
1. 内置模块
内置模块是node内置的api,比如 fs、http、path等。内置模块可以用直接引入的方式来使用。
const fs = require('fs');
内置模块的优先级最高,如果有第三方模块名字与内置模块冲突,引入的还是内置模块
2. 自定义模块
自定义模块引入时,必须要写入完整的文件路径,指定以 ./ 或 ../开头的路径标识符。如果不写的话,node就会认为你引入的是内置模块或者第三方模块,导致引入出错。
同时,如果在require() 时省略了文件的扩展名,则node 会按顺序分别尝试加载以下文件
(1)按照确切的文件名进行加载
(2)补全.js 扩展名进行加载
(3)补全 .json 扩展名进行加载
(4)补全 .node 扩展名进行加载
(5)加载失败,报错
3. 第三方模块
引入第三方模块时,node会从当前模块的父目录开始,尝试从node_modules 文件夹中加载第三方模块。如果没有找到,则会移动到再上一级父目录中,进行加载,知道文件系统的根目录。
例如,假设在 'C:\Users\login\workspace\project\foo.js' 文件里调用了 require('tools'),则node会按照以下顺序查找:
(1)C:\Users\login\workspace\project\node_modules\tools
(2)C:\Users\login\workspace\node_modules\tools
(3)C:\Users\login\node_modules\tools
(4)C:\Users\node_modules\tools
4. 加载文件夹
如果require('./test') 直接引入一个文件夹,node首先会查找这个文件夹中是否有package.json 文件,如果有,就会加载package.json 文件中的 main 属性的入口文件;
如果没有 package.json,或者main入口不存在或无法解析。node就会加载文件夹中的 index.js。
如果上述两步都失败,就会报错。