久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      一文聊聊Node.js中的模塊路徑解析

      本篇文章帶大家了解一下Node.js中的模塊路徑解析,介紹一下Node模塊路徑解析方法,希望對大家有所幫助!

      一文聊聊Node.js中的模塊路徑解析

      require案例

      • 當前有一個項目
      • 當前項目路徑/Users/rainbow/Documents/前端/腳手架開發(fā)/rainbow-test
      • 項目bin目錄下有一堆文件

      一文聊聊Node.js中的模塊路徑解析

      • /bin/index.js
      console.log(require.resolve(".")); // /Users/rainbow/Documents/前端/腳手架開發(fā)/rainbow-test/bin/index.js  輸出bin/index.js的絕對路徑 console.log(require.resolve.paths(".")); // [ '/Users/rainbow/Documents/前端/腳手架開發(fā)/rainbow-test/bin' ] 輸出的文件可能在的路徑的數(shù)組
      console.log(require.resolve("yargs")); // /Users/rainbow/Documents/前端/腳手架開發(fā)/rainbow-test/node_modules/yargs/index.cjs console.log(require.resolve.paths("yargs")); /* [   '/Users/rainbow/Documents/前端/腳手架開發(fā)/rainbow-test/bin/node_modules',   '/Users/rainbow/Documents/前端/腳手架開發(fā)/rainbow-test/node_modules',   '/Users/rainbow/Documents/前端/腳手架開發(fā)/node_modules',   '/Users/rainbow/Documents/前端/node_modules',   '/Users/rainbow/Documents/node_modules',   '/Users/rainbow/node_modules',   '/Users/node_modules',   '/node_modules',   '/Users/rainbow/.node_modules',   '/Users/rainbow/.node_libraries',   '/usr/local/Cellar/node/14.3.0_1/lib/node' ] */

      require解析并找到模塊執(zhí)行文件的流程

      1、Nodejs項目模塊路徑解析是通過require.resolve方式實現(xiàn)的。

      • require.resolve就是通過Module._resolveFileName方法實現(xiàn)的
      • Module._resolveFileName核心流程是:
        • 判斷該路徑是否是內(nèi)置模塊
        • 不是,則通過Module._resolveLookupPahts方法,生成node_modules可能存在的路徑,如果傳入的路徑是’/test/lerna/cli.js’,在每一級路徑下加上node_moduels的路徑數(shù)組
        • 通過Module._findPath查詢模塊的真實路徑,

      2、Module._findPath核心流程是:

      • 查詢緩存(將request和paths通過x00合并生成cacheKey)
      • 遍歷 Module._resolveLookupPahts方法生成的paths數(shù)組,將pathrequest組成文件路徑basePath
      • 如果basePath存在則調(diào)用fs.realPahtSync獲取文件的真實路徑
      • 將文件真實路徑緩存到Module._pathCache(key為cacheKey)(Module._pathCache就是一個map)

      3、fs.realPahtSync核心流程:

      • 查詢緩存(緩存的key為p。即Module._findPath中生成的路徑)
      • 從左往右遍歷路徑字符串,查詢到/時,拆分路徑,判斷該路徑是否為軟鏈接,如果是軟鏈接則查詢真實鏈接,并生成新路徑p,然后繼續(xù)讓后遍歷,這里有一個細節(jié):
      • 遍歷過程中生成的子路徑base會緩存在knownHard和cache中,避免重復查詢
      • 遍歷完成得到模塊對應的真實路徑,此時會將原始路徑original作為key,真實路徑作為value,保存到緩存中

      4、require.resolve.paths等價于Module._resolveLookupPaths,該方法獲取所有node_modules可能存在的路徑組成一個數(shù)組。

      5、require.resolve.paths實現(xiàn)原理是:

      • 如果是/(根路徑)直接返回['/node_modules']
      • 否則,將路徑字符串從后往前遍歷,查詢到/時,拆分路徑,在后面加上node_modules,并傳入一個paths數(shù)組,直到查詢不到/后返回paths數(shù)組

      require使用到內(nèi)置模塊的方法

      當我們使用require('yargs')

      require方法

      • 實際使用的是Module._load方法
      Module.prototype.require = function(id) { //id = 'yargs'   validateString(id, 'id');   if (id === '') {     throw new ERR_INVALID_ARG_VALUE('id', id, 'must be a non-empty string');   }   requireDepth++;   try {     return Module._load(id, this, /* isMain */ false);   } finally {     requireDepth--;   } };
      // 參數(shù) id = 'yargs' this={  paths: Module._nodeModulePaths(process.cwd()) }

      Module._nodeModulePaths方法

      一文聊聊Node.js中的模塊路徑解析

      // 進入mac電腦所在的邏輯: // from => /Users/rainbow/Documents/前端/腳手架開發(fā)/lerna源碼/lernas  //'from' is the __dirname of the module.   Module._nodeModulePaths = function(from) {     from = path.resolve(from);     // Return early not only to avoid unnecessary work, but to *avoid* returning     // an array of two items for a root: [ '//node_modules', '/node_modules' ]     if (from === '/')       return ['/node_modules'];      const paths = [];         // 關(guān)鍵算法代碼     for (let i = from.length - 1, p = 0, last = from.length; i >= 0; --i) {       const code = from.charCodeAt(i);       if (code === CHAR_FORWARD_SLASH) {         if (p !== nmLen)           paths.push(from.slice(0, last) + '/node_modules');         last = i;         p = 0;       } else if (p !== -1) {         if (nmChars[p] === code) {           ++p;         } else {           p = -1;         }       }     }      // Append /node_modules to handle root paths.     paths.push('/node_modules');      return paths;   };

      for循環(huán)的核心算法解析:

      一文聊聊Node.js中的模塊路徑解析

      Module._load方法

      Module._load(id, this, /* isMain */ false)

      核心實現(xiàn)代碼是:const filename = Module._resolveFilename(request, parent, isMain);

      require.resolve

      Node.js項目模塊路徑解析是通過require.resolve方式實現(xiàn)的。

      • require.resolve就是通過Module._resolveFileName方法實現(xiàn)的,
      // node.js內(nèi)置模塊require的源代碼 function resolve(request, options) {   validateString(request, 'request');   return Module._resolveFilename(request, mod, false, options); //核心實現(xiàn) }  require.resolve = resolve;  function paths(request) {   validateString(request, 'request');   return Module._resolveLookupPaths(request, mod); //核心代碼 }  resolve.paths = paths;

      Module._resolveFileName核心流程

      • 判斷該路徑是否是內(nèi)置模塊
      • 不是,則通過Module._resolveLookupPahts方法,將paths和環(huán)境中的路徑結(jié)合起來
      • 通過Module._findPath查詢模塊的真實路徑

      return Module._resolveFilename(request, parent, isMain);

      一文聊聊Node.js中的模塊路徑解析

      Module._resolveFilename = function(request, parent, isMain, options) {   if (NativeModule.canBeRequiredByUsers(request)) { //是否為內(nèi)置模塊     return request;   }    let paths;   // 讓paths和環(huán)境變量中的paths結(jié)合   paths = Module._resolveLookupPaths(request, parent); //核心代碼      if (parent && parent.filename) {     // 讀取filename對應的package.json文件,看是否有exports字段,當前filename = false     const filename = trySelf(parent.filename, request);     if (filename) { //false       const cacheKey = request + 'x00' +           (paths.length === 1 ? paths[0] : paths.join('x00'));       Module._pathCache[cacheKey] = filename;       return filename;     }   }   //關(guān)鍵代碼,找到本地執(zhí)行文件 // Look up the filename first, since that's the cache key.    const filename = Module._findPath(request, paths, isMain, false);   if (filename) return filename;   // ... };

      Module._resolveLookupPahts方法

      • 生成要查找模塊的所有路徑上可能存在node_modules的路徑數(shù)組
      • require.resolve.paths("yargs")核心實現(xiàn)方法

      生成

      [   '/Users/rainbow/Documents/前端/腳手架開發(fā)/rainbow-test/bin/node_modules',   '/Users/rainbow/Documents/前端/腳手架開發(fā)/rainbow-test/node_modules',   '/Users/rainbow/Documents/前端/腳手架開發(fā)/node_modules',   '/Users/rainbow/Documents/前端/node_modules',   '/Users/rainbow/Documents/node_modules',   '/Users/rainbow/node_modules',   '/Users/node_modules',   '/node_modules',   '/Users/rainbow/.node_modules',   '/Users/rainbow/.node_libraries',   '/usr/local/Cellar/node/14.3.0_1/lib/node' ]

      一文聊聊Node.js中的模塊路徑解析

      Module._resolveLookupPaths = function(request, parent) {   if (NativeModule.canBeRequiredByUsers(request)) {     debug('looking for %j in []', request);     return null;   }    // Check for node modules paths.   if (request.charAt(0) !== '.' ||       (request.length > 1 &&       request.charAt(1) !== '.' &&       request.charAt(1) !== '/' &&       (!isWindows || request.charAt(1) !== ''))){      let paths = modulePaths;      if (parent != null && parent.paths && parent.paths.length) {       paths = parent.paths.concat(paths);     }      debug('looking for %j in %j', request, paths);     return paths.length > 0 ? paths : null;   }      // In REPL, parent.filename is null.   if (!parent || !parent.id || !parent.filename) {     // Make require('./path/to/foo') work - normally the path is taken     // from realpath(__filename) but in REPL there is no filename     const mainPaths = ['.'];      debug('looking for %j in %j', request, mainPaths);     return mainPaths;   }    debug('RELATIVE: requested: %s from parent.id %s', request, parent.id);    const parentDir = [path.dirname(parent.filename)];   debug('looking for %j', parentDir);   return parentDir; };

      Module._findPath核心流程

      • 查詢緩存(將request和paths通過x00合并生成cacheKey)(x00是空格的16進制)
      • 遍歷Module._resolveLookupPahts方法生成的paths數(shù)組,將pathrequest組成文件路徑basePath
      • 如果basePath存在則調(diào)用fs.realPahtSync獲取文件的真實路徑

      一文聊聊Node.js中的模塊路徑解析

      fs.realPahtSync

      一文聊聊Node.js中的模塊路徑解析

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號