[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fpath":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fpath":2075,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fpath":2101},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":2071,"stem":2072,"id":2073,"extension":2074},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fpath","路径处理","path 模块提供了用于处理和转换文件路径的实用工具。它是 Node.js 核心模块，无需安装即可直接使用。由于不同操作系统（Windows、Linux、macOS）的路径分隔符不同（Windows 使用反斜杠 \\，POSIX 使用正…","技能小册",[12,13],"nodejs","path","2024-03-14",false,{"type":17,"value":18,"toc":2057},"minimark",[19,22,31,48,60,63,71,118,385,392,438,660,664,754,759,772,784,790,793,834,925,931,937,968,1178,1182,1189,1225,1232,1246,1318,1325,1331,1426,1433,1446,1482,1499,1505,1508,1520,1557,1563,1570,1581,1635,1645,1648,1806,1811,1843,1846,2027,2030,2047,2053],[20,21,8],"h1",{"id":8},[23,24,26,27,30],"h2",{"id":25},"nodejs-路径处理path-模块","Node.js 路径处理（",[28,29,13],"code",{}," 模块）",[32,33,34,36,37,40,41,44,45,47],"p",{},[28,35,13],{}," 模块提供了用于处理和转换文件路径的实用工具。它是 Node.js 核心模块，无需安装即可直接使用。由于不同操作系统（Windows、Linux、macOS）的路径分隔符不同（Windows 使用反斜杠 ",[28,38,39],{},"\\","，POSIX 使用正斜杠 ",[28,42,43],{},"\u002F","），",[28,46,13],{}," 模块可以自动处理这些差异，实现跨平台兼容。",[49,50,52,53,56,57],"h3",{"id":51},"一pathresolve-vs-pathjoin","一、",[28,54,55],{},"path.resolve"," vs ",[28,58,59],{},"path.join",[32,61,62],{},"两者都用于拼接路径片段，但行为有本质区别。",[64,65,67,68],"h4",{"id":66},"_1-pathjoinpaths","1. ",[28,69,70],{},"path.join([...paths])",[72,73,74,90,112],"ul",{},[75,76,77,81,82,85,86,89],"li",{},[78,79,80],"strong",{},"作用","：将多个路径片段",[78,83,84],{},"拼接","成一个规范化的路径，",[78,87,88],{},"不会","解析绝对路径。",[75,91,92,95,96],{},[78,93,94],{},"规则","：\n",[72,97,98,109],{},[75,99,100,101,104,105,108],{},"从第一个片段开始，依次拼接，遇到 ",[28,102,103],{},".."," 会回到上一级，遇到 ",[28,106,107],{},"."," 或空片段则忽略。",[75,110,111],{},"不会将相对路径转化为绝对路径（除非拼接后的结果本身就是绝对路径的起始）。",[75,113,114,117],{},[78,115,116],{},"示例","：",[119,120,125],"pre",{"className":121,"code":122,"language":123,"meta":124,"style":124},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","const path = require(\"path\");\n\nconsole.log(path.join(\"\u002Ffoo\", \"bar\", \"baz\u002Fasdf\", \"quux\", \"..\"));\n\u002F\u002F 输出: \u002Ffoo\u002Fbar\u002Fbaz\u002Fasdf (quux\u002F.. 被解析为上一级)\n\nconsole.log(path.join(\"a\", \"b\", \"c\", \"..\", \"d\"));\n\u002F\u002F 输出: a\u002Fb\u002Fd\n\nconsole.log(path.join(\"\u002Ffoo\", \"bar\", \"..\", \"\"));\n\u002F\u002F 输出: \u002Ffoo\u002F (空片段被忽略)\n","js","",[28,126,127,168,175,245,252,257,320,326,331,379],{"__ignoreMap":124},[128,129,132,136,140,144,148,152,156,159,161,164],"span",{"class":130,"line":131},"line",1,[128,133,135],{"class":134},"sbsja","const",[128,137,139],{"class":138},"s_hVV"," path",[128,141,143],{"class":142},"smGrS"," =",[128,145,147],{"class":146},"sGLFI"," require",[128,149,151],{"class":150},"su5hD","(",[128,153,155],{"class":154},"sjJ54","\"",[128,157,13],{"class":158},"s_sjI",[128,160,155],{"class":154},[128,162,163],{"class":150},")",[128,165,167],{"class":166},"sP7_E",";\n",[128,169,171],{"class":130,"line":170},2,[128,172,174],{"emptyLinePlaceholder":173},true,"\n",[128,176,178,181,183,186,189,191,194,196,198,201,203,206,209,212,214,216,218,221,223,225,227,230,232,234,236,238,240,243],{"class":130,"line":177},3,[128,179,180],{"class":150},"console",[128,182,107],{"class":166},[128,184,185],{"class":146},"log",[128,187,188],{"class":150},"(path",[128,190,107],{"class":166},[128,192,193],{"class":146},"join",[128,195,151],{"class":150},[128,197,155],{"class":154},[128,199,200],{"class":158},"\u002Ffoo",[128,202,155],{"class":154},[128,204,205],{"class":166},",",[128,207,208],{"class":154}," \"",[128,210,211],{"class":158},"bar",[128,213,155],{"class":154},[128,215,205],{"class":166},[128,217,208],{"class":154},[128,219,220],{"class":158},"baz\u002Fasdf",[128,222,155],{"class":154},[128,224,205],{"class":166},[128,226,208],{"class":154},[128,228,229],{"class":158},"quux",[128,231,155],{"class":154},[128,233,205],{"class":166},[128,235,208],{"class":154},[128,237,103],{"class":158},[128,239,155],{"class":154},[128,241,242],{"class":150},"))",[128,244,167],{"class":166},[128,246,248],{"class":130,"line":247},4,[128,249,251],{"class":250},"sutJx","\u002F\u002F 输出: \u002Ffoo\u002Fbar\u002Fbaz\u002Fasdf (quux\u002F.. 被解析为上一级)\n",[128,253,255],{"class":130,"line":254},5,[128,256,174],{"emptyLinePlaceholder":173},[128,258,260,262,264,266,268,270,272,274,276,279,281,283,285,288,290,292,294,297,299,301,303,305,307,309,311,314,316,318],{"class":130,"line":259},6,[128,261,180],{"class":150},[128,263,107],{"class":166},[128,265,185],{"class":146},[128,267,188],{"class":150},[128,269,107],{"class":166},[128,271,193],{"class":146},[128,273,151],{"class":150},[128,275,155],{"class":154},[128,277,278],{"class":158},"a",[128,280,155],{"class":154},[128,282,205],{"class":166},[128,284,208],{"class":154},[128,286,287],{"class":158},"b",[128,289,155],{"class":154},[128,291,205],{"class":166},[128,293,208],{"class":154},[128,295,296],{"class":158},"c",[128,298,155],{"class":154},[128,300,205],{"class":166},[128,302,208],{"class":154},[128,304,103],{"class":158},[128,306,155],{"class":154},[128,308,205],{"class":166},[128,310,208],{"class":154},[128,312,313],{"class":158},"d",[128,315,155],{"class":154},[128,317,242],{"class":150},[128,319,167],{"class":166},[128,321,323],{"class":130,"line":322},7,[128,324,325],{"class":250},"\u002F\u002F 输出: a\u002Fb\u002Fd\n",[128,327,329],{"class":130,"line":328},8,[128,330,174],{"emptyLinePlaceholder":173},[128,332,334,336,338,340,342,344,346,348,350,352,354,356,358,360,362,364,366,368,370,372,375,377],{"class":130,"line":333},9,[128,335,180],{"class":150},[128,337,107],{"class":166},[128,339,185],{"class":146},[128,341,188],{"class":150},[128,343,107],{"class":166},[128,345,193],{"class":146},[128,347,151],{"class":150},[128,349,155],{"class":154},[128,351,200],{"class":158},[128,353,155],{"class":154},[128,355,205],{"class":166},[128,357,208],{"class":154},[128,359,211],{"class":158},[128,361,155],{"class":154},[128,363,205],{"class":166},[128,365,208],{"class":154},[128,367,103],{"class":158},[128,369,155],{"class":154},[128,371,205],{"class":166},[128,373,374],{"class":154}," \"\"",[128,376,242],{"class":150},[128,378,167],{"class":166},[128,380,382],{"class":130,"line":381},10,[128,383,384],{"class":250},"\u002F\u002F 输出: \u002Ffoo\u002F (空片段被忽略)\n",[64,386,388,389],{"id":387},"_2-pathresolvepaths","2. ",[28,390,391],{},"path.resolve([...paths])",[72,393,394,403,434],{},[75,395,396,398,399,402],{},[78,397,80],{},"：将一系列路径片段",[78,400,401],{},"解析为绝对路径","，从右向左处理，直到生成一个绝对路径为止。",[75,404,405,95,407],{},[78,406,94],{},[72,408,409,415,422],{},[75,410,411,412,414],{},"从最后一个片段开始，向左处理，如果遇到以 ",[28,413,43],{}," 开头的片段（表示绝对路径）或到达最左端，则停止。",[75,416,417,418,421],{},"如果没有生成绝对路径，则自动加上当前工作目录（",[28,419,420],{},"process.cwd()","）作为前缀。",[75,423,424,425,427,428,430,431,433],{},"忽略空片段，并规范化（处理 ",[28,426,103],{},"、",[28,429,107],{},"、多余的 ",[28,432,43],{},"）。",[75,435,436,117],{},[78,437,116],{},[119,439,441],{"className":121,"code":440,"language":123,"meta":124,"style":124},"const path = require(\"path\");\n\nconsole.log(path.resolve(\"\u002Ffoo\", \"\u002Fbar\", \"baz\"));\n\u002F\u002F 输出: \u002Fbar\u002Fbaz (因为 \u002Fbar 是绝对路径，左侧的 \u002Ffoo 被丢弃)\n\nconsole.log(path.resolve(\"a\", \"b\", \"c\"));\n\u002F\u002F 假设当前工作目录是 \u002Fhome\u002Fuser，输出: \u002Fhome\u002Fuser\u002Fa\u002Fb\u002Fc\n\nconsole.log(path.resolve(\"a\", \"..\", \"b\", \"c\"));\n\u002F\u002F 输出: \u002Fhome\u002Fuser\u002Fb\u002Fc\n\nconsole.log(path.resolve());\n\u002F\u002F 输出: 当前工作目录的绝对路径（如 \u002Fhome\u002Fuser）\n",[28,442,443,465,469,514,519,523,565,570,574,624,629,634,654],{"__ignoreMap":124},[128,444,445,447,449,451,453,455,457,459,461,463],{"class":130,"line":131},[128,446,135],{"class":134},[128,448,139],{"class":138},[128,450,143],{"class":142},[128,452,147],{"class":146},[128,454,151],{"class":150},[128,456,155],{"class":154},[128,458,13],{"class":158},[128,460,155],{"class":154},[128,462,163],{"class":150},[128,464,167],{"class":166},[128,466,467],{"class":130,"line":170},[128,468,174],{"emptyLinePlaceholder":173},[128,470,471,473,475,477,479,481,484,486,488,490,492,494,496,499,501,503,505,508,510,512],{"class":130,"line":177},[128,472,180],{"class":150},[128,474,107],{"class":166},[128,476,185],{"class":146},[128,478,188],{"class":150},[128,480,107],{"class":166},[128,482,483],{"class":146},"resolve",[128,485,151],{"class":150},[128,487,155],{"class":154},[128,489,200],{"class":158},[128,491,155],{"class":154},[128,493,205],{"class":166},[128,495,208],{"class":154},[128,497,498],{"class":158},"\u002Fbar",[128,500,155],{"class":154},[128,502,205],{"class":166},[128,504,208],{"class":154},[128,506,507],{"class":158},"baz",[128,509,155],{"class":154},[128,511,242],{"class":150},[128,513,167],{"class":166},[128,515,516],{"class":130,"line":247},[128,517,518],{"class":250},"\u002F\u002F 输出: \u002Fbar\u002Fbaz (因为 \u002Fbar 是绝对路径，左侧的 \u002Ffoo 被丢弃)\n",[128,520,521],{"class":130,"line":254},[128,522,174],{"emptyLinePlaceholder":173},[128,524,525,527,529,531,533,535,537,539,541,543,545,547,549,551,553,555,557,559,561,563],{"class":130,"line":259},[128,526,180],{"class":150},[128,528,107],{"class":166},[128,530,185],{"class":146},[128,532,188],{"class":150},[128,534,107],{"class":166},[128,536,483],{"class":146},[128,538,151],{"class":150},[128,540,155],{"class":154},[128,542,278],{"class":158},[128,544,155],{"class":154},[128,546,205],{"class":166},[128,548,208],{"class":154},[128,550,287],{"class":158},[128,552,155],{"class":154},[128,554,205],{"class":166},[128,556,208],{"class":154},[128,558,296],{"class":158},[128,560,155],{"class":154},[128,562,242],{"class":150},[128,564,167],{"class":166},[128,566,567],{"class":130,"line":322},[128,568,569],{"class":250},"\u002F\u002F 假设当前工作目录是 \u002Fhome\u002Fuser，输出: \u002Fhome\u002Fuser\u002Fa\u002Fb\u002Fc\n",[128,571,572],{"class":130,"line":328},[128,573,174],{"emptyLinePlaceholder":173},[128,575,576,578,580,582,584,586,588,590,592,594,596,598,600,602,604,606,608,610,612,614,616,618,620,622],{"class":130,"line":333},[128,577,180],{"class":150},[128,579,107],{"class":166},[128,581,185],{"class":146},[128,583,188],{"class":150},[128,585,107],{"class":166},[128,587,483],{"class":146},[128,589,151],{"class":150},[128,591,155],{"class":154},[128,593,278],{"class":158},[128,595,155],{"class":154},[128,597,205],{"class":166},[128,599,208],{"class":154},[128,601,103],{"class":158},[128,603,155],{"class":154},[128,605,205],{"class":166},[128,607,208],{"class":154},[128,609,287],{"class":158},[128,611,155],{"class":154},[128,613,205],{"class":166},[128,615,208],{"class":154},[128,617,296],{"class":158},[128,619,155],{"class":154},[128,621,242],{"class":150},[128,623,167],{"class":166},[128,625,626],{"class":130,"line":381},[128,627,628],{"class":250},"\u002F\u002F 输出: \u002Fhome\u002Fuser\u002Fb\u002Fc\n",[128,630,632],{"class":130,"line":631},11,[128,633,174],{"emptyLinePlaceholder":173},[128,635,637,639,641,643,645,647,649,652],{"class":130,"line":636},12,[128,638,180],{"class":150},[128,640,107],{"class":166},[128,642,185],{"class":146},[128,644,188],{"class":150},[128,646,107],{"class":166},[128,648,483],{"class":146},[128,650,651],{"class":150},"())",[128,653,167],{"class":166},[128,655,657],{"class":130,"line":656},13,[128,658,659],{"class":250},"\u002F\u002F 输出: 当前工作目录的绝对路径（如 \u002Fhome\u002Fuser）\n",[64,661,663],{"id":662},"_3-关键区别总结","3. 关键区别总结",[665,666,667,685],"table",{},[668,669,670],"thead",{},[671,672,673,677,681],"tr",{},[674,675,676],"th",{},"特性",[674,678,679],{},[28,680,59],{},[674,682,683],{},[28,684,55],{},[686,687,688,702,715,728,741],"tbody",{},[671,689,690,696,699],{},[691,692,693],"td",{},[78,694,695],{},"目标",[691,697,698],{},"拼接路径片段",[691,700,701],{},"生成绝对路径",[671,703,704,709,712],{},[691,705,706],{},[78,707,708],{},"当前工作目录影响",[691,710,711],{},"否",[691,713,714],{},"是（当没有给出绝对路径时会自动添加）",[671,716,717,722,725],{},[691,718,719],{},[78,720,721],{},"处理左侧绝对路径",[691,723,724],{},"会保留所有片段，仅做规范化",[691,726,727],{},"遇到绝对路径后左侧片段被丢弃",[671,729,730,735,738],{},[691,731,732],{},[78,733,734],{},"返回值类型",[691,736,737],{},"可能是相对路径或绝对路径（取决于输入）",[691,739,740],{},"总是绝对路径",[671,742,743,748,751],{},[691,744,745],{},[78,746,747],{},"典型使用场景",[691,749,750],{},"相对路径拼接、构造文件路径",[691,752,753],{},"将相对路径转换为绝对路径，用于文件系统操作",[32,755,756,117],{},[78,757,758],{},"选择建议",[72,760,761,767],{},[75,762,763,764,766],{},"当你需要拼接多个路径片段，且不关心是否绝对路径时，使用 ",[28,765,59],{},"。",[75,768,769,770,766],{},"当你需要将一个相对路径解析为绝对路径（例如读取文件时），使用 ",[28,771,55],{},[49,773,775,776,779,780,783],{"id":774},"二解析路径parse格式化format","二、解析路径（",[28,777,778],{},"parse","）、格式化（",[28,781,782],{},"format","）",[64,785,67,787],{"id":786},"_1-pathparsepathstring",[28,788,789],{},"path.parse(pathString)",[32,791,792],{},"将一个路径字符串解析成一个对象，包含以下属性：",[72,794,795,807,813,819,828],{},[75,796,797,800,801,804,805,783],{},[28,798,799],{},"root","：根路径（如 Windows 上的 ",[28,802,803],{},"C:\\","，POSIX 上的 ",[28,806,43],{},[75,808,809,812],{},[28,810,811],{},"dir","：目录路径（不包含文件名）",[75,814,815,818],{},[28,816,817],{},"base","：文件全名（包含扩展名）",[75,820,821,824,825,783],{},[28,822,823],{},"ext","：扩展名（包含点号，如 ",[28,826,827],{},".js",[75,829,830,833],{},[28,831,832],{},"name","：文件名（不含扩展名）",[119,835,837],{"className":121,"code":836,"language":123,"meta":124,"style":124},"const parsed = path.parse(\"\u002Fhome\u002Fuser\u002Fdocs\u002Ffile.txt\");\nconsole.log(parsed);\n\u002F*\n{\n  root: '\u002F',\n  dir: '\u002Fhome\u002Fuser\u002Fdocs',\n  base: 'file.txt',\n  ext: '.txt',\n  name: 'file'\n}\n*\u002F\n",[28,838,839,867,880,885,890,895,900,905,910,915,920],{"__ignoreMap":124},[128,840,841,843,846,848,850,852,854,856,858,861,863,865],{"class":130,"line":131},[128,842,135],{"class":134},[128,844,845],{"class":138}," parsed",[128,847,143],{"class":142},[128,849,139],{"class":150},[128,851,107],{"class":166},[128,853,778],{"class":146},[128,855,151],{"class":150},[128,857,155],{"class":154},[128,859,860],{"class":158},"\u002Fhome\u002Fuser\u002Fdocs\u002Ffile.txt",[128,862,155],{"class":154},[128,864,163],{"class":150},[128,866,167],{"class":166},[128,868,869,871,873,875,878],{"class":130,"line":170},[128,870,180],{"class":150},[128,872,107],{"class":166},[128,874,185],{"class":146},[128,876,877],{"class":150},"(parsed)",[128,879,167],{"class":166},[128,881,882],{"class":130,"line":177},[128,883,884],{"class":250},"\u002F*\n",[128,886,887],{"class":130,"line":247},[128,888,889],{"class":250},"{\n",[128,891,892],{"class":130,"line":254},[128,893,894],{"class":250},"  root: '\u002F',\n",[128,896,897],{"class":130,"line":259},[128,898,899],{"class":250},"  dir: '\u002Fhome\u002Fuser\u002Fdocs',\n",[128,901,902],{"class":130,"line":322},[128,903,904],{"class":250},"  base: 'file.txt',\n",[128,906,907],{"class":130,"line":328},[128,908,909],{"class":250},"  ext: '.txt',\n",[128,911,912],{"class":130,"line":333},[128,913,914],{"class":250},"  name: 'file'\n",[128,916,917],{"class":130,"line":381},[128,918,919],{"class":250},"}\n",[128,921,922],{"class":130,"line":631},[128,923,924],{"class":250},"*\u002F\n",[64,926,388,928],{"id":927},"_2-pathformatpathobject",[28,929,930],{},"path.format(pathObject)",[32,932,933,934,936],{},"与 ",[28,935,778],{}," 相反，将对象转换为路径字符串。可以部分提供属性，优先使用以下组合：",[72,938,939,950,958],{},[75,940,941,942,944,945,947,948,766],{},"如果有 ",[28,943,811],{},"，则忽略 ",[28,946,799],{}," 和 ",[28,949,817],{},[75,951,941,952,944,954,947,956,766],{},[28,953,817],{},[28,955,823],{},[28,957,832],{},[75,959,960,961,963,964,963,966,766],{},"否则使用 ",[28,962,799],{}," + ",[28,965,832],{},[28,967,823],{},[119,969,971],{"className":121,"code":970,"language":123,"meta":124,"style":124},"const formatted = path.format({\n    root: \"\u002F\",\n    dir: \"\u002Fhome\u002Fuser\u002Fdocs\",\n    base: \"file.txt\",\n    ext: \".txt\",\n    name: \"file\",\n});\nconsole.log(formatted); \u002F\u002F \u002Fhome\u002Fuser\u002Fdocs\u002Ffile.txt\n\n\u002F\u002F 仅提供 name 和 ext\nconst formatted2 = path.format({ name: \"image\", ext: \".png\" });\nconsole.log(formatted2); \u002F\u002F image.png (会被添加到当前工作目录下？不，它只是相对路径)\n",[28,972,973,992,1010,1026,1042,1058,1074,1083,1100,1104,1109,1162],{"__ignoreMap":124},[128,974,975,977,980,982,984,986,988,990],{"class":130,"line":131},[128,976,135],{"class":134},[128,978,979],{"class":138}," formatted",[128,981,143],{"class":142},[128,983,139],{"class":150},[128,985,107],{"class":166},[128,987,782],{"class":146},[128,989,151],{"class":150},[128,991,889],{"class":166},[128,993,994,998,1001,1003,1005,1007],{"class":130,"line":170},[128,995,997],{"class":996},"skxfh","    root",[128,999,1000],{"class":166},":",[128,1002,208],{"class":154},[128,1004,43],{"class":158},[128,1006,155],{"class":154},[128,1008,1009],{"class":166},",\n",[128,1011,1012,1015,1017,1019,1022,1024],{"class":130,"line":177},[128,1013,1014],{"class":996},"    dir",[128,1016,1000],{"class":166},[128,1018,208],{"class":154},[128,1020,1021],{"class":158},"\u002Fhome\u002Fuser\u002Fdocs",[128,1023,155],{"class":154},[128,1025,1009],{"class":166},[128,1027,1028,1031,1033,1035,1038,1040],{"class":130,"line":247},[128,1029,1030],{"class":996},"    base",[128,1032,1000],{"class":166},[128,1034,208],{"class":154},[128,1036,1037],{"class":158},"file.txt",[128,1039,155],{"class":154},[128,1041,1009],{"class":166},[128,1043,1044,1047,1049,1051,1054,1056],{"class":130,"line":254},[128,1045,1046],{"class":996},"    ext",[128,1048,1000],{"class":166},[128,1050,208],{"class":154},[128,1052,1053],{"class":158},".txt",[128,1055,155],{"class":154},[128,1057,1009],{"class":166},[128,1059,1060,1063,1065,1067,1070,1072],{"class":130,"line":259},[128,1061,1062],{"class":996},"    name",[128,1064,1000],{"class":166},[128,1066,208],{"class":154},[128,1068,1069],{"class":158},"file",[128,1071,155],{"class":154},[128,1073,1009],{"class":166},[128,1075,1076,1079,1081],{"class":130,"line":322},[128,1077,1078],{"class":166},"}",[128,1080,163],{"class":150},[128,1082,167],{"class":166},[128,1084,1085,1087,1089,1091,1094,1097],{"class":130,"line":328},[128,1086,180],{"class":150},[128,1088,107],{"class":166},[128,1090,185],{"class":146},[128,1092,1093],{"class":150},"(formatted)",[128,1095,1096],{"class":166},";",[128,1098,1099],{"class":250}," \u002F\u002F \u002Fhome\u002Fuser\u002Fdocs\u002Ffile.txt\n",[128,1101,1102],{"class":130,"line":333},[128,1103,174],{"emptyLinePlaceholder":173},[128,1105,1106],{"class":130,"line":381},[128,1107,1108],{"class":250},"\u002F\u002F 仅提供 name 和 ext\n",[128,1110,1111,1113,1116,1118,1120,1122,1124,1126,1129,1132,1134,1136,1139,1141,1143,1146,1148,1150,1153,1155,1158,1160],{"class":130,"line":631},[128,1112,135],{"class":134},[128,1114,1115],{"class":138}," formatted2",[128,1117,143],{"class":142},[128,1119,139],{"class":150},[128,1121,107],{"class":166},[128,1123,782],{"class":146},[128,1125,151],{"class":150},[128,1127,1128],{"class":166},"{",[128,1130,1131],{"class":996}," name",[128,1133,1000],{"class":166},[128,1135,208],{"class":154},[128,1137,1138],{"class":158},"image",[128,1140,155],{"class":154},[128,1142,205],{"class":166},[128,1144,1145],{"class":996}," ext",[128,1147,1000],{"class":166},[128,1149,208],{"class":154},[128,1151,1152],{"class":158},".png",[128,1154,155],{"class":154},[128,1156,1157],{"class":166}," }",[128,1159,163],{"class":150},[128,1161,167],{"class":166},[128,1163,1164,1166,1168,1170,1173,1175],{"class":130,"line":636},[128,1165,180],{"class":150},[128,1167,107],{"class":166},[128,1169,185],{"class":146},[128,1171,1172],{"class":150},"(formatted2)",[128,1174,1096],{"class":166},[128,1176,1177],{"class":250}," \u002F\u002F image.png (会被添加到当前工作目录下？不，它只是相对路径)\n",[49,1179,1181],{"id":1180},"三获取文件名扩展名等常用操作","三、获取文件名、扩展名等常用操作",[64,1183,1185,1186],{"id":1184},"_1-获取目录名pathdirnamepath","1. 获取目录名：",[28,1187,1188],{},"path.dirname(path)",[119,1190,1192],{"className":121,"code":1191,"language":123,"meta":124,"style":124},"console.log(path.dirname(\"\u002Fa\u002Fb\u002Fc\u002Fd.js\")); \u002F\u002F \u002Fa\u002Fb\u002Fc\n",[28,1193,1194],{"__ignoreMap":124},[128,1195,1196,1198,1200,1202,1204,1206,1209,1211,1213,1216,1218,1220,1222],{"class":130,"line":131},[128,1197,180],{"class":150},[128,1199,107],{"class":166},[128,1201,185],{"class":146},[128,1203,188],{"class":150},[128,1205,107],{"class":166},[128,1207,1208],{"class":146},"dirname",[128,1210,151],{"class":150},[128,1212,155],{"class":154},[128,1214,1215],{"class":158},"\u002Fa\u002Fb\u002Fc\u002Fd.js",[128,1217,155],{"class":154},[128,1219,242],{"class":150},[128,1221,1096],{"class":166},[128,1223,1224],{"class":250}," \u002F\u002F \u002Fa\u002Fb\u002Fc\n",[64,1226,1228,1229],{"id":1227},"_2-获取文件名包含扩展名pathbasenamepath-ext","2. 获取文件名（包含扩展名）：",[28,1230,1231],{},"path.basename(path[, ext])",[72,1233,1234,1240],{},[75,1235,1236,1237,1239],{},"如果不带 ",[28,1238,823],{},"，返回完整文件名（含扩展名）。",[75,1241,1242,1243,1245],{},"如果传入 ",[28,1244,823],{},"，则会从结果中移除该扩展名（如果匹配）。",[119,1247,1249],{"className":121,"code":1248,"language":123,"meta":124,"style":124},"console.log(path.basename(\"\u002Fa\u002Fb\u002Fc\u002Fd.js\")); \u002F\u002F d.js\nconsole.log(path.basename(\"\u002Fa\u002Fb\u002Fc\u002Fd.js\", \".js\")); \u002F\u002F d\n",[28,1250,1251,1281],{"__ignoreMap":124},[128,1252,1253,1255,1257,1259,1261,1263,1266,1268,1270,1272,1274,1276,1278],{"class":130,"line":131},[128,1254,180],{"class":150},[128,1256,107],{"class":166},[128,1258,185],{"class":146},[128,1260,188],{"class":150},[128,1262,107],{"class":166},[128,1264,1265],{"class":146},"basename",[128,1267,151],{"class":150},[128,1269,155],{"class":154},[128,1271,1215],{"class":158},[128,1273,155],{"class":154},[128,1275,242],{"class":150},[128,1277,1096],{"class":166},[128,1279,1280],{"class":250}," \u002F\u002F d.js\n",[128,1282,1283,1285,1287,1289,1291,1293,1295,1297,1299,1301,1303,1305,1307,1309,1311,1313,1315],{"class":130,"line":170},[128,1284,180],{"class":150},[128,1286,107],{"class":166},[128,1288,185],{"class":146},[128,1290,188],{"class":150},[128,1292,107],{"class":166},[128,1294,1265],{"class":146},[128,1296,151],{"class":150},[128,1298,155],{"class":154},[128,1300,1215],{"class":158},[128,1302,155],{"class":154},[128,1304,205],{"class":166},[128,1306,208],{"class":154},[128,1308,827],{"class":158},[128,1310,155],{"class":154},[128,1312,242],{"class":150},[128,1314,1096],{"class":166},[128,1316,1317],{"class":250}," \u002F\u002F d\n",[64,1319,1321,1322],{"id":1320},"_3-获取扩展名pathextnamepath","3. 获取扩展名：",[28,1323,1324],{},"path.extname(path)",[32,1326,1327,1328,1330],{},"返回从最后一个 ",[28,1329,107],{}," 字符到末尾的字符串（包括点），如果没有点则返回空字符串。",[119,1332,1334],{"className":121,"code":1333,"language":123,"meta":124,"style":124},"console.log(path.extname(\"\u002Fa\u002Fb\u002Fc\u002Fd.js\")); \u002F\u002F .js\nconsole.log(path.extname(\"\u002Fa\u002Fb\u002Fc\u002F.dotfile\")); \u002F\u002F '' (点开头的文件不算扩展名)\nconsole.log(path.extname(\"\u002Fa\u002Fb\u002Fc\u002Ffile\")); \u002F\u002F ''\n",[28,1335,1336,1366,1396],{"__ignoreMap":124},[128,1337,1338,1340,1342,1344,1346,1348,1351,1353,1355,1357,1359,1361,1363],{"class":130,"line":131},[128,1339,180],{"class":150},[128,1341,107],{"class":166},[128,1343,185],{"class":146},[128,1345,188],{"class":150},[128,1347,107],{"class":166},[128,1349,1350],{"class":146},"extname",[128,1352,151],{"class":150},[128,1354,155],{"class":154},[128,1356,1215],{"class":158},[128,1358,155],{"class":154},[128,1360,242],{"class":150},[128,1362,1096],{"class":166},[128,1364,1365],{"class":250}," \u002F\u002F .js\n",[128,1367,1368,1370,1372,1374,1376,1378,1380,1382,1384,1387,1389,1391,1393],{"class":130,"line":170},[128,1369,180],{"class":150},[128,1371,107],{"class":166},[128,1373,185],{"class":146},[128,1375,188],{"class":150},[128,1377,107],{"class":166},[128,1379,1350],{"class":146},[128,1381,151],{"class":150},[128,1383,155],{"class":154},[128,1385,1386],{"class":158},"\u002Fa\u002Fb\u002Fc\u002F.dotfile",[128,1388,155],{"class":154},[128,1390,242],{"class":150},[128,1392,1096],{"class":166},[128,1394,1395],{"class":250}," \u002F\u002F '' (点开头的文件不算扩展名)\n",[128,1397,1398,1400,1402,1404,1406,1408,1410,1412,1414,1417,1419,1421,1423],{"class":130,"line":177},[128,1399,180],{"class":150},[128,1401,107],{"class":166},[128,1403,185],{"class":146},[128,1405,188],{"class":150},[128,1407,107],{"class":166},[128,1409,1350],{"class":146},[128,1411,151],{"class":150},[128,1413,155],{"class":154},[128,1415,1416],{"class":158},"\u002Fa\u002Fb\u002Fc\u002Ffile",[128,1418,155],{"class":154},[128,1420,242],{"class":150},[128,1422,1096],{"class":166},[128,1424,1425],{"class":250}," \u002F\u002F ''\n",[64,1427,1429,1430],{"id":1428},"_4-规范化路径pathnormalizepath","4. 规范化路径：",[28,1431,1432],{},"path.normalize(path)",[32,1434,1435,1436,427,1438,430,1440,1442,1443,1445],{},"将路径中的 ",[28,1437,103],{},[28,1439,107],{},[28,1441,43],{}," 或 ",[28,1444,39],{}," 等处理成标准形式。",[119,1447,1449],{"className":121,"code":1448,"language":123,"meta":124,"style":124},"console.log(path.normalize(\"\u002Ffoo\u002F\u002Fbar\u002Fbaz\u002F..\u002Fqux\")); \u002F\u002F \u002Ffoo\u002Fbar\u002Fqux\n",[28,1450,1451],{"__ignoreMap":124},[128,1452,1453,1455,1457,1459,1461,1463,1466,1468,1470,1473,1475,1477,1479],{"class":130,"line":131},[128,1454,180],{"class":150},[128,1456,107],{"class":166},[128,1458,185],{"class":146},[128,1460,188],{"class":150},[128,1462,107],{"class":166},[128,1464,1465],{"class":146},"normalize",[128,1467,151],{"class":150},[128,1469,155],{"class":154},[128,1471,1472],{"class":158},"\u002Ffoo\u002F\u002Fbar\u002Fbaz\u002F..\u002Fqux",[128,1474,155],{"class":154},[128,1476,242],{"class":150},[128,1478,1096],{"class":166},[128,1480,1481],{"class":250}," \u002F\u002F \u002Ffoo\u002Fbar\u002Fqux\n",[49,1483,1485,1486,427,1489,427,1492,43,1495,1498],{"id":1484},"四跨平台兼容sepdelimiterwin32posix-属性","四、跨平台兼容：",[28,1487,1488],{},"sep",[28,1490,1491],{},"delimiter",[28,1493,1494],{},"win32",[28,1496,1497],{},"posix"," 属性",[64,1500,67,1502],{"id":1501},"_1-pathsep",[28,1503,1504],{},"path.sep",[32,1506,1507],{},"当前操作系统的路径片段分隔符：",[72,1509,1510,1515],{},[75,1511,1512,1513],{},"Windows: ",[28,1514,39],{},[75,1516,1517,1518],{},"POSIX (Linux\u002FmacOS): ",[28,1519,43],{},[119,1521,1523],{"className":121,"code":1522,"language":123,"meta":124,"style":124},"console.log(path.sep);\n\u002F\u002F Windows 输出: \\\n\u002F\u002F POSIX 输出: \u002F\n\u002F\u002F 拼接跨平台路径时可以这样写：paths.join('a', 'b', 'c') 会自动使用正确分隔符\n",[28,1524,1525,1542,1547,1552],{"__ignoreMap":124},[128,1526,1527,1529,1531,1533,1535,1537,1540],{"class":130,"line":131},[128,1528,180],{"class":150},[128,1530,107],{"class":166},[128,1532,185],{"class":146},[128,1534,188],{"class":150},[128,1536,107],{"class":166},[128,1538,1539],{"class":150},"sep)",[128,1541,167],{"class":166},[128,1543,1544],{"class":130,"line":170},[128,1545,1546],{"class":250},"\u002F\u002F Windows 输出: \\\n",[128,1548,1549],{"class":130,"line":177},[128,1550,1551],{"class":250},"\u002F\u002F POSIX 输出: \u002F\n",[128,1553,1554],{"class":130,"line":247},[128,1555,1556],{"class":250},"\u002F\u002F 拼接跨平台路径时可以这样写：paths.join('a', 'b', 'c') 会自动使用正确分隔符\n",[64,1558,388,1560],{"id":1559},"_2-pathdelimiter",[28,1561,1562],{},"path.delimiter",[32,1564,1565,1566,1569],{},"环境变量 ",[28,1567,1568],{},"PATH"," 中的路径分隔符：",[72,1571,1572,1576],{},[75,1573,1512,1574],{},[28,1575,1096],{},[75,1577,1578,1579],{},"POSIX: ",[28,1580,1000],{},[119,1582,1584],{"className":121,"code":1583,"language":123,"meta":124,"style":124},"console.log(path.delimiter);\n\u002F\u002F 通常用于解析 process.env.PATH\nprocess.env.PATH.split(path.delimiter);\n",[28,1585,1586,1603,1608],{"__ignoreMap":124},[128,1587,1588,1590,1592,1594,1596,1598,1601],{"class":130,"line":131},[128,1589,180],{"class":150},[128,1591,107],{"class":166},[128,1593,185],{"class":146},[128,1595,188],{"class":150},[128,1597,107],{"class":166},[128,1599,1600],{"class":150},"delimiter)",[128,1602,167],{"class":166},[128,1604,1605],{"class":130,"line":170},[128,1606,1607],{"class":250},"\u002F\u002F 通常用于解析 process.env.PATH\n",[128,1609,1610,1613,1615,1618,1620,1622,1624,1627,1629,1631,1633],{"class":130,"line":177},[128,1611,1612],{"class":150},"process",[128,1614,107],{"class":166},[128,1616,1617],{"class":150},"env",[128,1619,107],{"class":166},[128,1621,1568],{"class":138},[128,1623,107],{"class":166},[128,1625,1626],{"class":146},"split",[128,1628,188],{"class":150},[128,1630,107],{"class":166},[128,1632,1600],{"class":150},[128,1634,167],{"class":166},[64,1636,1638,1639,947,1642],{"id":1637},"_3-pathwin32-和-pathposix","3. ",[28,1640,1641],{},"path.win32",[28,1643,1644],{},"path.posix",[32,1646,1647],{},"这两个对象分别提供 Windows 和 POSIX 风格的路径操作方法，无论当前系统是什么，都可以强制使用某种风格。",[119,1649,1651],{"className":121,"code":1650,"language":123,"meta":124,"style":124},"\u002F\u002F 即使在 Linux 上，也可以使用 Windows 风格\nconst winPath = path.win32.join(\"C:\", \"Users\", \"John\", \"file.txt\");\nconsole.log(winPath); \u002F\u002F C:\\Users\\John\\file.txt\n\n\u002F\u002F 强制使用 POSIX 风格\nconst posixPath = path.posix.join(\"\u002Fhome\", \"user\", \"file.txt\");\nconsole.log(posixPath); \u002F\u002F \u002Fhome\u002Fuser\u002Ffile.txt\n",[28,1652,1653,1658,1716,1732,1736,1741,1790],{"__ignoreMap":124},[128,1654,1655],{"class":130,"line":131},[128,1656,1657],{"class":250},"\u002F\u002F 即使在 Linux 上，也可以使用 Windows 风格\n",[128,1659,1660,1662,1665,1667,1669,1671,1673,1675,1677,1679,1681,1684,1686,1688,1690,1693,1695,1697,1699,1702,1704,1706,1708,1710,1712,1714],{"class":130,"line":170},[128,1661,135],{"class":134},[128,1663,1664],{"class":138}," winPath",[128,1666,143],{"class":142},[128,1668,139],{"class":150},[128,1670,107],{"class":166},[128,1672,1494],{"class":150},[128,1674,107],{"class":166},[128,1676,193],{"class":146},[128,1678,151],{"class":150},[128,1680,155],{"class":154},[128,1682,1683],{"class":158},"C:",[128,1685,155],{"class":154},[128,1687,205],{"class":166},[128,1689,208],{"class":154},[128,1691,1692],{"class":158},"Users",[128,1694,155],{"class":154},[128,1696,205],{"class":166},[128,1698,208],{"class":154},[128,1700,1701],{"class":158},"John",[128,1703,155],{"class":154},[128,1705,205],{"class":166},[128,1707,208],{"class":154},[128,1709,1037],{"class":158},[128,1711,155],{"class":154},[128,1713,163],{"class":150},[128,1715,167],{"class":166},[128,1717,1718,1720,1722,1724,1727,1729],{"class":130,"line":177},[128,1719,180],{"class":150},[128,1721,107],{"class":166},[128,1723,185],{"class":146},[128,1725,1726],{"class":150},"(winPath)",[128,1728,1096],{"class":166},[128,1730,1731],{"class":250}," \u002F\u002F C:\\Users\\John\\file.txt\n",[128,1733,1734],{"class":130,"line":247},[128,1735,174],{"emptyLinePlaceholder":173},[128,1737,1738],{"class":130,"line":254},[128,1739,1740],{"class":250},"\u002F\u002F 强制使用 POSIX 风格\n",[128,1742,1743,1745,1748,1750,1752,1754,1756,1758,1760,1762,1764,1767,1769,1771,1773,1776,1778,1780,1782,1784,1786,1788],{"class":130,"line":259},[128,1744,135],{"class":134},[128,1746,1747],{"class":138}," posixPath",[128,1749,143],{"class":142},[128,1751,139],{"class":150},[128,1753,107],{"class":166},[128,1755,1497],{"class":150},[128,1757,107],{"class":166},[128,1759,193],{"class":146},[128,1761,151],{"class":150},[128,1763,155],{"class":154},[128,1765,1766],{"class":158},"\u002Fhome",[128,1768,155],{"class":154},[128,1770,205],{"class":166},[128,1772,208],{"class":154},[128,1774,1775],{"class":158},"user",[128,1777,155],{"class":154},[128,1779,205],{"class":166},[128,1781,208],{"class":154},[128,1783,1037],{"class":158},[128,1785,155],{"class":154},[128,1787,163],{"class":150},[128,1789,167],{"class":166},[128,1791,1792,1794,1796,1798,1801,1803],{"class":130,"line":322},[128,1793,180],{"class":150},[128,1795,107],{"class":166},[128,1797,185],{"class":146},[128,1799,1800],{"class":150},"(posixPath)",[128,1802,1096],{"class":166},[128,1804,1805],{"class":250}," \u002F\u002F \u002Fhome\u002Fuser\u002Ffile.txt\n",[32,1807,1808,117],{},[78,1809,1810],{},"跨平台开发建议",[72,1812,1813,1825,1834],{},[75,1814,1815,1816,947,1818,1820,1821,1442,1823,766],{},"尽量使用 ",[28,1817,59],{},[28,1819,55],{},"，而不是手动拼接 ",[28,1822,43],{},[28,1824,39],{},[75,1826,1827,1828,1830,1831,1833],{},"避免在代码中硬编码路径分隔符，使用 ",[28,1829,1504],{}," 或依赖 ",[28,1832,13],{}," 模块的方法。",[75,1835,1836,1837,1442,1840,1842],{},"如果需要处理用户输入的路径（可能来自 Windows 或 Linux），可以先用 ",[28,1838,1839],{},"path.normalize",[28,1841,55],{}," 标准化。",[49,1844,1845],{"id":1845},"总结表",[665,1847,1848,1863],{},[668,1849,1850],{},[671,1851,1852,1855,1858,1861],{},[674,1853,1854],{},"方法",[674,1856,1857],{},"功能",[674,1859,1860],{},"是否依赖当前工作目录",[674,1862,734],{},[686,1864,1865,1879,1894,1909,1923,1937,1952,1966,1984,1998,2011],{},[671,1866,1867,1871,1874,1876],{},[691,1868,1869],{},[28,1870,59],{},[691,1872,1873],{},"拼接路径片段，规范化",[691,1875,711],{},[691,1877,1878],{},"相对或绝对",[671,1880,1881,1885,1888,1891],{},[691,1882,1883],{},[28,1884,55],{},[691,1886,1887],{},"解析绝对路径（右到左）",[691,1889,1890],{},"是（未发现绝对路径时）",[691,1892,1893],{},"绝对路径",[671,1895,1896,1901,1904,1906],{},[691,1897,1898],{},[28,1899,1900],{},"path.dirname",[691,1902,1903],{},"获取路径的目录部分",[691,1905,711],{},[691,1907,1908],{},"字符串",[671,1910,1911,1916,1919,1921],{},[691,1912,1913],{},[28,1914,1915],{},"path.basename",[691,1917,1918],{},"获取文件名（含扩展名）",[691,1920,711],{},[691,1922,1908],{},[671,1924,1925,1930,1933,1935],{},[691,1926,1927],{},[28,1928,1929],{},"path.extname",[691,1931,1932],{},"获取扩展名",[691,1934,711],{},[691,1936,1908],{},[671,1938,1939,1944,1947,1949],{},[691,1940,1941],{},[28,1942,1943],{},"path.parse",[691,1945,1946],{},"解析路径为对象",[691,1948,711],{},[691,1950,1951],{},"对象",[671,1953,1954,1959,1962,1964],{},[691,1955,1956],{},[28,1957,1958],{},"path.format",[691,1960,1961],{},"从对象生成路径字符串",[691,1963,711],{},[691,1965,1908],{},[671,1967,1968,1972,1980,1982],{},[691,1969,1970],{},[28,1971,1839],{},[691,1973,1974,1975,427,1977,1979],{},"规范化路径（解析 ",[28,1976,103],{},[28,1978,107],{}," 等）",[691,1981,711],{},[691,1983,1908],{},[671,1985,1986,1990,1993,1996],{},[691,1987,1988],{},[28,1989,1504],{},[691,1991,1992],{},"平台路径分隔符",[691,1994,1995],{},"-",[691,1997,1908],{},[671,1999,2000,2004,2007,2009],{},[691,2001,2002],{},[28,2003,1562],{},[691,2005,2006],{},"环境变量分隔符",[691,2008,1995],{},[691,2010,1908],{},[671,2012,2013,2020,2023,2025],{},[691,2014,2015,2017,2018],{},[28,2016,1641],{}," \u002F ",[28,2019,1644],{},[691,2021,2022],{},"强制使用特定平台风格",[691,2024,1995],{},[691,2026,1951],{},[23,2028,2029],{"id":2029},"推荐参考资料",[72,2031,2032,2041,2044],{},[75,2033,2034,2035],{},"Node.js 官方文档：",[278,2036,2040],{"href":2037,"rel":2038},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fpath.html",[2039],"nofollow","Path",[75,2042,2043],{},"中文文档：Node.js 路径模块详解",[75,2045,2046],{},"实践建议：跨平台 Node.js 项目中的路径处理最佳实践",[32,2048,2049,2050,2052],{},"掌握 ",[28,2051,13],{}," 模块，能够写出更健壮、跨平台的文件处理代码，避免因操作系统差异导致的 Bug。",[2054,2055,2056],"style",{},"html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":124,"searchDepth":170,"depth":170,"links":2058},[2059,2070],{"id":25,"depth":170,"text":2060,"children":2061},"Node.js 路径处理（path 模块）",[2062,2064,2066,2067,2069],{"id":51,"depth":177,"text":2063},"一、path.resolve vs path.join",{"id":774,"depth":177,"text":2065},"二、解析路径（parse）、格式化（format）",{"id":1180,"depth":177,"text":1181},{"id":1484,"depth":177,"text":2068},"四、跨平台兼容：sep、delimiter、win32\u002Fposix 属性",{"id":1845,"depth":177,"text":1845},{"id":2029,"depth":170,"text":2029},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fend\u002FNodeJs\u002Fcore\u002Fpath","knowledge\u002Fknowledge\u002Fbooklet\u002Fend\u002FNodeJs\u002Fcore\u002Fpath.md","md",{"items":2076},[2077,2081,2085,2089,2093,2097],{"path":2078,"title":2079,"description":2080,"category":10,"score":259},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Ffs","文件系统","Node.js 的 fs 模块提供了与文件系统交互的 API，几乎涵盖了所有标准文件操作。它支持三种风格的 API：同步、回调式异步 和 Promise 式异步。下面详细介绍这些 API 的选择策略、流式读写、文件监视以及常用操作。",{"path":2082,"title":2083,"description":2084,"category":10,"score":259},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fbuffer","缓冲区","Buffer 是 Node.js 全局对象，用于处理二进制数据流（如文件、网络数据）。在 ES6 引入 TypedArray 之前，Buffer 是 Node.js 处理二进制的主要方式；现在 Buffer 实现了 Uint8Arra…",{"path":2086,"title":2087,"description":2088,"category":10,"score":259},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fprocess","进程与子进程","Node.js 在单个进程中运行，但通过 process 对象、child_process 模块及 worker_threads 模块提供了对进程的精细控制以及多进程\u002F多线程能力。下面从三个方面展开。",{"path":2090,"title":2091,"description":2092,"category":10,"score":259},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fhttp","网络编程","Node.js 提供了丰富的内置模块，用于构建网络应用。下面从 HTTP\u002FHTTPS、WebSocket、TCP\u002FUDP 以及 DNS 解析四个方面进行深入介绍。",{"path":2094,"title":2095,"description":2096,"category":10,"score":259},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fstream","流","流是 Node.js 中处理有序数据的抽象接口，用于以连续方式异步读取或写入数据。它们特别适合处理大文件、网络通信或任何可能无限产生的数据。Node.js 内置的 stream 模块提供了四种基本流类型，以及用于组合和错误处理的工具函数。",{"path":2098,"title":2099,"description":2100,"category":10,"score":259},"\u002Fknowledge\u002Fbooklet\u002Fend\u002Fnodejs\u002Fcore\u002Fother","其他常用模块","以下是 Node.js 中几个重要内置模块的详细介绍，涵盖事件触发器、定时器、加密、压缩、操作系统信息和实用工具。",{"series":2102,"title":2103,"items":2104,"index":247,"prev":2118,"next":2119},"booklet\u002Fend\u002Fnodejs\u002Fcore","core",[2105,2107,2109,2111,2113,2114,2116],{"path":2082,"title":2083,"date":2106,"pinned":15},"2025-01-30",{"path":2078,"title":2079,"date":2108,"pinned":15},"2026-06-04",{"path":2090,"title":2091,"date":2110,"pinned":15},"2023-01-27",{"path":2098,"title":2099,"date":2112,"pinned":15},"2020-03-27",{"path":7,"title":8,"date":14,"pinned":15},{"path":2086,"title":2087,"date":2115,"pinned":15},"2023-11-10",{"path":2094,"title":2095,"date":2117,"pinned":15},"2022-05-03",{"path":2098,"title":2099,"date":2112,"pinned":15},{"path":2086,"title":2087,"date":2115,"pinned":15}]