nodejs 相对路径,node 路径

  nodejs 相对路径,node 路径

  本文带你了解Node.js中的模块路径解析,并介绍Node中模块路径解析的方法。希望对你有帮助!

  node.js速度课程简介:进入学习

  

require案例

  当前有一个项目。当前项目路径/Users/rainbow/Documents/front-end/scaffold development/rainbow-test项目bin目录下有一堆文件。

  /bin/index . js console . log(require . resolve( . )));

  ///Users/rainbow/Documents/前端/脚手架开发/rainbow-test/bin/index.js输出bin/index.js的绝对路径

  console . log(require . resolve . paths( . )));

  //[/Users/rainbow/Documents/front-end/scaffold development/rainbow-test/bin ]输出文件可能所在路径的Array console . log(require . resolve( yargs );

  ///Users/rainbow/Documents/front-end/scaffold development/rainbow-test/node _ modules/yargs/index . cjs

  console . log(require . resolve . paths( yargs ));

  /*

  [

  /Users/rainbow/Documents/前端/脚手架开发/rainbow-test/bin/node_modules ,

  /Users/rainbow/Documents/前端/脚手架开发/rainbow-test/node_modules ,

  /用户/彩虹/文档/前端/脚手架开发/节点_模块,

  /用户/彩虹/文档/前端/节点_模块,

  /Users/rainbow/Documents/node _ modules ,

  /Users/rainbow/node_modules ,

  /用户/节点模块,

  /node_modules ,

  /用户/彩虹/。节点模块,

  /用户/彩虹/。节点_库,

  /usr/local/Cellar/node/14 . 3 . 0 _ 1/lib/node

  ]

  */

require解析并找到模块执行文件的流程

   1.Nodejs项目模块的路径解析通过require.resolve实现

  Require.resolve是模块实现的模块。_resolveFileName方法。_ ResolveFilename的核心过程是判断路径是否是内置模块,然后由模块生成node_modules的可能路径。_resolveLookupPahts方法。如果传入路径为/test/lerna/cli.js ,则在每一级路径下添加node _ moduels的路径数组,通过module查询模块的真实路径。_findPath。2.模块的核心流程。_findPath是:

  查询缓存(通过\x00组合请求和路径来生成cacheKey)遍历模块生成的路径数组。_resolveLookupPahts方法,将路径和请求转换为文件路径basePath。如果basePath存在,调用fs.realPahtSync获取文件的真实路径,并将文件的真实路径缓存到模块。_pathCache(key是cacheKey)(模块。_pathCache是地图)。3.fs.realPahtSync核心进程:

  查询(缓存的键是p .也就是模块中生成的路径。_findPath)从左到右遍历路径字符串。找到/时,拆分路径以确定该路径是否为软链接。如果是软链接,查询真实链接,生成新的路径P,然后继续遍历。这里有个细节:遍历过程中生成的子路径基会缓存在knownHard和cache中。避免重复查询遍历来获取模块对应的真实路径。此时,原始路径将被用作键,真实路径将被用作值,这些值将被保存在缓存中。4.require.resolve.paths相当于模块。_resolveLookupPaths。该方法获取node_modules的所有可能路径,形成一个数组。

  5.require.resolve.paths的实现原理是:

  如果是/(根路径)直接返回[/node_modules],否则,从后向前遍历路径字符串,当找到/时,拆分路径,在后面加上node_modules,传入一个paths数组,直到没有找到/为止,然后当我们使用require(yargs )时,返回paths数组

require使用到内置模块的方法

  。

  require方法

  实际上,模块。_load方法module . prototype . require=function(id){//id= yargs

  validateString(id, id );

  if (id===) {

  throw new ERR _ INVALID _ ARG _ VALUE( ID ,id,必须是非空字符串);

  }

  要求深度;

  尝试{

  返回模块。_load(id,this,/* isMain */false);

  }最后{

  要求深度-;

  }

  };//参数

  id=yargs

  这={

  路径:模块。_nodeModulePaths(process.cwd())

  }Module._nodeModulePaths方法

  //输入mac电脑所在的逻辑:

  //from=/users/rainbow/documents/front-end/scaffold development/ler na source/ler nas// from 是模块的_ _ dirname。

  模块。_ nodeModulePaths=function(from){

  from=path . resolve(from);

  //尽早返回不仅是为了避免不必要的工作,也是为了避免返回

  //根的两个项目的数组:[ //node_modules ,/node_modules ]

  if (from===/)

  return[/node _ modules ];

  常量路径=[];

  //关键算法代码

  对于(设i=from.length - 1,p=0,last=from . length I=0;- i) {

  常量代码=from。charcodeat(I);

  if (code===CHAR_FORWARD_SLASH) {

  如果(p!==nmLen)

  paths.push(from.slice(0,last)/node _ modules );

  last=I;

  p=0;

  } else if (p!==-1) {

  if (nmChars[p]===code) {

  p;

  }否则{

  p=-1;

  }

  }

  }

  //追加/节点_模块来处理根路径。

  路径。push(/node _ modules );

  返回路径;

  };为循环的核心算法解析:

  Module._load方法

  模块. load(id,this,/* isMain */false)

  核心实现代码是:常量文件名=模块. resolveFilename(request,parent,is main);

  require.resolve

  节点。射流研究…项目模块路径解析是通过要求。解决方式实现的。

  要求。解决就是通过模块.解决文件名方法实现的,//node.js内置模块需要的源代码

  函数解析(请求,选项){

  验证字符串(请求,‘请求’);

  返回模块. resolveFilename(request,mod,false,options);//核心实现

  }

  require.resolve=resolve

  函数路径(请求){

  验证字符串(请求,‘请求’);

  返回模块. resolveLookupPaths(request,mod);//核心代码

  }

  resolve.paths=pathsModule._resolveFileName核心流程

  判断该路径是否是内置模块不是,则通过模块resolveLookupPahts方法,将小路和环境中的路径结合起来通过模块. find path _ find path查询模块的真实路径返回模块. resolveFilename(request,parent,is main);

  模块. resolve filename=function(request,parent,isMain,options) {

  if(原生模块。canberequiredbyusers(request)){//是否为内置模块

  退货请求;

  }

  让路径;

  //让小路和环境变量中的小路结合

  路径=模块. resolveLookupPaths(请求,父级);//核心代码

  if (parent parent.filename) {

  //读取文件名对应的package.json文件,看是否有出口字段,当前文件名=假

  const filename=try self(parent。文件名,请求);

  如果(文件名){ //false

  const cacheKey=request \x00

  (paths.length===1?路径[0]:路径。加入( \ x00 );

  模块. path cache[cache key]=filename;

  返回文件名;

  }

  }

  //关键代码,找到本地执行文件//首先查找文件名,因为那是缓存键。

  常数文件名=模块. findPath(request,paths,isMain,false);

  如果(文件名)返回文件名;

  //.

  };Module._resolveLookupPahts方法

  生成要查找模块的所有路径上可能存在节点_模块的路径数组require.resolve.paths(yargs )核心实现方法生成

  [

  /用户/彩虹/文档/前端/脚手架开发/rainbow-test/bin/node_modules ,

  /用户/彩虹/文档/前端/脚手架开发/rainbow-test/node_modules ,

  /用户/彩虹/文档/前端/脚手架开发/node_modules ,

  /用户/彩虹/文档/前端/node_modules ,

  /Users/rainbow/Documents/node _ modules ,

  /Users/rainbow/node_modules ,

  /用户/节点模块,

  /node_modules ,

  /用户/彩虹/。节点模块,

  /用户/彩虹/。节点_库,

  /usr/local/Cellar/node/14。3 . 0 _ 1/库/节点

  ]

  模块resolveLookupPaths=function(request,parent) {

  if(原生模块。canberequiredbyusers(请求)){

  调试(在[]中查找%j,请求);

  返回空

  }

  //检查节点模块路径。

  if (request.charAt(0)!==.

  (请求长度一

  request.charAt(1)!==.

  request.charAt(1)!==/

  (!isWindows request.charAt(1)!==\))){

  设路径=模块路径

  如果(家长!=空父级。父路径。路径。长度){

  路径=父路径。路径。concat(路径);

  }

  调试(在%j中查找“%j”,请求,路径);

  返回路径。长度0?路径:空;

  }

  //在REPL,家长.文件名为空。

  如果(!父!parent.id !parent.filename) {

  //Make require( ./path/to/foo’)工作-通常采用路径

  //来自实路径(_ _文件名),但在取代没有文件名

  const mainPaths=[ . ];

  调试(在%j中查找“%j”,请求,主路径);

  返回主路径;

  }

  debug( RELATIVE:requested:% s来自父级。id % s ,请求,父级。id);

  const父目录=[路径。目录名(父级。文件名)];

  调试(寻找“%j”,父目录);

  返回父目录

  };Module._findPath核心流程

  查询缓存(将请求和小路通过\x00合并生成cacheKey)(\x00是空格的16进制)遍历模块resolveLookupPahts方法生成的小路数组,将小路与请求组成文件路径基本路径如果基本路径存在则调用fs.realPahtSync获取文件的真实路径

  fs.realPahtSync

  更多结节相关知识,请访问:节点射流研究…教程!以上就是一文聊聊节点。射流研究…中的模块路径解析的详细内容,更多请关注我们其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: