中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Node.js path模塊中的常用工具函數怎么使用

發布時間:2022-06-09 09:34:30 來源:億速云 閱讀:149 作者:zzz 欄目:web開發

這篇“Node.js path模塊中的常用工具函數怎么使用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Node.js path模塊中的常用工具函數怎么使用”文章吧。

Node.js path模塊中的常用工具函數怎么使用

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 路徑 ( \servername\sharename,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)}`;
}

執行結果梳理


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

以上就是關于“Node.js path模塊中的常用工具函數怎么使用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

同心县| 镇原县| 太仆寺旗| 隆林| 镇巴县| 隆安县| 莱阳市| 仪征市| 长治市| 蒙自县| 中山市| 方正县| 和静县| 东阿县| 丰原市| 龙山县| 巨鹿县| 霍山县| 汉中市| 呼和浩特市| 江陵县| 兴安县| 凯里市| 隆德县| 乐至县| 渭南市| 重庆市| 博客| 精河县| 陆良县| 道真| 上思县| 晋城| 柞水县| 汪清县| 调兵山市| 屏东市| 咸丰县| 辽宁省| 长武县| 江山市|