久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

聊聊Node.js path模塊中的常用工具函數

本篇文章帶大家聊聊Node中的path模塊,介紹一下path的常見使用場景、執行機制,以及常用工具函數,希望對大家有所幫助!

聊聊Node.js path模塊中的常用工具函數

在開發過程中,會經常用到 Node.js ,它利用 V8 提供的能力,拓展了 JS 的能力。而在 Node.js 中,我們可以使用 JS 中本來不存在的 path 模塊,為了我們更加熟悉的運用,讓我們一起來了解一下吧~

本文 Node.js 版本為 16.14.0,本文的源碼來自于此版本。希望大家閱讀本文后,會對大家閱讀源碼有所幫助。

path 的常見使用場景

Path 用于處理文件和目錄的路徑,這個模塊中提供了一些便于開發者開發的工具函數,來協助我們進行復雜的路徑判斷,提高開發效率。例如:

  • 在項目中配置別名,別名的配置方便我們對文件更簡便的引用,避免深層級逐級向上查找。

reslove: {   alias: {     // __dirname 當前文件所在的目錄路徑     'src': path.resolve(__dirname, './src'),     // process.cwd 當前工作目錄     '@': path.join(process.cwd(), 'src'),   }, }
  • 在 webpack 中,文件的輸出路徑也可以通過我們自行配置生成到指定的位置。

module.exports = {   entry: './path/to/my/entry/file.js',   output: {     path: path.resolve(__dirname, 'dist'),     filename: 'my-first-webpack.bundle.js',   }, };
  • 又或者對于文件夾的操作

let fs = require("fs"); let path = require("path");  // 刪除文件夾 let deleDir = (src) => {     // 讀取文件夾     let children = fs.readdirSync(src);     children.forEach(item => {         let childpath = path.join(src, item);         // 檢查文件是否存在         let file = fs.statSync(childpath).isFile();         if (file) {             // 文件存在就刪除             fs.unlinkSync(childpath)         } else {             // 繼續檢測文件夾             deleDir(childpath)         }     })     // 刪除空文件夾     fs.rmdirSync(src) } deleDir("../floor")

簡單的了解了一下 path 的使用場景,接下來我們根據使用來研究一下它的執行機制,以及是怎么實現的。

path 的執行機制

聊聊Node.js path模塊中的常用工具函數

  • 引入 path 模塊,調用 path 的工具函數的時候,會進入原生模塊的處理邏輯。

  • 使用 _load 函數根據你引入的模塊名作為 ID,判斷要加載的模塊是原生 JS 模塊后,會通過 loadNativeModule 函數,利用 id 從 _source (保存原生JS模塊的源碼字符串轉成的 ASCII 碼)中找到對應的數據加載原生 JS 模塊。

  • 執行 lib/path.js 文件,利用 process 判斷操作系統,根據操作系統的不同,在其文件處理上可能會存在操作字符的差異化處理,但方法大致一樣,處理完后返回給調用方。

常用工具函數簡析

resolve 返回當前路徑的絕對路徑

resolve 將多個參數,依次進行拼接,生成新的絕對路徑。

resolve(...args) {   let resolvedDevice = '';   let resolvedTail = '';   let resolvedAbsolute = false;    // 從右到左檢測參數   for (let i = args.length - 1; i >= -1; i--) {     ......   }    // 規范化路徑   resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\', isPathSeparator);    return resolvedAbsolute ?     `${resolvedDevice}\${resolvedTail}` :     `${resolvedDevice}${resolvedTail}` || '.'; }

聊聊Node.js path模塊中的常用工具函數

根據參數獲取路徑,對接收到的參數進行遍歷,參數的長度大于等于 0 時都會開始進行拼接,對拼接好的 path 進行非字符串校驗,有不符合的參數則拋出 throw new ERR_INVALID_ARG_TYPE(name, 'string', value), 符合要求則會對 path 進行長度判斷,有值則 +=path 做下一步操作。

let path;  if (i >= 0) {   path = args[i];   // internal/validators   validateString(path, 'path');   // path 長度為 0 的話,會直接跳出上述代碼塊的 for 循環   if (path.length === 0) {     continue;   } } else if (resolvedDevice.length === 0) {   // resolvedDevice 的長度為 0,給 path 賦值為當前工作目錄   path = process.cwd(); } else {   // 賦值為環境對象或者當前工作目錄   path = process.env[`=${resolvedDevice}`] || process.cwd();   if (path === undefined ||       (StringPrototypeToLowerCase(StringPrototypeSlice(path, 0, 2)) !==       StringPrototypeToLowerCase(resolvedDevice) &&       StringPrototypeCharCodeAt(path, 2) === CHAR_BACKWARD_SLASH)) {     // 對 path 進行非空與絕對路徑判斷得出 path 路徑     path = `${resolvedDevice}\`;   } }

聊聊Node.js path模塊中的常用工具函數

嘗試匹配根路徑,判斷是否是只有一個路徑分隔符 ('') 或者 path 為絕對路徑,然后給絕對路徑打標,并把 rootEnd 截取標識設為 1 (下標)。第二項若還是路徑分隔符 ('') ,就定義截取值為 2 (下標),并用 last 保存截取值,以便后續判斷使用。

繼續判斷第三項是否是路徑分隔符 (''),如果是,那么為絕對路徑,rootEnd 截取標識為 1 (下標),但也有可能是 UNC 路徑 ( servernamesharename,servername 服務器名。sharename 共享資源名稱)。如果有其他值,截取值會繼續進行自增讀取后面的值,并用 firstPart 保存第三位的值,以便拼接目錄時取值,并把 last 和截取值保持一致,以便結束判斷。

const len = path.length; let rootEnd = 0; // 路徑截取結束下標 let device = ''; // 磁盤根 D:、C: let isAbsolute = false; // 是否是磁盤根路徑 const code = StringPrototypeCharCodeAt(path, 0);  // path 長度為 1 if (len === 1) {   // 只有一個路徑分隔符  為絕對路徑   if (isPathSeparator(code)) {     rootEnd = 1;     isAbsolute = true;   } } else if (isPathSeparator(code)) {   // 可能是 UNC 根,從一個分隔符  開始,至少有一個它就是某種絕對路徑(UNC或其他)   isAbsolute = true;   // 開始匹配雙路徑分隔符   if (isPathSeparator(StringPrototypeCharCodeAt(path, 1))) {     let j = 2;     let last = j;     // 匹配一個或多個非路徑分隔符     while (j < len &&     !isPathSeparator(StringPrototypeCharCodeAt(path, j))) {       j++;     }     if (j < len && j !== last) {       const firstPart = StringPrototypeSlice(path, last, j);       last = j;       // 匹配一個或多個路徑分隔符       while (j < len &&               isPathSeparator(StringPrototypeCharCodeAt(path, j))) {         j++;       }       if (j < len && j !== last) {         last = j;         while (j < len &&                 !isPathSeparator(StringPrototypeCharCodeAt(path, j))) {           j++;         }         if (j === len || j !== last) {           device =             `\\${firstPart}\${StringPrototypeSlice(path, last, j)}`;           rootEnd = j;         }       }     }   } else {     rootEnd = 1;   } // 檢測磁盤根目錄匹配 例:D:,C: } else if (isWindowsDeviceRoot(code) && StringPrototypeCharCodeAt(path, 1) === CHAR_COLON) {   device = StringPrototypeSlice(path, 0, 2);   rootEnd = 2;   if (len > 2 && isPathSeparator(StringPrototypeCharCodeAt(path, 2))) {     isAbsolute = true;     rootEnd = 3;   } }

檢測路徑并生成,檢測磁盤根目錄是否存在或解析 resolvedAbsolute 是否為絕對路徑。

// 檢測磁盤根目錄 if (device.length > 0) {   // resolvedDevice 有值   if (resolvedDevice.length > 0) {     if (StringPrototypeToLowerCase(device) !==         StringPrototypeToLowerCase(resolvedDevice))       continue;   } else {     // resolvedDevice 無值并賦值為磁盤根目錄     resolvedDevice = device;   } }  // 絕對路徑 if (resolvedAbsolute) {   // 磁盤根目錄存在結束循環   if (resolvedDevice.length > 0)     break; } else {   // 獲取路徑前綴進行拼接   resolvedTail =     `${StringPrototypeSlice(path, rootEnd)}\${resolvedTail}`;   resolvedAbsolute = isAbsolute;   if (isAbsolute && resolvedDevice.length > 0) {     // 磁盤根存在便結束循環     break;   } }

join 根據傳入的 path 片段進行路徑拼接

聊聊Node.js path模塊中的常用工具函數

  • 接收多個參數,利用特定分隔符作為定界符將所有的 path 參數連接在一起,生成新的規范化路徑。

  • 接收參數后進行校驗,如果沒有參數的話,會直接返回 '.' ,反之進行遍歷,通過內置 validateString 方法校驗每個參數,如有一項不合規則直接 throw new ERR_INVALID_ARG_TYPE(name, 'string', value);

  • window 下為反斜杠 ('') , 而 linux 下為正斜杠 ('/'),這里是 join 方法區分操作系統的一個不同點,而反斜杠 ('') 有轉義符的作用,單獨使用會被認為是要轉義斜杠后面的字符串,故此使用雙反斜杠轉義出反斜杠 ('') 使用。

  • 最后進行拼接后的字符串校驗并格式化返回。

if (args.length === 0)     return '.';  let joined; let firstPart; // 從左到右檢測參數 for (let i = 0; i < args.length; ++i) {   const arg = args[i];   // internal/validators   validateString(arg, 'path');   if (arg.length > 0) {     if (joined === undefined)       // 把第一個字符串賦值給 joined,并用 firstPart 變量保存第一個字符串以待后面使用       joined = firstPart = arg;     else       // joined 有值,進行 += 拼接操作       joined += `\${arg}`;   } }  if (joined === undefined)   return '.';

在 window 系統下,因為使用反斜杠 ('') 和 UNC (主要指局域網上資源的完整 Windows 2000 名稱)路徑的緣故,需要進行網絡路徑處理,('') 代表的是網絡路徑格式,因此在 win32 下掛載的join 方法默認會進行截取操作。

如果匹配得到反斜杠 (''),slashCount 就會進行自增操作,只要匹配反斜杠 ('') 大于兩個就會對拼接好的路徑進行截取操作,并手動拼接轉義后的反斜杠 ('')。

let needsReplace = true; let slashCount = 0; // 根據 StringPrototypeCharCodeAt 對首個字符串依次進行 code 碼提取,并通過 isPathSeparator 方法與定義好的 code 碼進行匹配 if (isPathSeparator(StringPrototypeCharCodeAt(firstPart, 0))) {   ++slashCount;   const firstLen = firstPart.length;   if (firstLen > 1 &&       isPathSeparator(StringPrototypeCharCodeAt(firstPart, 1))) {     ++slashCount;     if (firstLen > 2) {       if (isPathSeparator(StringPrototypeCharCodeAt(firstPart, 2)))         ++slashCount;       else {         needsReplace = false;       }     }   } }  if (needsReplace) {   while (slashCount < joined.length &&           isPathSeparator(StringPrototypeCharCodeAt(joined, slashCount))) {     slashCount++;   }    if (slashCount >= 2)     joined = `\${StringPrototypeSlice(joined, slashCount)}`; }

執行結果梳理

resolve join
無參數 當前文件的絕對路徑 .
參數無絕對路徑 當前文件的絕對路徑按順序拼接參數 拼接成的路徑
首個參數為絕對路徑 參數路徑覆蓋當前文件絕對路徑并拼接后續非絕對路徑 拼接成的絕對路徑
后置參數為絕對路徑 參數路徑覆蓋當前文件絕對路徑并覆蓋前置參數 拼接成的路徑
首個參數為(./) 有后續參數,當前文件的絕對路徑拼接參數
無后續參數,當前文件的絕對路徑
有后續參數,后續參數拼接成的路徑
無后續參數,(./)
后置參數有(./) 解析后的絕對路徑拼接參數 有后續參數,拼接成的路徑拼接后續參數
無后續參數,拼接(/)
首個參數為(../) 有后續參數,覆蓋當前文件的絕對路徑的最后一級目錄后拼接參數
無后續參數,覆蓋當前文件的絕對路徑的最后一級目錄
有后續參數,拼接后續參數
無后續參數,(../)
后置參數有(../) 出現(../)的上層目錄會被覆蓋,后置出現多少個,就會覆蓋多少層,上層目錄被覆蓋完后,返回(/),后續參數會拼接 出現(../)的上層目錄會被覆蓋,后置出現多少個,就會覆蓋多少層,上層目錄被覆蓋完后,會進行參數拼接

總結

閱讀了源碼之后,resolve 方法會對參數進行處理,考慮路徑的形式,在最后拋出絕對路徑。在使用的時候,如果是進行文件之類的操作,推薦使用 resolve 方法,相比來看, resolve 方法就算沒有參數也會返回一個路徑,供使用者操作,在執行過程中會進行路徑的處理。而 join 方法只是對傳入的參數進行規范化拼接,對于生成一個新的路徑比較實用,可以按照使用者意愿創建。不過每個方法都有優點,要根據自己的使用場景以及項目需求,去選擇合適的方法。

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
欧美在线综合| 欧美成人基地 | 99成人在线视频| a国产在线视频| japanese国产精品| 中文字幕一区二区三区在线视频| 中文在线а√天堂| 亚洲午夜一级| 日韩欧美美女在线观看| 日韩和欧美的一区| 啪啪亚洲精品| 麻豆国产欧美日韩综合精品二区| 亚洲激情二区| 免费视频久久| 久久夜色精品| 亚洲欧美日本国产| 欧美在线首页| 国产一区二区三区黄网站 | 精品三级国产| 福利视频一区| 最近高清中文在线字幕在线观看1| 香蕉久久一区| 国产欧美啪啪| 日韩不卡免费高清视频| 成人羞羞在线观看网站| 免费久久久久久久久| 蜜桃视频一区二区三区在线观看| 日韩伦理福利| 午夜精品影院| 日韩av资源网| 成人在线丰满少妇av| 香蕉久久99| 日本亚州欧洲精品不卡| 欧美成人精品午夜一区二区| 日韩欧美精品一区| 国产亚洲永久域名| 国产精品毛片一区二区在线看| 久久九九精品| 日韩福利视频一区| 久久香蕉国产| 精品视频高潮| 日韩精品电影一区亚洲| 欧美日韩国产高清电影| 麻豆精品在线视频| 亚洲精品系列| 欧洲av不卡| 国产精品片aa在线观看| 西西人体一区二区| 精品视频一区二区三区四区五区| 精品国产免费人成网站| 亚洲人成在线影院| 亚洲有吗中文字幕| 免费观看久久久4p| 国产日韩在线观看视频| 欧美日韩尤物久久| 69堂免费精品视频在线播放| 日韩成人亚洲| 久久国际精品| 亚洲精品99| 精品久久久久久久| 久久国产高清| 蜜桃视频在线网站| 国产精品中文字幕亚洲欧美| 欧美午夜精彩| 欧美1区2区3| 亚洲精品少妇| 美女毛片一区二区三区四区| 国产极品模特精品一二| 国产精品美女| 卡一卡二国产精品| 亚州精品视频| 欧美日韩免费观看一区=区三区| 蜜臀久久99精品久久一区二区| 黑人精品一区| 无码日韩精品一区二区免费| 日韩在线观看| 欧美a一区二区| 日韩欧美2区| 久久久久欧美精品| 精品视频网站| 国产精品网址| 亚洲精品在线国产| 中文精品视频| 午夜av不卡| 丝袜美腿一区| 久久人人97超碰国产公开结果| 综合激情一区| 在线视频亚洲| 久久不射网站| 三级在线观看一区二区| 国产精品嫩草99av在线| 欧美aa在线观看| 夜鲁夜鲁夜鲁视频在线播放| 精品国产不卡| 91亚洲国产| 日韩黄色大片网站| 免费污视频在线一区| 久久久久久久久丰满| 伊人久久高清| 国产高清视频一区二区| 欧美日韩亚洲一区在线观看| 亚洲另类黄色| 亚洲日本免费电影| 蜜臀av性久久久久蜜臀aⅴ四虎| 日韩欧美另类中文字幕| 国产精品日本欧美一区二区三区| 综合激情网站| 亚洲精品888| 久久国产亚洲精品| 日韩在线看片| 久久三级视频| 99国产精品免费视频观看| 色偷偷偷在线视频播放| 狠狠躁少妇一区二区三区| 精品成人18| 国产一区二区精品久| 国产成人免费| 福利一区二区三区视频在线观看| 亚洲国产一区二区三区在线播放| 亚州精品视频| 免费成人在线视频观看| 国产毛片久久| 91久久黄色| av不卡在线看| 天堂成人免费av电影一区 | 国产精品激情电影| 日本少妇精品亚洲第一区| 日韩精品免费视频人成| 欧美啪啪一区| 日韩视频不卡| 国产一区导航| 国产精品qvod| 久久天堂精品| 亚洲狼人精品一区二区三区| 久久这里只有| 成人av二区| 最新亚洲激情| 国产亚洲久久| 亚洲精品.com| 中文字幕日韩亚洲| 国产一区二区三区亚洲| 国产精品毛片一区二区三区| 国产亚洲一区| 欧美亚洲精品在线| 青草久久视频| 91精品一区二区三区综合| 久久婷婷一区| 午夜一级久久| 久久国产婷婷国产香蕉| 国产一区一一区高清不卡| 久久久久久美女精品| 在线精品小视频| 日本不卡视频在线观看| 精品国产99| 欧美日韩四区| 欧美一区二区三区久久| 国产成人精品一区二区三区免费 | 久久香蕉网站| 黄毛片在线观看| 欧美亚洲国产一区| 亚洲精品伊人| 成人午夜在线| 亚洲一区二区三区高清| 日韩高清电影免费| 老司机精品视频在线播放| 91看片一区| 亚洲精品人人| 理论片午夜视频在线观看| 国产亚洲在线观看| 国产精品黄色| 日韩视频一区| 捆绑调教美女网站视频一区| 亚洲女同中文字幕| 国产精品jk白丝蜜臀av小说| 欧美亚洲国产精品久久| 日韩成人一级| 久久国产精品成人免费观看的软件| 日本激情一区| 久久中文字幕av| 精品国产欧美日韩| 久久亚洲影院| 亚洲午夜91| 国产suv精品一区| 91亚洲精品在看在线观看高清| 日韩一区中文| 香蕉国产精品| 日韩电影免费在线观看| 久久av影院| 欧美亚洲免费| 亚洲理论在线| 伊人成人网在线看| 色网在线免费观看| 久久精品国产999大香线蕉| 黄色在线一区| 亚洲黄色免费av| 精品精品国产三级a∨在线| 欧美日本久久| 久久久久九九精品影院| av高清不卡| 国产精品久久乐|