返回

Node.js(笔记11) - 模块的加载机制

发布时间:2023-01-05 15:14:12 241
# javascript# node.js# java# java# json

优先从缓存中加载

模块在第一次加载后会被缓存。这也意味着多次调用 require() 不会导致模块的代码被执行多次。

注意:不论是内置模块、用户自定义模块,还是第三方模块,都会优先从缓存加载,提高加载效率。

新建个模块文件   m1.js:

console.log('this is a module')

再从  demo.js 中引入模块3次:

require('./m1.js')
require('./m1.js')
require('./m1.js')

在终端执行这个  demo.js :

> node demo.js

结果是:

Node.js(笔记11) - 模块的加载机制_Node.js

只引入了一次,其实就是缓存了,提高了模块的加载效率;


内置的模块的加载机制

内置模块是由 Node.js 官方提供的模块,内置模块的加载优先级最高(相比于自定义和第三方模块);

例如:require('fs') 始终返回内置的 fs 模块,即使在 node_modules 目录下有名字相同的包也叫 fs。


自定义模块的加载机制

使用 require() 方法加载自定义模块时,必须指定以​ ./ ​​或​ ../ ​​开头的路径标识符。在加载自定义模块时,如果没有指定​ ./ ​​或​ ../ ​这样的路径标识符,则 node 会把它当作内置模块第三方模块进行加载。 

如上例,使用 ./ 路径来加载自定义模块没有问题。

require('./m1.js')

如果改成:

require('m1.js')

改成这样会被认为是内置或第三方模块,而当前并没有叫这个名字的内置或第三方模块,所以报错。

Node.js(笔记11) - 模块的加载机制_Node.js_02


同时,在使用 require() 引入自定义模块时,如果省略了文件的扩展名,则 node.js 会 按顺序 分别尝试加载以下的文件:

1)按照确切的文件名加进行加载

2)补全 ​.js​ 扩展名进行加载;

3)补全 ​.json​ 扩展名进行加载;

4)补全 ​.node​ 扩展名进行加载;

5)加载失败,终端报错

 例如在 demo.js 中加载模块:

require('./m1')

同时在当前目录新建4个文件: ​m1​,​m1.js​,​m1.json​,​m1.node

如果 m1 在,就加载 m1,否则就从 .js、.json、.node 这个顺序依次补全文件名,找到并尝试加载,直到找到,如果都没找到,就报错。

这也就是为什么加载自定义模块时,可以省略扩展名的原因。


第三方模块的加载机制

如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ./ 或 ../ 开头,则 Node.js 会从当前模块的父目录开始,尝试从 /node_modules 文件夹中加载第三方模块。

如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录。

例如:假设在“C:\Users\name\project\foo.js” 文件里调用了 require('tools'),则 Node.js 会按以下顺序查找:

1)C:\Users\name\project\node_module\tools

2)C:\Users\name\node_module\tools

3)C:\Users\node_module\tools

4)C:\node_module\tools

逐级目录找下去,找到就加载成功,找到根目录还是没有找到,就报错。


目录作为模块

当把目录作为模块标识符,传递给 require() 进行加载的时候,有三种加载方式:

1)在被加载的目录下查找 package.json 文件,如果 main 中定义了入口文件,那会被 require() 加载

2)如果目录里没有 package.json 文件,或 main 入口不存在或无法解析,则 Node.js 会尝试加载目录下的 index.js 文件。

3)如果以上两个都加载失败,则 Node.js 会报错。​Error:Cannot find module 'xxx'

做个测试,建如下目录结构:

Node.js(笔记11) - 模块的加载机制_Node.js_03

testm 目录中的3个文件:

index.js

console.log('this is index.js');

m.js

console.log('this is m.js');

package.json

{
"main": "./m.js"
}

在 package.json 中指定了 main 中的文件。

那么从外部的 a.js 加载:

require("./testm")

注意,这里只是写了目录,并没有指定文件,所以结果是:

Node.js(笔记11) - 模块的加载机制_Node.js_04

显而易见是 m.js ;

如果删除 package.json 或者不写 main 属性中的入口文件,就会尝试加载 index.js

Node.js(笔记11) - 模块的加载机制_Node.js_05

把 testm 目录中的文件都删除呢?

Node.js(笔记11) - 模块的加载机制_Node.js_06

就会报错。


特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
三步问题 2023-01-05 14:43:44