匹配字符相等算法
// node_modules reverse 
var nmChars = [ 115, 101, 108, 117, 100, 111, 109, 95, 101, 100, 111, 110 ];
let from = "F:\node-test\lerna-3.22.1\lerna-3.22.1";// 绝对路径
// 末尾开始找
const CHAR_BACKWARD_SLASH = 92; // \
const CHAR_BACKWARD_SLASH = 47;// /
const CHAR_COLON = 58;// :

for (var i = from.length - 1; i >= 0; --i) {
  const code = from.charCodeAt(i);

  if (code === CHAR_BACKWARD_SLASH ||
      code === CHAR_FORWARD_SLASH ||
      code === CHAR_COLON) {
    if (p !== nmLen) // /.../之间不能与node_modules匹配,加上node_modules
      paths.push(from.slice(0, last) + '\\node_modules');
    last = i;
    p = 0;
  } else if (p !== -1) {
    if (nmChars[p] === code) { //匹配 ++
      ++p;
    } else {//新的目录,重新开始计数
      p = -1;
    }
  }
}
yargs
  • 脚手架构成

    • bin:package.js中配置bin属性,npm link本地安装

    • command:命令

    • options:参数(boolean、string、number)

    • 文件顶部增加

      #!usr/bin/env node
      
  • 脚手架初始化流程

    • 构造函数:Yargs()

    • 常用方法:

      Yargs.options
      Yargs.option
      Yargs.group
      Yargs.demandCommand
      Yargs.recommendCommands
      Yargs.strict
      Yargs.fail
      Yargs.alias
      Yargs.wrap
      Yargs.epilogue
      
  • 脚手架参数解析方法

    hideBin(process.args)/Yargs.argv
    Yargs.parse(argv,options)
    
  • 命令注册方法

    Yargs.command(command,describe,builder,handler)
    Yargs.command({command,describe,builder,handler})
    
Lerna实现原理
  • Lerna是基于git+npm的多package项目管理工具
  • 实现原理
    • 通过import-local优先调用本地lerna命令
    • 通过Yargs生成脚手架,先注册全局属性,再注册命令,最后通过parse方法解析参数
    • lerna命令注册时需要传入builder和handler两个方法,builder方法用于注册命令专属的options,handler用来处理命令的业务逻辑
    • lerna通过配置npm本地依赖的方式来进行本地开发,具体方法是在package.json的依赖中写入:file:your-local-module-path,在lerna publish时会自动将该路径替换
Node.js模块路径解析流程
  • Node.js项目模块路径解析是通过require.resolve方法来实现的

  • require.resolve就是通过Module._resolveFileName方法实现的

  • require.resolve实现原理:

    • Module._resolveFileName方法核心流程有3点:

      • 判断是否为内置模块
      • 通过Module._resolveLookupPaths方法生成node_modules可能存在的路径
      • 通过Module._findPath查询模块的真实路径
    • Module._findPath核心流程有4点:

      • 查询缓存(将request和paths通过\x00合并成cacheKey)
      • 遍历paths,将path与request组成文件路径basePath
      • 如果basePath存在则调用fs.realPathSync获取文件真实路径
      • 将文件真实路径缓存到Module._pathCache(key就是前面生成的cacheKey)
    • fs.realPathSync核心流程有3点:

      • 查询缓存(缓存的key为p,即Module._findPath中生成的文件路径)
      • 从左往右遍历路径字符串,查询到/时,拆分路径,判断该路径是否为软链接,如果是软连接则查询真实链接,并生成新路径p,然后继续往后遍历,这里有1个细节需要特别注意:
        • 遍历过程中生成的子路径base会缓存在knownHard和cache中,避免重复查询
      • 遍历完成得到模块对应的真实路径,此时会将原始路径original作为key,真实路径作为value,保存到缓存中
    • require.resolve.paths等价于Module._resolveLookupPaths,该方法用于获取所有node_modules可能存在的路径

    • require.resolve.path实现原理:

      • 如果路径为/(根目录),直接返回['/node_modules']

      • 否则,将路径字符串从后往前遍历,查询到/时,拆分路径,在后面加上node_modules,并传入一个paths数组,直到查询不到/后返回paths数组

Copyright © imooc-lego (2020 - present) all right reserved,powered by GitbookFile Modify: 2021-06-27 08:04:56

results matching ""

    No results matching ""