首页 » PHP教程 » phprequire不在path技巧_require 方法详解

phprequire不在path技巧_require 方法详解

访客 2024-11-06 0

扫一扫用手机浏览

文章目录 [+]

每个模块内部,都有一个 module 工具,代表当前模块。
它有以下属性。

module 工具的属性module.id 模块的识别符,常日是带有绝对路径的模块文件名。
module.filename 模块的文件名,带有绝对路径。
module.loaded 返回一个布尔值,表示模块是否已经完成加载。
module.parent 返回一个工具,表示调用该模块的模块(程序入口文件的module.parent为null)module.children 返回一个数组,表示该模块要用到的其他模块。
module.exports 表示模块对外输出的值。
module.exports 属性module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上便是读取module.exports变量。
module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上便是读取module.exports变量。
exports 变量

我们有时候会这么写:

phprequire不在path技巧_require 方法详解

// test.jsfunction test(){ console.log(test);}export.test = test;// result.jsconst test = require("./test")

这样也可以拿到精确的结果,这是由于:exports 变量指向 module.exports。
这等同在每个模块头部,有一行这样的命令。

phprequire不在path技巧_require 方法详解
(图片来自网络侵删)

varexports=module.exports;

把稳:不能直接给 exports 变量赋值,这样会改变 exports 的指向,不再指向 module.exports。
在其他模块利用 require 方法是拿不到赋给 exports 的值的,由于 require 方法获取的是其他模块的 module.exports 的值。

建议:尽可能的利用 module.exports 来导出结果。

模块的流程创建模块导出模块加载模块利用模块require 方法

require 是 node 用来加载并实行其它文件导出的模块的方法。

在 NodeJs 中,我们引入的任何一个模块都对应一个 Module 实例,包括入口文件。

完全步骤:

1、调用父模块的 require 方法(父模块是指调用模块确当前模块)

require = function require(path) { return mod.require(path);};

2、调用 Module 的 _load 方法

3、通过 Module._resolveFilename 获取模块的路径 fileName

constfilename = Module._resolveFilename(request, parent, isMain);

4、根据 fileName 判断是否存在该模块的缓存如果存在缓存,则调用 updateChildren 方法在更新缓存内容,并返回缓存如果不存在缓存,则连续实行

5、当做原生模块,调用 loadNativeModule 方法进行加载如果加载成功,则返回该原生模块否则,连续实行

6、根据当前模块名(路径)和父模块工具天生一个 Module 实例:

constmodule= cachedModule ||newModule(filename, parent);

7、再判断该模块是否是入口文件

if (isMain) { process.mainModule = module; module.id = '.';}

8、将该模块的实例存入到 Module 的缓存中

Module._cache[filename] =module;

9、该模块的实例调用自身的 load 方法,根据 fileName 加载模块

module.load(filename);

10、获取该模块文件的后缀名称

constextension = findLongestRegisteredExtension(filename);

如果后缀名称是ES Module格式的(.mjs),则判断Module是否支持.mjs文件的解析,如果不支持,则抛出非常。

11、根据后缀名称解析模块文件内容

Module._extensions[extension](this, filename);

12、根据fileName读取文件内容

content = fs.readFileSync(filename,'utf8');

13、编译并实行读取到的文件,调用 module 自身的 _complile 方法:

module._compile(content, filename);

_compile 紧张内容步骤:

const compiledWrapper = wrapSafe(filename, content, this);const dirname = path.dirname(filename);const require = makeRequireFunction(this, redirects);let result;const exports = this.exports;const thisValue = exports;const module = this;result = compiledWrapper.call(thisValue, exports, require, module, filename, dirname);return result;

wrapSafe方法的返回值

详细得到上图结果的代码是:

const wrapper = Module.wrap(content);return vm.runInThisContext(wrapper, { filename, lineOffset: 0, displayErrors: true, importModuleDynamically: async (specifier) => { const loader = asyncESM.ESMLoader; return loader.import(specifier, normalizeReferrerURL(filename)); },});

14、修正该模块的加载状态为true

this.loaded =true;

15、加载成功。

总结

通过上面的调试过程可得出以下结论:

在NodeJs中,从入口文件开始,统统皆 Module。
模块的加载是同步的。
由于缓存机制的存在,模块的循环引用对性能的影响微乎其微,并且循环引用到的模块可能是不完全的,并且可能会导致错require 查找模块的流程如下:

文件路径的解析流程图如下:

~本文完~

学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!

大家好!
我是〖编程三昧〗的作者 隐逸王,我的公众年夜众号是『编程三昧』,欢迎关注,希望大家多多指教!

知识与技能并重,内力和外功兼修,理论和实践两手都要抓、两手都要硬!

标签:

相关文章

Java代码虚拟化保护技术与应用前景

软件应用的需求日益增长,软件开发过程中对代码的保护成为了一个重要议题。Java作为一种广泛应用于企业级应用的编程语言,其代码虚拟化...

PHP教程 2025-03-02 阅读1 评论0

CAD插件错误代码与应对步骤

CAD(计算机辅助设计)软件在工程设计领域得到了广泛应用。CAD插件作为提升设计效率的重要工具,在提高设计师工作效率的也带来了一定...

PHP教程 2025-03-02 阅读1 评论0

上古卷轴代码规则大全游戏背后的编程奥秘

《上古卷轴》作为一款深受玩家喜爱的角色扮演游戏,自问世以来便以其丰富的世界观、独特的游戏体验和深厚的文化底蕴吸引了无数玩家。在这款...

PHP教程 2025-03-02 阅读1 评论0