[{"data":1,"prerenderedAt":4088},["ShallowReactive",2],{"blog-\u002Fblog\u002Fwsl2-setup-guide":3,"blog-siblings-\u002Fblog\u002Fwsl2-setup-guide":4085},{"id":4,"title":5,"body":6,"category":4069,"date":4070,"description":4071,"draft":4072,"extension":4073,"meta":4074,"navigation":686,"path":4075,"seo":4076,"source":4077,"stem":4078,"tags":4079,"__hash__":4084},"blog\u002Fblog\u002Fwsl2-setup-guide.md","WSL2 初始使用与开发环境配置指南",{"type":7,"value":8,"toc":4003},"minimark",[9,14,21,25,93,101,104,112,119,123,170,173,234,237,259,262,296,298,302,306,317,320,352,355,384,388,461,464,542,544,548,554,558,583,608,612,637,650,654,710,722,726,733,893,896,909,919,923,933,958,961,969,972,980,983,1035,1037,1041,1045,1125,1131,1148,1152,1157,1189,1192,1210,1214,1339,1361,1365,1368,1393,1397,1400,1421,1428,1433,1439,1442,1456,1459,1477,1481,1486,1492,1502,1509,1526,1530,1536,1547,1560,1562,1566,1570,1591,1690,1694,1705,1727,1733,1782,1786,1792,1838,1849,1860,1863,1914,1922,1930,1961,1971,1978,1981,2006,2009,2013,2019,2022,2053,2061,2072,2078,2092,2106,2109,2196,2200,2207,2262,2265,2298,2303,2307,2313,2319,2380,2382,2386,2399,2403,2436,2440,2555,2559,2624,2634,2636,2640,2644,2647,2709,2716,2720,2723,2742,2748,2752,2799,2811,2828,2837,2839,2843,3045,3047,3054,3519,3521,3525,3947,3950,3952,3955,3962,3982,3985,3992,3999],[10,11,13],"h1",{"id":12},"wsl2-初始使用与开发环境完整配置指南","WSL2 初始使用与开发环境完整配置指南",[15,16,17],"blockquote",{},[18,19,20],"p",{},"从零开始把一台干净的 Windows 11 + WSL2 Ubuntu 配成趁手的前端\u002F全栈开发环境。本文记录每一步的「为什么」和「怎么做」，包含我自己踩过的所有坑。",[22,23,24],"h2",{"id":24},"环境前置",[26,27,28,41],"table",{},[29,30,31],"thead",{},[32,33,34,38],"tr",{},[35,36,37],"th",{},"项目",[35,39,40],{},"版本\u002F说明",[42,43,44,53,61,69,77,85],"tbody",{},[32,45,46,50],{},[47,48,49],"td",{},"操作系统",[47,51,52],{},"Windows 11 Pro 26200",[32,54,55,58],{},[47,56,57],{},"WSL 版本",[47,59,60],{},"2.7.3.0（内核 6.6.114.1-1）",[32,62,63,66],{},[47,64,65],{},"WSL 发行版",[47,67,68],{},"Ubuntu 24.04",[32,70,71,74],{},[47,72,73],{},"默认 Shell",[47,75,76],{},"Zsh + Oh My Zsh",[32,78,79,82],{},[47,80,81],{},"代理方案",[47,83,84],{},"Mihomo Party（Clash 系列）TUN 模式",[32,86,87,90],{},[47,88,89],{},"网络模式",[47,91,92],{},"NAT",[18,94,95,96,100],{},"WSL 安装本身不在本文范围（一句话：",[97,98,99],"code",{},"wsl --install -d Ubuntu-24.04","）。本文从「Ubuntu 已装好，第一次进系统」开始。",[102,103],"hr",{},[22,105,107,108,111],{"id":106},"一wslconfig-wsl2-全局配置","一、",[97,109,110],{},".wslconfig"," —— WSL2 全局配置",[18,113,114,115,118],{},"文件位置：",[97,116,117],{},"C:\\Users\\\u003C你的用户名>\\.wslconfig","（Windows 端，不在 WSL 里）。",[120,121,122],"h3",{"id":122},"推荐配置",[124,125,130],"pre",{"className":126,"code":127,"language":128,"meta":129,"style":129},"language-ini shiki shiki-themes github-light github-dark","[wsl2]\nnetworkingMode=NAT          # 网络模式：NAT（默认）\nmemory=4GB                  # WSL 可用内存上限（按机器内存的 1\u002F2 ~ 1\u002F4）\nprocessors=4                # CPU 核心数（按物理核数的一半）\nswap=2GB                    # 交换分区\nlocalhostForwarding=true    # 启用 localhost 转发（默认就是 true，显式写保险）\n","ini","",[97,131,132,140,146,152,158,164],{"__ignoreMap":129},[133,134,137],"span",{"class":135,"line":136},"line",1,[133,138,139],{},"[wsl2]\n",[133,141,143],{"class":135,"line":142},2,[133,144,145],{},"networkingMode=NAT          # 网络模式：NAT（默认）\n",[133,147,149],{"class":135,"line":148},3,[133,150,151],{},"memory=4GB                  # WSL 可用内存上限（按机器内存的 1\u002F2 ~ 1\u002F4）\n",[133,153,155],{"class":135,"line":154},4,[133,156,157],{},"processors=4                # CPU 核心数（按物理核数的一半）\n",[133,159,161],{"class":135,"line":160},5,[133,162,163],{},"swap=2GB                    # 交换分区\n",[133,165,167],{"class":135,"line":166},6,[133,168,169],{},"localhostForwarding=true    # 启用 localhost 转发（默认就是 true，显式写保险）\n",[120,171,172],{"id":172},"各项说明",[174,175,176,190,206,222],"ul",{},[177,178,179,185,186,189],"li",{},[180,181,182],"strong",{},[97,183,184],{},"networkingMode=NAT","：WSL 在 Hyper-V 内部 NAT 子网（如 ",[97,187,188],{},"172.20.x.x","），通过 Windows 主机 NAT 出网。这是默认且最稳定的模式。",[177,191,192,201,202,205],{},[180,193,194,197,198],{},[97,195,196],{},"memory"," \u002F ",[97,199,200],{},"processors","：不限制的话 WSL 默认能吃掉一半物理内存。运行大型构建时（webpack、TypeScript）很容易把 Windows 拖到卡死，",[180,203,204],{},"必须显式限制","。",[177,207,208,213,214,217,218,221],{},[180,209,210],{},[97,211,212],{},"localhostForwarding=true","：Windows 主机访问 ",[97,215,216],{},"localhost:port"," 自动转到 WSL。这是单向的，",[180,219,220],{},"不会让局域网其他机器访问 WSL","（这是另一篇文档的话题）。",[177,223,224,230,231,205],{},[180,225,226,227],{},"不要用 ",[97,228,229],{},"networkingMode=mirrored","：理论上是最优雅的方案（WSL 共用 Windows 网络栈），但跟 VMware \u002F Hyper-V \u002F Docker Desktop 多虚拟化环境严重冲突，会报错 ",[97,232,233],{},"0x8007054f",[120,235,236],{"id":236},"让配置生效",[124,238,242],{"className":239,"code":240,"language":241,"meta":129,"style":129},"language-powershell shiki shiki-themes github-light github-dark","wsl --shutdown\n# 等 8 秒确保完全关闭\nwsl\n","powershell",[97,243,244,249,254],{"__ignoreMap":129},[133,245,246],{"class":135,"line":136},[133,247,248],{},"wsl --shutdown\n",[133,250,251],{"class":135,"line":142},[133,252,253],{},"# 等 8 秒确保完全关闭\n",[133,255,256],{"class":135,"line":148},[133,257,258],{},"wsl\n",[120,260,261],{"id":261},"验证",[124,263,267],{"className":264,"code":265,"language":266,"meta":129,"style":129},"language-bash shiki shiki-themes github-light github-dark","# WSL 内\nfree -h       # 看内存上限\nnproc         # 看 CPU 核数\n","bash",[97,268,269,275,288],{"__ignoreMap":129},[133,270,271],{"class":135,"line":136},[133,272,274],{"class":273},"sJ8bj","# WSL 内\n",[133,276,277,281,285],{"class":135,"line":142},[133,278,280],{"class":279},"sScJk","free",[133,282,284],{"class":283},"sj4cs"," -h",[133,286,287],{"class":273},"       # 看内存上限\n",[133,289,290,293],{"class":135,"line":148},[133,291,292],{"class":279},"nproc",[133,294,295],{"class":273},"         # 看 CPU 核数\n",[102,297],{},[22,299,301],{"id":300},"二ubuntu-系统初始化","二、Ubuntu 系统初始化",[120,303,305],{"id":304},"_21-换国内源重要","2.1 换国内源（重要）",[18,307,308,309,312,313,316],{},"Ubuntu 24.04 用了新的 deb822 格式，源文件在 ",[97,310,311],{},"\u002Fetc\u002Fapt\u002Fsources.list.d\u002Fubuntu.sources","（不是老版的 ",[97,314,315],{},"\u002Fetc\u002Fapt\u002Fsources.list","）。",[18,318,319],{},"换清华源：",[124,321,323],{"className":264,"code":322,"language":266,"meta":129,"style":129},"sudo sed -i \\\n  's@\u002F\u002F.*archive.ubuntu.com@\u002F\u002Fmirrors.tuna.tsinghua.edu.cn@g; s@\u002F\u002Fsecurity.ubuntu.com@\u002F\u002Fmirrors.tuna.tsinghua.edu.cn@g' \\\n  \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fubuntu.sources\n",[97,324,325,340,347],{"__ignoreMap":129},[133,326,327,330,334,337],{"class":135,"line":136},[133,328,329],{"class":279},"sudo",[133,331,333],{"class":332},"sZZnC"," sed",[133,335,336],{"class":283}," -i",[133,338,339],{"class":283}," \\\n",[133,341,342,345],{"class":135,"line":142},[133,343,344],{"class":332},"  's@\u002F\u002F.*archive.ubuntu.com@\u002F\u002Fmirrors.tuna.tsinghua.edu.cn@g; s@\u002F\u002Fsecurity.ubuntu.com@\u002F\u002Fmirrors.tuna.tsinghua.edu.cn@g'",[133,346,339],{"class":283},[133,348,349],{"class":135,"line":148},[133,350,351],{"class":332},"  \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fubuntu.sources\n",[18,353,354],{},"更新软件包列表：",[124,356,358],{"className":264,"code":357,"language":266,"meta":129,"style":129},"sudo apt update && sudo apt upgrade -y\n",[97,359,360],{"__ignoreMap":129},[133,361,362,364,367,370,374,376,378,381],{"class":135,"line":136},[133,363,329],{"class":279},[133,365,366],{"class":332}," apt",[133,368,369],{"class":332}," update",[133,371,373],{"class":372},"sVt8B"," && ",[133,375,329],{"class":279},[133,377,366],{"class":332},[133,379,380],{"class":332}," upgrade",[133,382,383],{"class":283}," -y\n",[120,385,387],{"id":386},"_22-安装基础工具链","2.2 安装基础工具链",[124,389,391],{"className":264,"code":390,"language":266,"meta":129,"style":129},"sudo apt install -y \\\n  build-essential \\\n  git curl wget vim \\\n  zsh unzip \\\n  ca-certificates gnupg lsb-release \\\n  net-tools dnsutils\n",[97,392,393,407,414,430,440,453],{"__ignoreMap":129},[133,394,395,397,399,402,405],{"class":135,"line":136},[133,396,329],{"class":279},[133,398,366],{"class":332},[133,400,401],{"class":332}," install",[133,403,404],{"class":283}," -y",[133,406,339],{"class":283},[133,408,409,412],{"class":135,"line":142},[133,410,411],{"class":332},"  build-essential",[133,413,339],{"class":283},[133,415,416,419,422,425,428],{"class":135,"line":148},[133,417,418],{"class":332},"  git",[133,420,421],{"class":332}," curl",[133,423,424],{"class":332}," wget",[133,426,427],{"class":332}," vim",[133,429,339],{"class":283},[133,431,432,435,438],{"class":135,"line":154},[133,433,434],{"class":332},"  zsh",[133,436,437],{"class":332}," unzip",[133,439,339],{"class":283},[133,441,442,445,448,451],{"class":135,"line":160},[133,443,444],{"class":332},"  ca-certificates",[133,446,447],{"class":332}," gnupg",[133,449,450],{"class":332}," lsb-release",[133,452,339],{"class":283},[133,454,455,458],{"class":135,"line":166},[133,456,457],{"class":332},"  net-tools",[133,459,460],{"class":332}," dnsutils\n",[18,462,463],{},"各包用途：",[26,465,466,476],{},[29,467,468],{},[32,469,470,473],{},[35,471,472],{},"包",[35,474,475],{},"作用",[42,477,478,492,502,512,522],{},[32,479,480,485],{},[47,481,482],{},[97,483,484],{},"build-essential",[47,486,487,488,491],{},"gcc\u002Fg++\u002Fmake，",[180,489,490],{},"几乎所有 native 模块编译都需要","（如 sqlite3、bcrypt、node-gyp）",[32,493,494,499],{},[47,495,496],{},[97,497,498],{},"git curl wget",[47,500,501],{},"必备",[32,503,504,509],{},[47,505,506],{},[97,507,508],{},"vim",[47,510,511],{},"命令行编辑器",[32,513,514,519],{},[47,515,516],{},[97,517,518],{},"zsh",[47,520,521],{},"我们要换的 shell",[32,523,524,529],{},[47,525,526],{},[97,527,528],{},"net-tools dnsutils",[47,530,531,534,535,534,538,541],{},[97,532,533],{},"ifconfig","、",[97,536,537],{},"nslookup",[97,539,540],{},"dig"," 等网络诊断工具",[102,543],{},[22,545,547],{"id":546},"三zsh-oh-my-zsh-插件-随机主题","三、Zsh + Oh My Zsh + 插件 + 随机主题",[18,549,550,551,205],{},"为什么换 zsh：tab 补全更智能、插件生态丰富、自动建议、语法高亮。",[180,552,553],{},"写过几天就回不去 bash 了",[120,555,557],{"id":556},"_31-安装-oh-my-zsh","3.1 安装 Oh My Zsh",[124,559,561],{"className":264,"code":560,"language":266,"meta":129,"style":129},"sh -c \"$(curl -fsSL https:\u002F\u002Fgitee.com\u002Fmirrors\u002Foh-my-zsh\u002Fraw\u002Fmaster\u002Ftools\u002Finstall.sh)\"\n",[97,562,563],{"__ignoreMap":129},[133,564,565,568,571,574,577,580],{"class":135,"line":136},[133,566,567],{"class":279},"sh",[133,569,570],{"class":283}," -c",[133,572,573],{"class":332}," \"$(",[133,575,576],{"class":279},"curl",[133,578,579],{"class":283}," -fsSL",[133,581,582],{"class":332}," https:\u002F\u002Fgitee.com\u002Fmirrors\u002Foh-my-zsh\u002Fraw\u002Fmaster\u002Ftools\u002Finstall.sh)\"\n",[15,584,585,588],{},[18,586,587],{},"如果你开了 TUN 代理直连 GitHub 稳定，直接用官方脚本也行：",[124,589,591],{"className":264,"code":590,"language":266,"meta":129,"style":129},"sh -c \"$(curl -fsSL https:\u002F\u002Fraw.githubusercontent.com\u002Fohmyzsh\u002Fohmyzsh\u002Fmaster\u002Ftools\u002Finstall.sh)\"\n",[97,592,593],{"__ignoreMap":129},[133,594,595,597,599,601,603,605],{"class":135,"line":136},[133,596,567],{"class":279},[133,598,570],{"class":283},[133,600,573],{"class":332},[133,602,576],{"class":279},[133,604,579],{"class":283},[133,606,607],{"class":332}," https:\u002F\u002Fraw.githubusercontent.com\u002Fohmyzsh\u002Fohmyzsh\u002Fmaster\u002Ftools\u002Finstall.sh)\"\n",[120,609,611],{"id":610},"_32-设置-zsh-为默认-shell","3.2 设置 Zsh 为默认 Shell",[124,613,615],{"className":264,"code":614,"language":266,"meta":129,"style":129},"chsh -s $(which zsh)\n",[97,616,617],{"__ignoreMap":129},[133,618,619,622,625,628,631,634],{"class":135,"line":136},[133,620,621],{"class":279},"chsh",[133,623,624],{"class":283}," -s",[133,626,627],{"class":372}," $(",[133,629,630],{"class":283},"which",[133,632,633],{"class":332}," zsh",[133,635,636],{"class":372},")\n",[18,638,639,642,643,645,646,649],{},[180,640,641],{},"重要","：",[97,644,621],{}," 改的是登录 shell，",[180,647,648],{},"需要退出 WSL 重新进","才能生效（或者直接关闭再打开 WSL 终端窗口）。",[120,651,653],{"id":652},"_33-安装两个必备插件","3.3 安装两个必备插件",[124,655,657],{"className":264,"code":656,"language":266,"meta":129,"style":129},"# 自动建议（敲一半命令时显示历史里的灰色补全）\ngit clone https:\u002F\u002Fgithub.com\u002Fzsh-users\u002Fzsh-autosuggestions \\\n  ~\u002F.oh-my-zsh\u002Fcustom\u002Fplugins\u002Fzsh-autosuggestions\n\n# 语法高亮（命令存在=绿色，不存在=红色）\ngit clone https:\u002F\u002Fgithub.com\u002Fzsh-users\u002Fzsh-syntax-highlighting \\\n  ~\u002F.oh-my-zsh\u002Fcustom\u002Fplugins\u002Fzsh-syntax-highlighting\n",[97,658,659,664,677,682,688,693,704],{"__ignoreMap":129},[133,660,661],{"class":135,"line":136},[133,662,663],{"class":273},"# 自动建议（敲一半命令时显示历史里的灰色补全）\n",[133,665,666,669,672,675],{"class":135,"line":142},[133,667,668],{"class":279},"git",[133,670,671],{"class":332}," clone",[133,673,674],{"class":332}," https:\u002F\u002Fgithub.com\u002Fzsh-users\u002Fzsh-autosuggestions",[133,676,339],{"class":283},[133,678,679],{"class":135,"line":148},[133,680,681],{"class":332},"  ~\u002F.oh-my-zsh\u002Fcustom\u002Fplugins\u002Fzsh-autosuggestions\n",[133,683,684],{"class":135,"line":154},[133,685,687],{"emptyLinePlaceholder":686},true,"\n",[133,689,690],{"class":135,"line":160},[133,691,692],{"class":273},"# 语法高亮（命令存在=绿色，不存在=红色）\n",[133,694,695,697,699,702],{"class":135,"line":166},[133,696,668],{"class":279},[133,698,671],{"class":332},[133,700,701],{"class":332}," https:\u002F\u002Fgithub.com\u002Fzsh-users\u002Fzsh-syntax-highlighting",[133,703,339],{"class":283},[133,705,707],{"class":135,"line":706},7,[133,708,709],{"class":332},"  ~\u002F.oh-my-zsh\u002Fcustom\u002Fplugins\u002Fzsh-syntax-highlighting\n",[15,711,712],{},[18,713,714,715,718,719,316],{},"⚠️ 我最开始踩的坑：用了一个不存在的 gitee 镜像 URL（",[97,716,717],{},"gitee.com\u002Fplayjokes\u002F...","），404。要么用 GitHub 原版（开代理直连），要么去 gitee 搜真实可用的镜像（如 ",[97,720,721],{},"gitee.com\u002Fmirrors\u002Fzsh-autosuggestions",[120,723,725],{"id":724},"_34-启用插件-随机主题","3.4 启用插件 + 随机主题",[18,727,728,729,732],{},"编辑 ",[97,730,731],{},"~\u002F.zshrc","，修改两处：",[124,734,736],{"className":264,"code":735,"language":266,"meta":129,"style":129},"# 主题：用随机\nZSH_THEME=\"random\"\n\n# 候选池：避开需要 Nerd Font 字体的主题（agnoster、bira 等会乱码）\nZSH_THEME_RANDOM_CANDIDATES=(\n  \"robbyrussell\"\n  \"ys\"\n  \"bureau\"\n  \"candy\"\n  \"clean\"\n  \"fishy\"\n  \"gnzh\"\n  \"jonathan\"\n  \"kolo\"\n  \"mh\"\n  \"muse\"\n  \"sorin\"\n  \"fox\"\n  \"kphoen\"\n)\n\n# 插件\nplugins=(git zsh-autosuggestions zsh-syntax-highlighting)\n",[97,737,738,743,755,759,764,774,779,784,790,796,802,808,814,820,826,832,838,844,850,856,861,866,872],{"__ignoreMap":129},[133,739,740],{"class":135,"line":136},[133,741,742],{"class":273},"# 主题：用随机\n",[133,744,745,748,752],{"class":135,"line":142},[133,746,747],{"class":372},"ZSH_THEME",[133,749,751],{"class":750},"szBVR","=",[133,753,754],{"class":332},"\"random\"\n",[133,756,757],{"class":135,"line":148},[133,758,687],{"emptyLinePlaceholder":686},[133,760,761],{"class":135,"line":154},[133,762,763],{"class":273},"# 候选池：避开需要 Nerd Font 字体的主题（agnoster、bira 等会乱码）\n",[133,765,766,769,771],{"class":135,"line":160},[133,767,768],{"class":372},"ZSH_THEME_RANDOM_CANDIDATES",[133,770,751],{"class":750},[133,772,773],{"class":372},"(\n",[133,775,776],{"class":135,"line":166},[133,777,778],{"class":332},"  \"robbyrussell\"\n",[133,780,781],{"class":135,"line":706},[133,782,783],{"class":332},"  \"ys\"\n",[133,785,787],{"class":135,"line":786},8,[133,788,789],{"class":332},"  \"bureau\"\n",[133,791,793],{"class":135,"line":792},9,[133,794,795],{"class":332},"  \"candy\"\n",[133,797,799],{"class":135,"line":798},10,[133,800,801],{"class":332},"  \"clean\"\n",[133,803,805],{"class":135,"line":804},11,[133,806,807],{"class":332},"  \"fishy\"\n",[133,809,811],{"class":135,"line":810},12,[133,812,813],{"class":332},"  \"gnzh\"\n",[133,815,817],{"class":135,"line":816},13,[133,818,819],{"class":332},"  \"jonathan\"\n",[133,821,823],{"class":135,"line":822},14,[133,824,825],{"class":332},"  \"kolo\"\n",[133,827,829],{"class":135,"line":828},15,[133,830,831],{"class":332},"  \"mh\"\n",[133,833,835],{"class":135,"line":834},16,[133,836,837],{"class":332},"  \"muse\"\n",[133,839,841],{"class":135,"line":840},17,[133,842,843],{"class":332},"  \"sorin\"\n",[133,845,847],{"class":135,"line":846},18,[133,848,849],{"class":332},"  \"fox\"\n",[133,851,853],{"class":135,"line":852},19,[133,854,855],{"class":332},"  \"kphoen\"\n",[133,857,859],{"class":135,"line":858},20,[133,860,636],{"class":372},[133,862,864],{"class":135,"line":863},21,[133,865,687],{"emptyLinePlaceholder":686},[133,867,869],{"class":135,"line":868},22,[133,870,871],{"class":273},"# 插件\n",[133,873,875,878,880,883,885,888,891],{"class":135,"line":874},23,[133,876,877],{"class":372},"plugins",[133,879,751],{"class":750},[133,881,882],{"class":372},"(",[133,884,668],{"class":332},[133,886,887],{"class":332}," zsh-autosuggestions",[133,889,890],{"class":332}," zsh-syntax-highlighting",[133,892,636],{"class":372},[18,894,895],{},"应用：",[124,897,899],{"className":264,"code":898,"language":266,"meta":129,"style":129},"exec zsh\n",[97,900,901],{"__ignoreMap":129},[133,902,903,906],{"class":135,"line":136},[133,904,905],{"class":283},"exec",[133,907,908],{"class":332}," zsh\n",[18,910,911,912,915,916,205],{},"每次开新终端随机切主题，",[180,913,914],{},"用一段时间就能挑出自己最爱的那个","。看当前用的是哪个：",[97,917,918],{},"echo $RANDOM_THEME",[120,920,922],{"id":921},"_35-想用酷炫主题可选","3.5 想用酷炫主题（可选）",[18,924,925,926,534,929,932],{},"如果想用 ",[97,927,928],{},"agnoster",[97,930,931],{},"powerlevel10k"," 这类带图标、Git 状态、电池显示的主题，需要：",[934,935,936,946,955],"ol",{},[177,937,938,939,534,942,945],{},"Windows Terminal 设置一款 Nerd Font 字体（如 ",[97,940,941],{},"MesloLGS NF",[97,943,944],{},"FiraCode Nerd Font","）",[177,947,948,949],{},"下载：",[950,951,952],"a",{"href":952,"rel":953},"https:\u002F\u002Fwww.nerdfonts.com\u002Ffont-downloads",[954],"nofollow",[177,956,957],{},"Windows Terminal → 设置 → Ubuntu profile → 外观 → 字体改成 Nerd Font",[18,959,960],{},"不急的话先用纯 ASCII 主题就够。",[120,962,964,965,968],{"id":963},"_36-常见踩坑compinit-报错","3.6 常见踩坑：",[97,966,967],{},"compinit"," 报错",[18,970,971],{},"如果你装过 Docker Desktop 然后又卸了（或 Docker Desktop 的 WSL Integration 在装），开终端时可能看到：",[124,973,978],{"className":974,"code":976,"language":977},[975],"language-text","compinit:527: no such file or directory: \u002Fusr\u002Fshare\u002Fzsh\u002Fvendor-completions\u002F_docker\n","text",[97,979,976],{"__ignoreMap":129},[18,981,982],{},"这是 Docker Desktop 残留的死链。修复：",[124,984,986],{"className":264,"code":985,"language":266,"meta":129,"style":129},"ls -la \u002Fusr\u002Fshare\u002Fzsh\u002Fvendor-completions\u002F_docker\n# 如果是个 -> 指向已不存在的路径，确认后删掉\nsudo rm -f \u002Fusr\u002Fshare\u002Fzsh\u002Fvendor-completions\u002F_docker\nrm -f ~\u002F.zcompdump*\nexec zsh\n",[97,987,988,999,1004,1016,1029],{"__ignoreMap":129},[133,989,990,993,996],{"class":135,"line":136},[133,991,992],{"class":279},"ls",[133,994,995],{"class":283}," -la",[133,997,998],{"class":332}," \u002Fusr\u002Fshare\u002Fzsh\u002Fvendor-completions\u002F_docker\n",[133,1000,1001],{"class":135,"line":142},[133,1002,1003],{"class":273},"# 如果是个 -> 指向已不存在的路径，确认后删掉\n",[133,1005,1006,1008,1011,1014],{"class":135,"line":148},[133,1007,329],{"class":279},[133,1009,1010],{"class":332}," rm",[133,1012,1013],{"class":283}," -f",[133,1015,998],{"class":332},[133,1017,1018,1021,1023,1026],{"class":135,"line":154},[133,1019,1020],{"class":279},"rm",[133,1022,1013],{"class":283},[133,1024,1025],{"class":332}," ~\u002F.zcompdump",[133,1027,1028],{"class":283},"*\n",[133,1030,1031,1033],{"class":135,"line":160},[133,1032,905],{"class":283},[133,1034,908],{"class":332},[102,1036],{},[22,1038,1040],{"id":1039},"四git-配置","四、Git 配置",[120,1042,1044],{"id":1043},"_41-全局基础配置","4.1 全局基础配置",[124,1046,1048],{"className":264,"code":1047,"language":266,"meta":129,"style":129},"git config --global user.name \"你的名字\"\ngit config --global user.email \"你的邮箱\"\ngit config --global init.defaultBranch main\ngit config --global core.autocrlf input    # 重要：避免换行符跨平台问题\ngit config --global pull.rebase false\n",[97,1049,1050,1066,1080,1094,1111],{"__ignoreMap":129},[133,1051,1052,1054,1057,1060,1063],{"class":135,"line":136},[133,1053,668],{"class":279},[133,1055,1056],{"class":332}," config",[133,1058,1059],{"class":283}," --global",[133,1061,1062],{"class":332}," user.name",[133,1064,1065],{"class":332}," \"你的名字\"\n",[133,1067,1068,1070,1072,1074,1077],{"class":135,"line":142},[133,1069,668],{"class":279},[133,1071,1056],{"class":332},[133,1073,1059],{"class":283},[133,1075,1076],{"class":332}," user.email",[133,1078,1079],{"class":332}," \"你的邮箱\"\n",[133,1081,1082,1084,1086,1088,1091],{"class":135,"line":148},[133,1083,668],{"class":279},[133,1085,1056],{"class":332},[133,1087,1059],{"class":283},[133,1089,1090],{"class":332}," init.defaultBranch",[133,1092,1093],{"class":332}," main\n",[133,1095,1096,1098,1100,1102,1105,1108],{"class":135,"line":154},[133,1097,668],{"class":279},[133,1099,1056],{"class":332},[133,1101,1059],{"class":283},[133,1103,1104],{"class":332}," core.autocrlf",[133,1106,1107],{"class":332}," input",[133,1109,1110],{"class":273},"    # 重要：避免换行符跨平台问题\n",[133,1112,1113,1115,1117,1119,1122],{"class":135,"line":160},[133,1114,668],{"class":279},[133,1116,1056],{"class":332},[133,1118,1059],{"class":283},[133,1120,1121],{"class":332}," pull.rebase",[133,1123,1124],{"class":283}," false\n",[18,1126,1127,1130],{},[97,1128,1129],{},"core.autocrlf input"," 解释：",[174,1132,1133,1136,1139],{},[177,1134,1135],{},"WSL 是 Linux，提交时用 LF",[177,1137,1138],{},"Windows 上签出别人的代码会自动转 CRLF",[177,1140,1141,1144,1145,205],{},[97,1142,1143],{},"input"," 模式：提交时 CRLF → LF，签出时不转换。",[180,1146,1147],{},"最适合跨平台团队",[120,1149,1151],{"id":1150},"_42-ssh-key-配置","4.2 SSH key 配置",[1153,1154,1156],"h4",{"id":1155},"方案-awsl-内独立生成推荐最干净","方案 A：WSL 内独立生成（推荐，最干净）",[124,1158,1160],{"className":264,"code":1159,"language":266,"meta":129,"style":129},"ssh-keygen -t ed25519 -C \"your-email@example.com\"\n# 一路回车，默认存到 ~\u002F.ssh\u002Fid_ed25519\n# passphrase 可以留空（个人开发机）\n",[97,1161,1162,1179,1184],{"__ignoreMap":129},[133,1163,1164,1167,1170,1173,1176],{"class":135,"line":136},[133,1165,1166],{"class":279},"ssh-keygen",[133,1168,1169],{"class":283}," -t",[133,1171,1172],{"class":332}," ed25519",[133,1174,1175],{"class":283}," -C",[133,1177,1178],{"class":332}," \"your-email@example.com\"\n",[133,1180,1181],{"class":135,"line":142},[133,1182,1183],{"class":273},"# 一路回车，默认存到 ~\u002F.ssh\u002Fid_ed25519\n",[133,1185,1186],{"class":135,"line":148},[133,1187,1188],{"class":273},"# passphrase 可以留空（个人开发机）\n",[18,1190,1191],{},"把公钥贴到 GitHub：",[124,1193,1195],{"className":264,"code":1194,"language":266,"meta":129,"style":129},"cat ~\u002F.ssh\u002Fid_ed25519.pub\n# 复制输出 → https:\u002F\u002Fgithub.com\u002Fsettings\u002Fssh\u002Fnew\n",[97,1196,1197,1205],{"__ignoreMap":129},[133,1198,1199,1202],{"class":135,"line":136},[133,1200,1201],{"class":279},"cat",[133,1203,1204],{"class":332}," ~\u002F.ssh\u002Fid_ed25519.pub\n",[133,1206,1207],{"class":135,"line":142},[133,1208,1209],{"class":273},"# 复制输出 → https:\u002F\u002Fgithub.com\u002Fsettings\u002Fssh\u002Fnew\n",[1153,1211,1213],{"id":1212},"方案-b复用-windows-已有的-ssh-key","方案 B：复用 Windows 已有的 SSH key",[124,1215,1217],{"className":264,"code":1216,"language":266,"meta":129,"style":129},"mkdir -p ~\u002F.ssh\ncp \u002Fmnt\u002Fc\u002FUsers\u002F\u003C你的用户名>\u002F.ssh\u002Fid_ed25519 ~\u002F.ssh\u002F\ncp \u002Fmnt\u002Fc\u002FUsers\u002F\u003C你的用户名>\u002F.ssh\u002Fid_ed25519.pub ~\u002F.ssh\u002F\ncp \u002Fmnt\u002Fc\u002FUsers\u002F\u003C你的用户名>\u002F.ssh\u002Fknown_hosts ~\u002F.ssh\u002F 2>\u002Fdev\u002Fnull\n\n# 关键：权限必须严格\nchmod 700 ~\u002F.ssh\nchmod 600 ~\u002F.ssh\u002Fid_ed25519\nchmod 644 ~\u002F.ssh\u002Fid_ed25519.pub\n",[97,1218,1219,1230,1256,1275,1301,1305,1310,1320,1330],{"__ignoreMap":129},[133,1220,1221,1224,1227],{"class":135,"line":136},[133,1222,1223],{"class":279},"mkdir",[133,1225,1226],{"class":283}," -p",[133,1228,1229],{"class":332}," ~\u002F.ssh\n",[133,1231,1232,1235,1238,1241,1244,1247,1250,1253],{"class":135,"line":142},[133,1233,1234],{"class":279},"cp",[133,1236,1237],{"class":332}," \u002Fmnt\u002Fc\u002FUsers\u002F",[133,1239,1240],{"class":750},"\u003C",[133,1242,1243],{"class":332},"你的用户",[133,1245,1246],{"class":372},"名",[133,1248,1249],{"class":750},">",[133,1251,1252],{"class":332},"\u002F.ssh\u002Fid_ed25519",[133,1254,1255],{"class":332}," ~\u002F.ssh\u002F\n",[133,1257,1258,1260,1262,1264,1266,1268,1270,1273],{"class":135,"line":148},[133,1259,1234],{"class":279},[133,1261,1237],{"class":332},[133,1263,1240],{"class":750},[133,1265,1243],{"class":332},[133,1267,1246],{"class":372},[133,1269,1249],{"class":750},[133,1271,1272],{"class":332},"\u002F.ssh\u002Fid_ed25519.pub",[133,1274,1255],{"class":332},[133,1276,1277,1279,1281,1283,1285,1287,1289,1292,1295,1298],{"class":135,"line":154},[133,1278,1234],{"class":279},[133,1280,1237],{"class":332},[133,1282,1240],{"class":750},[133,1284,1243],{"class":332},[133,1286,1246],{"class":372},[133,1288,1249],{"class":750},[133,1290,1291],{"class":332},"\u002F.ssh\u002Fknown_hosts",[133,1293,1294],{"class":332}," ~\u002F.ssh\u002F",[133,1296,1297],{"class":750}," 2>",[133,1299,1300],{"class":332},"\u002Fdev\u002Fnull\n",[133,1302,1303],{"class":135,"line":160},[133,1304,687],{"emptyLinePlaceholder":686},[133,1306,1307],{"class":135,"line":166},[133,1308,1309],{"class":273},"# 关键：权限必须严格\n",[133,1311,1312,1315,1318],{"class":135,"line":706},[133,1313,1314],{"class":279},"chmod",[133,1316,1317],{"class":283}," 700",[133,1319,1229],{"class":332},[133,1321,1322,1324,1327],{"class":135,"line":786},[133,1323,1314],{"class":279},[133,1325,1326],{"class":283}," 600",[133,1328,1329],{"class":332}," ~\u002F.ssh\u002Fid_ed25519\n",[133,1331,1332,1334,1337],{"class":135,"line":792},[133,1333,1314],{"class":279},[133,1335,1336],{"class":283}," 644",[133,1338,1204],{"class":332},[15,1340,1341],{},[18,1342,1343,1344,1350,1351,1354,1357,1358,205],{},"⚠️ ",[180,1345,1346,1347],{},"不要用软链 ",[97,1348,1349],{},"ln -s \u002Fmnt\u002Fc\u002F...","！",[1352,1353],"br",{},[97,1355,1356],{},"\u002Fmnt\u002Fc"," 是 9P 文件系统挂载，不支持 Linux 权限模型，SSH 看到 .ssh 是 777 会拒绝使用私钥（\"Permissions are too open\"）。",[180,1359,1360],{},"必须复制",[1153,1362,1364],{"id":1363},"方案-c用旧版-rsa-key兼容老内部仓库","方案 C：用旧版 RSA key（兼容老内部仓库）",[18,1366,1367],{},"如果公司老仓库只认 RSA：",[124,1369,1371],{"className":264,"code":1370,"language":266,"meta":129,"style":129},"ssh-keygen -t rsa -b 4096 -C \"your-email\"\n",[97,1372,1373],{"__ignoreMap":129},[133,1374,1375,1377,1379,1382,1385,1388,1390],{"class":135,"line":136},[133,1376,1166],{"class":279},[133,1378,1169],{"class":283},[133,1380,1381],{"class":332}," rsa",[133,1383,1384],{"class":283}," -b",[133,1386,1387],{"class":283}," 4096",[133,1389,1175],{"class":283},[133,1391,1392],{"class":332}," \"your-email\"\n",[120,1394,1396],{"id":1395},"_43-github-ssh-连接-22-端口失败-走-443","4.3 GitHub SSH 连接 22 端口失败 → 走 443",[18,1398,1399],{},"国内 ISP 偶尔对 GitHub 的 22 端口做干扰。症状：",[124,1401,1403],{"className":264,"code":1402,"language":266,"meta":129,"style":129},"ssh -T git@github.com\n# Connection closed by 20.205.243.166 port 22\n",[97,1404,1405,1416],{"__ignoreMap":129},[133,1406,1407,1410,1413],{"class":135,"line":136},[133,1408,1409],{"class":279},"ssh",[133,1411,1412],{"class":283}," -T",[133,1414,1415],{"class":332}," git@github.com\n",[133,1417,1418],{"class":135,"line":142},[133,1419,1420],{"class":273},"# Connection closed by 20.205.243.166 port 22\n",[18,1422,1423,1424,1427],{},"解决：让 SSH 走 GitHub 官方提供的 443 端口入口（",[97,1425,1426],{},"ssh.github.com:443","，伪装成 HTTPS）。",[18,1429,728,1430,642],{},[97,1431,1432],{},"~\u002F.ssh\u002Fconfig",[124,1434,1437],{"className":1435,"code":1436,"language":977},[975],"Host github.com\n    Hostname ssh.github.com\n    Port 443\n    User git\n    IdentityFile ~\u002F.ssh\u002Fid_ed25519\n    IdentitiesOnly yes\n",[97,1438,1436],{"__ignoreMap":129},[18,1440,1441],{},"权限：",[124,1443,1445],{"className":264,"code":1444,"language":266,"meta":129,"style":129},"chmod 600 ~\u002F.ssh\u002Fconfig\n",[97,1446,1447],{"__ignoreMap":129},[133,1448,1449,1451,1453],{"class":135,"line":136},[133,1450,1314],{"class":279},[133,1452,1326],{"class":283},[133,1454,1455],{"class":332}," ~\u002F.ssh\u002Fconfig\n",[18,1457,1458],{},"测试：",[124,1460,1462],{"className":264,"code":1461,"language":266,"meta":129,"style":129},"ssh -T git@github.com\n# Hi \u003C你的用户名>! You've successfully authenticated...\n",[97,1463,1464,1472],{"__ignoreMap":129},[133,1465,1466,1468,1470],{"class":135,"line":136},[133,1467,1409],{"class":279},[133,1469,1412],{"class":283},[133,1471,1415],{"class":332},[133,1473,1474],{"class":135,"line":142},[133,1475,1476],{"class":273},"# Hi \u003C你的用户名>! You've successfully authenticated...\n",[120,1478,1480],{"id":1479},"_44-多-key-场景内部仓库-rsa-github-ed25519","4.4 多 Key 场景：内部仓库 RSA + GitHub Ed25519",[18,1482,1483,1484,642],{},"公司老仓库要 RSA、GitHub 用 Ed25519 是典型组合。完整 ",[97,1485,1432],{},[124,1487,1490],{"className":1488,"code":1489,"language":977},[975],"# GitHub 走 443 + Ed25519\nHost github.com\n    Hostname ssh.github.com\n    Port 443\n    User git\n    IdentityFile ~\u002F.ssh\u002Fid_ed25519\n    IdentitiesOnly yes\n\n# 公司内部仓库走 22 + RSA\nHost company\n    Hostname 192.168.1.201\n    Port 8022\n    User git\n    IdentityFile ~\u002F.ssh\u002Fid_rsa\n    IdentitiesOnly yes\n\n# Gitee\nHost gitee.com\n    Hostname gitee.com\n    Port 22\n    User git\n    IdentityFile ~\u002F.ssh\u002Fid_ed25519\n    IdentitiesOnly yes\n",[97,1491,1489],{"__ignoreMap":129},[18,1493,1494,1497,1498,1501],{},[97,1495,1496],{},"IdentitiesOnly yes"," ",[180,1499,1500],{},"必加","，否则 SSH 会按 agent 里所有 key 轮询尝试，触发 GitHub \"Too many authentication failures\" 拒绝。",[18,1503,1504,1505,1508],{},"之后 ",[97,1506,1507],{},"git clone"," 可以用别名：",[124,1510,1512],{"className":264,"code":1511,"language":266,"meta":129,"style":129},"git clone company:group\u002Frepo.git   # 等价于 git@192.168.1.201:group\u002Frepo.git，端口 8022\n",[97,1513,1514],{"__ignoreMap":129},[133,1515,1516,1518,1520,1523],{"class":135,"line":136},[133,1517,668],{"class":279},[133,1519,671],{"class":332},[133,1521,1522],{"class":332}," company:group\u002Frepo.git",[133,1524,1525],{"class":273},"   # 等价于 git@192.168.1.201:group\u002Frepo.git，端口 8022\n",[120,1527,1529],{"id":1528},"_45-ssh-首次连接的-authenticity-提示","4.5 SSH 首次连接的 \"authenticity\" 提示",[124,1531,1534],{"className":1532,"code":1533,"language":977},[975],"The authenticity of host '[ssh.github.com]:443 ...' can't be established.\nED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF\u002FzLDA0zPMSvHdkr4UvCOqU.\nAre you sure you want to continue connecting (yes\u002Fno)?\n",[97,1535,1533],{"__ignoreMap":129},[18,1537,1538,1539,1542,1543,1546],{},"这是 SSH 的 TOFU（Trust On First Use）机制，所有新主机第一次连都会问。回答 ",[97,1540,1541],{},"yes","，host key 会存到 ",[97,1544,1545],{},"~\u002F.ssh\u002Fknown_hosts","，下次不再问。",[18,1548,1549,1550,1555,1556,1559],{},"如果未来看到 ",[180,1551,1552],{},[97,1553,1554],{},"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!"," 这种感叹号警告，",[180,1557,1558],{},"那才是真问题","（服务器 key 变了，可能被替换或中间人攻击）。",[102,1561],{},[22,1563,1565],{"id":1564},"五nodejs-nvm-配置","五、Node.js \u002F nvm 配置",[120,1567,1569],{"id":1568},"_51-安装-nvm","5.1 安装 nvm",[124,1571,1573],{"className":264,"code":1572,"language":266,"meta":129,"style":129},"curl -o- https:\u002F\u002Fgitee.com\u002Fmirrors\u002Fnvm\u002Fraw\u002Fmaster\u002Finstall.sh | bash\n",[97,1574,1575],{"__ignoreMap":129},[133,1576,1577,1579,1582,1585,1588],{"class":135,"line":136},[133,1578,576],{"class":279},[133,1580,1581],{"class":283}," -o-",[133,1583,1584],{"class":332}," https:\u002F\u002Fgitee.com\u002Fmirrors\u002Fnvm\u002Fraw\u002Fmaster\u002Finstall.sh",[133,1586,1587],{"class":750}," |",[133,1589,1590],{"class":279}," bash\n",[15,1592,1593,1612],{},[18,1594,1595,1596,1598,1600,1601,1603,1605,1608,1609,1611],{},"用 zsh 之前装：自动写入 ",[97,1597,731],{},[1352,1599],{},"\n用 zsh 之后装：也会自动写入 ",[97,1602,731],{},[1352,1604],{},[180,1606,1607],{},"检查方法","：看 ",[97,1610,731],{}," 末尾有没有：",[124,1613,1615],{"className":264,"code":1614,"language":266,"meta":129,"style":129},"export NVM_DIR=\"$HOME\u002F.nvm\"\n[ -s \"$NVM_DIR\u002Fnvm.sh\" ] && \\. \"$NVM_DIR\u002Fnvm.sh\"\n[ -s \"$NVM_DIR\u002Fbash_completion\" ] && \\. \"$NVM_DIR\u002Fbash_completion\"\n",[97,1616,1617,1636,1666],{"__ignoreMap":129},[133,1618,1619,1622,1625,1627,1630,1633],{"class":135,"line":136},[133,1620,1621],{"class":750},"export",[133,1623,1624],{"class":372}," NVM_DIR",[133,1626,751],{"class":750},[133,1628,1629],{"class":332},"\"",[133,1631,1632],{"class":372},"$HOME",[133,1634,1635],{"class":332},"\u002F.nvm\"\n",[133,1637,1638,1641,1644,1647,1650,1653,1656,1659,1661,1663],{"class":135,"line":142},[133,1639,1640],{"class":372},"[ ",[133,1642,1643],{"class":750},"-s",[133,1645,1646],{"class":332}," \"",[133,1648,1649],{"class":372},"$NVM_DIR",[133,1651,1652],{"class":332},"\u002Fnvm.sh\"",[133,1654,1655],{"class":372}," ] && ",[133,1657,1658],{"class":279},"\\.",[133,1660,1646],{"class":332},[133,1662,1649],{"class":372},[133,1664,1665],{"class":332},"\u002Fnvm.sh\"\n",[133,1667,1668,1670,1672,1674,1676,1679,1681,1683,1685,1687],{"class":135,"line":148},[133,1669,1640],{"class":372},[133,1671,1643],{"class":750},[133,1673,1646],{"class":332},[133,1675,1649],{"class":372},[133,1677,1678],{"class":332},"\u002Fbash_completion\"",[133,1680,1655],{"class":372},[133,1682,1658],{"class":279},[133,1684,1646],{"class":332},[133,1686,1649],{"class":372},[133,1688,1689],{"class":332},"\u002Fbash_completion\"\n",[120,1691,1693],{"id":1692},"_52-关键配-nvm-下载源","5.2 关键：配 nvm 下载源",[18,1695,1696,1697,1700,1701,1704],{},"nvm 装 Node 时从 ",[97,1698,1699],{},"nodejs.org"," 下载二进制，",[180,1702,1703],{},"国内访问极不稳定","，即使开了代理也常超时。改用淘宝镜像：",[124,1706,1708],{"className":264,"code":1707,"language":266,"meta":129,"style":129},"# 写入 ~\u002F.zshrc\nexport NVM_NODEJS_ORG_MIRROR=https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\n",[97,1709,1710,1715],{"__ignoreMap":129},[133,1711,1712],{"class":135,"line":136},[133,1713,1714],{"class":273},"# 写入 ~\u002F.zshrc\n",[133,1716,1717,1719,1722,1724],{"class":135,"line":142},[133,1718,1621],{"class":750},[133,1720,1721],{"class":372}," NVM_NODEJS_ORG_MIRROR",[133,1723,751],{"class":750},[133,1725,1726],{"class":372},"https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\n",[18,1728,1729,1732],{},[97,1730,1731],{},"source ~\u002F.zshrc"," 后再装：",[124,1734,1736],{"className":264,"code":1735,"language":266,"meta":129,"style":129},"nvm install 18.20.8\nnvm install --lts\nnvm alias default lts\u002F*\nnvm use default\n",[97,1737,1738,1748,1757,1772],{"__ignoreMap":129},[133,1739,1740,1743,1745],{"class":135,"line":136},[133,1741,1742],{"class":279},"nvm",[133,1744,401],{"class":332},[133,1746,1747],{"class":283}," 18.20.8\n",[133,1749,1750,1752,1754],{"class":135,"line":142},[133,1751,1742],{"class":279},[133,1753,401],{"class":332},[133,1755,1756],{"class":283}," --lts\n",[133,1758,1759,1761,1764,1767,1770],{"class":135,"line":148},[133,1760,1742],{"class":279},[133,1762,1763],{"class":332}," alias",[133,1765,1766],{"class":332}," default",[133,1768,1769],{"class":332}," lts\u002F",[133,1771,1028],{"class":283},[133,1773,1774,1776,1779],{"class":135,"line":154},[133,1775,1742],{"class":279},[133,1777,1778],{"class":332}," use",[133,1780,1781],{"class":332}," default\n",[120,1783,1785],{"id":1784},"_53-npm-镜像-不一定需要改","5.3 npm 镜像 —— 不一定需要改",[18,1787,1788,1791],{},[180,1789,1790],{},"关键认知","：nvm 下载源 ≠ npm registry。",[26,1793,1794,1807],{},[29,1795,1796],{},[32,1797,1798,1801,1804],{},[35,1799,1800],{},"工具",[35,1802,1803],{},"下载位置",[35,1805,1806],{},"是否要改",[42,1808,1809,1825],{},[32,1810,1811,1815,1818],{},[47,1812,1813],{},[180,1814,1742],{},[47,1816,1817],{},"nodejs.org 下 node 二进制",[47,1819,1820,1821,1824],{},"✅ ",[180,1822,1823],{},"要改","（国内极慢）",[32,1826,1827,1832,1835],{},[47,1828,1829],{},[180,1830,1831],{},"npm",[47,1833,1834],{},"registry.npmjs.org 下包",[47,1836,1837],{},"❌ 不一定改",[18,1839,1840,1841,1844,1845,1848],{},"如果你开了 TUN 代理，",[180,1842,1843],{},"npm 直连 npmjs.org 就走代理了","，速度完全 OK，",[180,1846,1847],{},"不必改 registry","。改成淘宝镜像反而：",[174,1850,1851,1854,1857],{},[177,1852,1853],{},"套娃延迟（代理 → 阿里云镜像）",[177,1855,1856],{},"私有包丢失（公司私库的包淘宝没同步）",[177,1858,1859],{},"关代理后不一定更快",[18,1861,1862],{},"如果确实要改：",[124,1864,1866],{"className":264,"code":1865,"language":266,"meta":129,"style":129},"npm config set registry https:\u002F\u002Fregistry.npmmirror.com    # 改\nnpm config delete registry                                # 还原\nnpm config get registry                                   # 查\n",[97,1867,1868,1886,1900],{"__ignoreMap":129},[133,1869,1870,1872,1874,1877,1880,1883],{"class":135,"line":136},[133,1871,1831],{"class":279},[133,1873,1056],{"class":332},[133,1875,1876],{"class":332}," set",[133,1878,1879],{"class":332}," registry",[133,1881,1882],{"class":332}," https:\u002F\u002Fregistry.npmmirror.com",[133,1884,1885],{"class":273},"    # 改\n",[133,1887,1888,1890,1892,1895,1897],{"class":135,"line":142},[133,1889,1831],{"class":279},[133,1891,1056],{"class":332},[133,1893,1894],{"class":332}," delete",[133,1896,1879],{"class":332},[133,1898,1899],{"class":273},"                                # 还原\n",[133,1901,1902,1904,1906,1909,1911],{"class":135,"line":148},[133,1903,1831],{"class":279},[133,1905,1056],{"class":332},[133,1907,1908],{"class":332}," get",[133,1910,1879],{"class":332},[133,1912,1913],{"class":273},"                                   # 查\n",[120,1915,1917,1918,1921],{"id":1916},"_54-npmrc-配置最佳实践","5.4 ",[97,1919,1920],{},".npmrc"," 配置最佳实践",[1153,1923,1925,1926,1929],{"id":1924},"用户级-npmrc一次配全局生效","用户级 ",[97,1927,1928],{},"~\u002F.npmrc","（一次配，全局生效）",[124,1931,1933],{"className":264,"code":1932,"language":266,"meta":129,"style":129},"npm config set audit false\nnpm config set fund false\n",[97,1934,1935,1948],{"__ignoreMap":129},[133,1936,1937,1939,1941,1943,1946],{"class":135,"line":136},[133,1938,1831],{"class":279},[133,1940,1056],{"class":332},[133,1942,1876],{"class":332},[133,1944,1945],{"class":332}," audit",[133,1947,1124],{"class":283},[133,1949,1950,1952,1954,1956,1959],{"class":135,"line":142},[133,1951,1831],{"class":279},[133,1953,1056],{"class":332},[133,1955,1876],{"class":332},[133,1957,1958],{"class":332}," fund",[133,1960,1124],{"class":283},[18,1962,1963,1966,1967,1970],{},[97,1964,1965],{},"audit=false"," 不只是关广告，",[180,1968,1969],{},"它治 npm 8 + 私服环境下的 EPIPE 报错","（详见下面踩坑部分）。",[1153,1972,1974,1975,1977],{"id":1973},"项目级-npmrccommit-到-git团队共享","项目级 ",[97,1976,1920],{},"（commit 到 git，团队共享）",[18,1979,1980],{},"放跟项目相关的配置：",[124,1982,1984],{"className":126,"code":1983,"language":128,"meta":129,"style":129},"registry=http:\u002F\u002F192.168.1.100:8081\u002Frepository\u002Fnpm-group\u002F\nstrict-ssl=false\nfund=false\naudit=false\n",[97,1985,1986,1991,1996,2001],{"__ignoreMap":129},[133,1987,1988],{"class":135,"line":136},[133,1989,1990],{},"registry=http:\u002F\u002F192.168.1.100:8081\u002Frepository\u002Fnpm-group\u002F\n",[133,1992,1993],{"class":135,"line":142},[133,1994,1995],{},"strict-ssl=false\n",[133,1997,1998],{"class":135,"line":148},[133,1999,2000],{},"fund=false\n",[133,2002,2003],{"class":135,"line":154},[133,2004,2005],{},"audit=false\n",[18,2007,2008],{},"公司私服的内网 HTTP registry 写在项目里，新人 clone 就能用。",[1153,2010,2012],{"id":2011},"npm-配置优先级从高到低","npm 配置优先级（从高到低）",[124,2014,2017],{"className":2015,"code":2016,"language":977},[975],"1. 命令行 --xxx=yyy\n2. 项目根 .npmrc\n3. 项目父目录的 .npmrc（向上递归）\n4. 用户级 ~\u002F.npmrc\n5. 全局 $(npm prefix -g)\u002Fetc\u002Fnpmrc\n6. npm 内置默认值\n",[97,2018,2016],{"__ignoreMap":129},[18,2020,2021],{},"查当前生效：",[124,2023,2025],{"className":264,"code":2024,"language":266,"meta":129,"style":129},"npm config list           # 当前所有非默认配置\nnpm config list -l        # 含默认值的所有配置\n",[97,2026,2027,2039],{"__ignoreMap":129},[133,2028,2029,2031,2033,2036],{"class":135,"line":136},[133,2030,1831],{"class":279},[133,2032,1056],{"class":332},[133,2034,2035],{"class":332}," list",[133,2037,2038],{"class":273},"           # 当前所有非默认配置\n",[133,2040,2041,2043,2045,2047,2050],{"class":135,"line":142},[133,2042,1831],{"class":279},[133,2044,1056],{"class":332},[133,2046,2035],{"class":332},[133,2048,2049],{"class":283}," -l",[133,2051,2052],{"class":273},"        # 含默认值的所有配置\n",[120,2054,2056,2057,2060],{"id":2055},"_55-npm-安装报-epipe-怎么办","5.5 npm 安装报 ",[97,2058,2059],{},"EPIPE"," 怎么办",[18,2062,2063,2064,2067,2068,2071],{},"我亲历的真实场景：在大型 Vue2 + webpack4 老项目里跑 ",[97,2065,2066],{},"npm i","，所有 http fetch 都 200 OK，但 reify 阶段（解压写入 ",[97,2069,2070],{},"node_modules","）报：",[124,2073,2076],{"className":2074,"code":2075,"language":977},[975],"npm ERR! code EPIPE\nnpm ERR! syscall write\nnpm ERR! errno -32\nnpm ERR! write EPIPE\n",[97,2077,2075],{"__ignoreMap":129},[18,2079,2080,2083,2084,2087,2088,2091],{},[180,2081,2082],{},"真凶","：npm install 完成后会自动发起 ",[97,2085,2086],{},"npm audit"," 漏洞扫描，",[180,2089,2090],{},"npm 8 + 私服（Nexus \u002F Verdaccio）+ 大项目"," 的组合下，audit 的并发 stream 处理有 bug，会触发 EPIPE。",[18,2093,2094,2097,2098,2100,2101,2103,2104,205],{},[180,2095,2096],{},"修复","：在项目 ",[97,2099,1920],{}," 或用户级 ",[97,2102,1928],{}," 加 ",[97,2105,1965],{},[18,2107,2108],{},"附加修复（提高文件描述符限制，防大项目踩坑）：",[124,2110,2112],{"className":264,"code":2111,"language":266,"meta":129,"style":129},"# 临时\nulimit -n 65536\n\n# 永久（加到 ~\u002F.zshrc）\necho 'ulimit -n 65536' >> ~\u002F.zshrc\n\n# 系统级（\u002Fetc\u002Fsecurity\u002Flimits.conf）\nsudo tee -a \u002Fetc\u002Fsecurity\u002Flimits.conf \u003C\u003C'EOF'\n* soft nofile 65536\n* hard nofile 65536\nEOF\n",[97,2113,2114,2119,2130,2134,2139,2153,2157,2162,2181,2186,2191],{"__ignoreMap":129},[133,2115,2116],{"class":135,"line":136},[133,2117,2118],{"class":273},"# 临时\n",[133,2120,2121,2124,2127],{"class":135,"line":142},[133,2122,2123],{"class":283},"ulimit",[133,2125,2126],{"class":283}," -n",[133,2128,2129],{"class":283}," 65536\n",[133,2131,2132],{"class":135,"line":148},[133,2133,687],{"emptyLinePlaceholder":686},[133,2135,2136],{"class":135,"line":154},[133,2137,2138],{"class":273},"# 永久（加到 ~\u002F.zshrc）\n",[133,2140,2141,2144,2147,2150],{"class":135,"line":160},[133,2142,2143],{"class":283},"echo",[133,2145,2146],{"class":332}," 'ulimit -n 65536'",[133,2148,2149],{"class":750}," >>",[133,2151,2152],{"class":332}," ~\u002F.zshrc\n",[133,2154,2155],{"class":135,"line":166},[133,2156,687],{"emptyLinePlaceholder":686},[133,2158,2159],{"class":135,"line":706},[133,2160,2161],{"class":273},"# 系统级（\u002Fetc\u002Fsecurity\u002Flimits.conf）\n",[133,2163,2164,2166,2169,2172,2175,2178],{"class":135,"line":786},[133,2165,329],{"class":279},[133,2167,2168],{"class":332}," tee",[133,2170,2171],{"class":283}," -a",[133,2173,2174],{"class":332}," \u002Fetc\u002Fsecurity\u002Flimits.conf",[133,2176,2177],{"class":750}," \u003C\u003C",[133,2179,2180],{"class":332},"'EOF'\n",[133,2182,2183],{"class":135,"line":792},[133,2184,2185],{"class":332},"* soft nofile 65536\n",[133,2187,2188],{"class":135,"line":798},[133,2189,2190],{"class":332},"* hard nofile 65536\n",[133,2192,2193],{"class":135,"line":804},[133,2194,2195],{"class":332},"EOF\n",[120,2197,2199],{"id":2198},"_56-npm-还崩-直接换-pnpm","5.6 npm 还崩 → 直接换 pnpm",[18,2201,2202,2203,2206],{},"如果 npm 各种调都不行，",[180,2204,2205],{},"用 pnpm","。它用硬链接 + 内容寻址存储，并发控制更稳，在 WSL2 上实测比 npm 稳定 10 倍。",[124,2208,2210],{"className":264,"code":2209,"language":266,"meta":129,"style":129},"# 通过 npm 装（如果 npm i -g 都崩，下一条）\nnpm install -g pnpm\n\n# 或者用 pnpm 官方独立安装器（不依赖 npm）\ncurl -fsSL https:\u002F\u002Fget.pnpm.io\u002Finstall.sh | sh -\nsource ~\u002F.zshrc\n",[97,2211,2212,2217,2229,2233,2238,2255],{"__ignoreMap":129},[133,2213,2214],{"class":135,"line":136},[133,2215,2216],{"class":273},"# 通过 npm 装（如果 npm i -g 都崩，下一条）\n",[133,2218,2219,2221,2223,2226],{"class":135,"line":142},[133,2220,1831],{"class":279},[133,2222,401],{"class":332},[133,2224,2225],{"class":283}," -g",[133,2227,2228],{"class":332}," pnpm\n",[133,2230,2231],{"class":135,"line":148},[133,2232,687],{"emptyLinePlaceholder":686},[133,2234,2235],{"class":135,"line":154},[133,2236,2237],{"class":273},"# 或者用 pnpm 官方独立安装器（不依赖 npm）\n",[133,2239,2240,2242,2244,2247,2249,2252],{"class":135,"line":160},[133,2241,576],{"class":279},[133,2243,579],{"class":283},[133,2245,2246],{"class":332}," https:\u002F\u002Fget.pnpm.io\u002Finstall.sh",[133,2248,1587],{"class":750},[133,2250,2251],{"class":279}," sh",[133,2253,2254],{"class":332}," -\n",[133,2256,2257,2260],{"class":135,"line":166},[133,2258,2259],{"class":283},"source",[133,2261,2152],{"class":332},[18,2263,2264],{},"用法兼容 npm：",[124,2266,2268],{"className":264,"code":2267,"language":266,"meta":129,"style":129},"pnpm install\npnpm add react\npnpm run dev\n",[97,2269,2270,2278,2288],{"__ignoreMap":129},[133,2271,2272,2275],{"class":135,"line":136},[133,2273,2274],{"class":279},"pnpm",[133,2276,2277],{"class":332}," install\n",[133,2279,2280,2282,2285],{"class":135,"line":142},[133,2281,2274],{"class":279},[133,2283,2284],{"class":332}," add",[133,2286,2287],{"class":332}," react\n",[133,2289,2290,2292,2295],{"class":135,"line":148},[133,2291,2274],{"class":279},[133,2293,2294],{"class":332}," run",[133,2296,2297],{"class":332}," dev\n",[18,2299,2300,2302],{},[97,2301,1920],{}," 配置 pnpm 也认。",[120,2304,2306],{"id":2305},"_57-enotempty-错误","5.7 ENOTEMPTY 错误",[124,2308,2311],{"className":2309,"code":2310,"language":977},[975],"npm ERR! code ENOTEMPTY\nnpm ERR! ENOTEMPTY: directory not empty, rename '...\u002Fnode_modules\u002Fbody-parser' -> '...'\n",[97,2312,2310],{"__ignoreMap":129},[18,2314,2315,2316,642],{},"这是上次 npm i 半成功留下的脏状态。",[180,2317,2318],{},"彻底清理重来",[124,2320,2322],{"className":264,"code":2321,"language":266,"meta":129,"style":129},"rm -rf node_modules\nrm -f package-lock.json yarn.lock pnpm-lock.yaml\nnpm cache clean --force\nulimit -n 65536\nnpm i    # 或 pnpm install\n",[97,2323,2324,2334,2349,2362,2370],{"__ignoreMap":129},[133,2325,2326,2328,2331],{"class":135,"line":136},[133,2327,1020],{"class":279},[133,2329,2330],{"class":283}," -rf",[133,2332,2333],{"class":332}," node_modules\n",[133,2335,2336,2338,2340,2343,2346],{"class":135,"line":142},[133,2337,1020],{"class":279},[133,2339,1013],{"class":283},[133,2341,2342],{"class":332}," package-lock.json",[133,2344,2345],{"class":332}," yarn.lock",[133,2347,2348],{"class":332}," pnpm-lock.yaml\n",[133,2350,2351,2353,2356,2359],{"class":135,"line":148},[133,2352,1831],{"class":279},[133,2354,2355],{"class":332}," cache",[133,2357,2358],{"class":332}," clean",[133,2360,2361],{"class":283}," --force\n",[133,2363,2364,2366,2368],{"class":135,"line":154},[133,2365,2123],{"class":283},[133,2367,2126],{"class":283},[133,2369,2129],{"class":283},[133,2371,2372,2374,2377],{"class":135,"line":160},[133,2373,1831],{"class":279},[133,2375,2376],{"class":332}," i",[133,2378,2379],{"class":273},"    # 或 pnpm install\n",[102,2381],{},[22,2383,2385],{"id":2384},"六python-uv-配置","六、Python \u002F uv 配置",[18,2387,2388,2391,2392,2395,2396,205],{},[97,2389,2390],{},"uv"," 是 Astral 出的 Python 包管理器，",[180,2393,2394],{},"一站式替代"," pyenv + pip + pipx + poetry + virtualenv，用 Rust 写的，比 pip 快 10-100 倍。",[180,2397,2398],{},"2024-2025 Python 圈的事实标准",[120,2400,2402],{"id":2401},"_61-安装","6.1 安装",[124,2404,2406],{"className":264,"code":2405,"language":266,"meta":129,"style":129},"curl -LsSf https:\u002F\u002Fastral.sh\u002Fuv\u002Finstall.sh | sh\nsource ~\u002F.zshrc\nuv --version\n",[97,2407,2408,2423,2429],{"__ignoreMap":129},[133,2409,2410,2412,2415,2418,2420],{"class":135,"line":136},[133,2411,576],{"class":279},[133,2413,2414],{"class":283}," -LsSf",[133,2416,2417],{"class":332}," https:\u002F\u002Fastral.sh\u002Fuv\u002Finstall.sh",[133,2419,1587],{"class":750},[133,2421,2422],{"class":279}," sh\n",[133,2424,2425,2427],{"class":135,"line":142},[133,2426,2259],{"class":283},[133,2428,2152],{"class":332},[133,2430,2431,2433],{"class":135,"line":148},[133,2432,2390],{"class":279},[133,2434,2435],{"class":283}," --version\n",[120,2437,2439],{"id":2438},"_62-常用命令速查","6.2 常用命令速查",[26,2441,2442,2452],{},[29,2443,2444],{},[32,2445,2446,2449],{},[35,2447,2448],{},"用途",[35,2450,2451],{},"命令",[42,2453,2454,2464,2474,2484,2494,2504,2514,2524,2534,2545],{},[32,2455,2456,2459],{},[47,2457,2458],{},"装 Python 解释器",[47,2460,2461],{},[97,2462,2463],{},"uv python install 3.12",[32,2465,2466,2469],{},[47,2467,2468],{},"列出已装版本",[47,2470,2471],{},[97,2472,2473],{},"uv python list",[32,2475,2476,2479],{},[47,2477,2478],{},"创建项目",[47,2480,2481],{},[97,2482,2483],{},"uv init myproject && cd myproject",[32,2485,2486,2489],{},[47,2487,2488],{},"加依赖",[47,2490,2491],{},[97,2492,2493],{},"uv add requests",[32,2495,2496,2499],{},[47,2497,2498],{},"删依赖",[47,2500,2501],{},[97,2502,2503],{},"uv remove requests",[32,2505,2506,2509],{},[47,2507,2508],{},"运行脚本",[47,2510,2511],{},[97,2512,2513],{},"uv run python xxx.py",[32,2515,2516,2519],{},[47,2517,2518],{},"同步依赖",[47,2520,2521],{},[97,2522,2523],{},"uv sync",[32,2525,2526,2529],{},[47,2527,2528],{},"单文件脚本依赖",[47,2530,2531],{},[97,2532,2533],{},"uv run --with requests script.py",[32,2535,2536,2539],{},[47,2537,2538],{},"临时跑工具",[47,2540,2541,2544],{},[97,2542,2543],{},"uvx ruff check .","（类似 npx）",[32,2546,2547,2550],{},[47,2548,2549],{},"装独立 CLI 工具",[47,2551,2552],{},[97,2553,2554],{},"uv tool install ruff",[120,2556,2558],{"id":2557},"_63-基础工作流","6.3 基础工作流",[124,2560,2562],{"className":264,"code":2561,"language":266,"meta":129,"style":129},"uv python install 3.12             # 装 Python 3.12（uv 自己管理，不污染系统）\nuv init test-proj && cd test-proj  # 创建项目\nuv add requests                    # 加依赖（自动建 venv）\nuv run python -c \"import requests; print(requests.__version__)\"\n",[97,2563,2564,2579,2599,2611],{"__ignoreMap":129},[133,2565,2566,2568,2571,2573,2576],{"class":135,"line":136},[133,2567,2390],{"class":279},[133,2569,2570],{"class":332}," python",[133,2572,401],{"class":332},[133,2574,2575],{"class":283}," 3.12",[133,2577,2578],{"class":273},"             # 装 Python 3.12（uv 自己管理，不污染系统）\n",[133,2580,2581,2583,2586,2589,2591,2594,2596],{"class":135,"line":142},[133,2582,2390],{"class":279},[133,2584,2585],{"class":332}," init",[133,2587,2588],{"class":332}," test-proj",[133,2590,373],{"class":372},[133,2592,2593],{"class":283},"cd",[133,2595,2588],{"class":332},[133,2597,2598],{"class":273},"  # 创建项目\n",[133,2600,2601,2603,2605,2608],{"class":135,"line":148},[133,2602,2390],{"class":279},[133,2604,2284],{"class":332},[133,2606,2607],{"class":332}," requests",[133,2609,2610],{"class":273},"                    # 加依赖（自动建 venv）\n",[133,2612,2613,2615,2617,2619,2621],{"class":135,"line":154},[133,2614,2390],{"class":279},[133,2616,2294],{"class":332},[133,2618,2570],{"class":332},[133,2620,570],{"class":283},[133,2622,2623],{"class":332}," \"import requests; print(requests.__version__)\"\n",[18,2625,2626,2627,2630,2631,205],{},"不再需要手动 ",[97,2628,2629],{},"python -m venv .venv && source .venv\u002Fbin\u002Factivate","，",[180,2632,2633],{},"uv 自动管理 venv",[102,2635],{},[22,2637,2639],{"id":2638},"七跨系统协作","七、跨系统协作",[120,2641,2643],{"id":2642},"_71-git-凭据复用-windowshttps-场景","7.1 Git 凭据复用 Windows（HTTPS 场景）",[18,2645,2646],{},"如果你不用 SSH 而走 HTTPS clone，可以复用 Windows 的 Git Credential Manager（GCM）：",[124,2648,2650],{"className":264,"code":2649,"language":266,"meta":129,"style":129},"# 验证 Windows Git 是否能被 WSL 调用\nwhich git-credential-manager.exe\n\n# 如果有输出（说明 Windows 装了 Git for Windows）\ngit config --global credential.helper manager\n\n# 如果要写完整路径（注意外单引号 + 内双引号，避免 sh 转义吃掉空格）\ngit config --global credential.helper '\"\u002Fmnt\u002Fc\u002FProgram Files\u002FGit\u002Fmingw64\u002Fbin\u002Fgit-credential-manager.exe\"'\n",[97,2651,2652,2657,2664,2668,2673,2687,2691,2696],{"__ignoreMap":129},[133,2653,2654],{"class":135,"line":136},[133,2655,2656],{"class":273},"# 验证 Windows Git 是否能被 WSL 调用\n",[133,2658,2659,2661],{"class":135,"line":142},[133,2660,630],{"class":283},[133,2662,2663],{"class":332}," git-credential-manager.exe\n",[133,2665,2666],{"class":135,"line":148},[133,2667,687],{"emptyLinePlaceholder":686},[133,2669,2670],{"class":135,"line":154},[133,2671,2672],{"class":273},"# 如果有输出（说明 Windows 装了 Git for Windows）\n",[133,2674,2675,2677,2679,2681,2684],{"class":135,"line":160},[133,2676,668],{"class":279},[133,2678,1056],{"class":332},[133,2680,1059],{"class":283},[133,2682,2683],{"class":332}," credential.helper",[133,2685,2686],{"class":332}," manager\n",[133,2688,2689],{"class":135,"line":166},[133,2690,687],{"emptyLinePlaceholder":686},[133,2692,2693],{"class":135,"line":706},[133,2694,2695],{"class":273},"# 如果要写完整路径（注意外单引号 + 内双引号，避免 sh 转义吃掉空格）\n",[133,2697,2698,2700,2702,2704,2706],{"class":135,"line":786},[133,2699,668],{"class":279},[133,2701,1056],{"class":332},[133,2703,1059],{"class":283},[133,2705,2683],{"class":332},[133,2707,2708],{"class":332}," '\"\u002Fmnt\u002Fc\u002FProgram Files\u002FGit\u002Fmingw64\u002Fbin\u002Fgit-credential-manager.exe\"'\n",[18,2710,2711,2712,2715],{},"但",[180,2713,2714],{},"推荐还是用 SSH key","（方案 A），更纯粹。",[120,2717,2719],{"id":2718},"_72-vs-code-集成","7.2 VS Code 集成",[18,2721,2722],{},"Windows 装好 VS Code 后，WSL 里：",[124,2724,2726],{"className":264,"code":2725,"language":266,"meta":129,"style":129},"cd ~\u002Fprojects\u002Fmyproject\ncode .\n",[97,2727,2728,2735],{"__ignoreMap":129},[133,2729,2730,2732],{"class":135,"line":136},[133,2731,2593],{"class":283},[133,2733,2734],{"class":332}," ~\u002Fprojects\u002Fmyproject\n",[133,2736,2737,2739],{"class":135,"line":142},[133,2738,97],{"class":279},[133,2740,2741],{"class":332}," .\n",[18,2743,2744,2745,205],{},"会自动装 Remote-WSL server 端，本地 VS Code 通过 WSL Remote 打开项目，",[180,2746,2747],{},"编辑器在 Windows，运行在 WSL",[120,2749,2751],{"id":2750},"_73-文件位置铁律","7.3 文件位置铁律",[26,2753,2754,2763],{},[29,2755,2756],{},[32,2757,2758,2760],{},[35,2759,2448],{},[35,2761,2762],{},"路径",[42,2764,2765,2775,2786],{},[32,2766,2767,2770],{},[47,2768,2769],{},"WSL 访问 Windows 用户目录",[47,2771,2772],{},[97,2773,2774],{},"\u002Fmnt\u002Fc\u002FUsers\u002F\u003C你的用户名>\u002F",[32,2776,2777,2780],{},[47,2778,2779],{},"Windows 访问 WSL 文件系统",[47,2781,2782,2783],{},"资源管理器输入 ",[97,2784,2785],{},"\\\\wsl$\\Ubuntu-24.04\\home\\\u003C你的用户名>\\",[32,2787,2788,2791],{},[47,2789,2790],{},"项目存放位置",[47,2792,2793,1497,2796],{},[180,2794,2795],{},"必须放 WSL 原生路径",[97,2797,2798],{},"~\u002Fprojects\u002F",[18,2800,2801,642],{},[180,2802,2803,2804,2807,2808],{},"🚫 项目千万别放 ",[97,2805,2806],{},"\u002Fmnt\u002Fc\u002F"," 或 ",[97,2809,2810],{},"\u002Fmnt\u002Ff\u002F",[174,2812,2813,2816,2825],{},[177,2814,2815],{},"9P 协议挂载的 Windows 盘，IO 慢 10 倍以上",[177,2817,2818,534,2821,2824],{},[97,2819,2820],{},"git status",[97,2822,2823],{},"npm install"," 会卡到怀疑人生",[177,2826,2827],{},"文件监听（HMR）也会出问题",[18,2829,2830,2831,205],{},"如果项目本来在 Windows 盘，",[180,2832,2833,2834,2836],{},"git clone 一份到 ",[97,2835,2798],{}," 用",[102,2838],{},[22,2840,2842],{"id":2841},"八踩坑速查表","八、踩坑速查表",[26,2844,2845,2857],{},[29,2846,2847],{},[32,2848,2849,2852,2855],{},[35,2850,2851],{},"现象",[35,2853,2854],{},"原因",[35,2856,2096],{},[42,2858,2859,2870,2883,2898,2914,2936,2952,2967,2986,3008,3023],{},[32,2860,2861,2864,2867],{},[47,2862,2863],{},"WSL 内 ping IP 通但解析域名失败",[47,2865,2866],{},"Clash TUN 拦了 DNS \u002F 镜像模式问题",[47,2868,2869],{},"NAT 模式 + Clash 排除内网网段不包含 WSL 网段",[32,2871,2872,2877,2880],{},[47,2873,2874],{},[97,2875,2876],{},"Destination Host Unreachable",[47,2878,2879],{},"ARP 失败（火绒「对外 ARP 攻击拦截」误伤 Hyper-V 网卡）",[47,2881,2882],{},"关闭火绒「对外 ARP 攻击拦截」",[32,2884,2885,2890,2893],{},[47,2886,2887],{},[97,2888,2889],{},"ssh: Connection closed by ... port 22",[47,2891,2892],{},"ISP 干扰 GitHub 22 端口",[47,2894,2895,2896],{},"用 ",[97,2897,1426],{},[32,2899,2900,2905,2908],{},[47,2901,2902],{},[97,2903,2904],{},"npm ERR! EPIPE",[47,2906,2907],{},"npm 8 + 私服 audit 流崩",[47,2909,2910,2103,2912],{},[97,2911,1920],{},[97,2913,1965],{},[32,2915,2916,2921,2924],{},[47,2917,2918],{},[97,2919,2920],{},"ENOTEMPTY: directory not empty",[47,2922,2923],{},"上次 npm i 半成功",[47,2925,2926,2927,2929,2930,2929,2933],{},"删 ",[97,2928,2070],{}," + ",[97,2931,2932],{},"package-lock.json",[97,2934,2935],{},"npm cache clean --force",[32,2937,2938,2944,2947],{},[47,2939,2940,2943],{},[97,2941,2942],{},"nvm install"," 卡住",[47,2945,2946],{},"下载 nodejs.org 超时",[47,2948,2949],{},[97,2950,2951],{},"export NVM_NODEJS_ORG_MIRROR=https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode",[32,2953,2954,2959,2962],{},[47,2955,2956],{},[97,2957,2958],{},"No acceptable C compiler found",[47,2960,2961],{},"没装 build-essential",[47,2963,2964],{},[97,2965,2966],{},"sudo apt install build-essential",[32,2968,2969,2974,2977],{},[47,2970,2971],{},[97,2972,2973],{},"compinit:527: no such file ...",[47,2975,2976],{},"Docker Desktop 死链残留",[47,2978,2979,2980,2929,2983],{},"删死链 + ",[97,2981,2982],{},"rm ~\u002F.zcompdump*",[97,2984,2985],{},"exec zsh",[32,2987,2988,2993,2998],{},[47,2989,2990],{},[97,2991,2992],{},"rm: cannot remove ...: Is a directory",[47,2994,2895,2995,2997],{},[97,2996,1020],{}," 删目录",[47,2999,3000,3003,3004,3007],{},[97,3001,3002],{},"rmdir","（空）或 ",[97,3005,3006],{},"rm -r","（非空）",[32,3009,3010,3013,3016],{},[47,3011,3012],{},"PowerShell 脚本中文注释报错",[47,3014,3015],{},"UTF-8 无 BOM 被按 GBK 解码",[47,3017,3018,3019,3022],{},"用记事本另存为 \"UTF-8 with BOM\" 或改用 PowerShell 7 (",[97,3020,3021],{},"pwsh",")",[32,3024,3025,3031,3034],{},[47,3026,3027,3030],{},[97,3028,3029],{},"rm -rf"," 误删",[47,3032,3033],{},"没有回收站，永久消失",[47,3035,3036,3037,3040,3041,3044],{},"装 ",[97,3038,3039],{},"trash-cli","，用 ",[97,3042,3043],{},"trash"," 替代",[102,3046],{},[22,3048,3050,3051,3053],{"id":3049},"九zshrc-完整参考","九、",[97,3052,731],{}," 完整参考",[124,3055,3057],{"className":264,"code":3056,"language":266,"meta":129,"style":129},"# Path to Oh My Zsh\nexport ZSH=\"$HOME\u002F.oh-my-zsh\"\n\n# 随机主题 + 候选池\nZSH_THEME=\"random\"\nZSH_THEME_RANDOM_CANDIDATES=(\n  \"robbyrussell\" \"ys\" \"bureau\" \"candy\" \"clean\" \"fishy\"\n  \"gnzh\" \"jonathan\" \"kolo\" \"mh\" \"muse\" \"sorin\" \"fox\" \"kphoen\"\n)\n\n# 插件\nplugins=(git zsh-autosuggestions zsh-syntax-highlighting)\n\nsource $ZSH\u002Foh-my-zsh.sh\n\n# ---------- 自定义 ----------\n\n# 文件描述符上限（大型项目 npm install）\nulimit -n 65536\n\n# nvm\nexport NVM_DIR=\"$HOME\u002F.nvm\"\n[ -s \"$NVM_DIR\u002Fnvm.sh\" ] && \\. \"$NVM_DIR\u002Fnvm.sh\"\n[ -s \"$NVM_DIR\u002Fbash_completion\" ] && \\. \"$NVM_DIR\u002Fbash_completion\"\n\n# nvm 下载源（淘宝镜像）\nexport NVM_NODEJS_ORG_MIRROR=https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\n\n# 代理开关（备用，TUN 模式下不需要）\nproxy_on() {\n  export hostip=$(ip route show | grep -i default | awk '{print $3}')\n  export http_proxy=\"http:\u002F\u002F$hostip:7890\"\n  export https_proxy=\"http:\u002F\u002F$hostip:7890\"\n  export all_proxy=\"socks5:\u002F\u002F$hostip:7890\"\n  echo \"Proxy on: $http_proxy\"\n}\nproxy_off() {\n  unset http_proxy https_proxy all_proxy\n  echo \"Proxy off\"\n}\n\n# 常用别名\nalias ll='ls -lah'\nalias ..='cd ..'\nalias ...='cd ..\u002F..'\n",[97,3058,3059,3064,3080,3084,3089,3097,3105,3125,3151,3155,3159,3163,3179,3183,3193,3197,3202,3206,3211,3219,3223,3228,3242,3264,3287,3292,3298,3309,3314,3320,3329,3371,3390,3406,3423,3438,3444,3452,3465,3473,3478,3483,3489,3503,3511],{"__ignoreMap":129},[133,3060,3061],{"class":135,"line":136},[133,3062,3063],{"class":273},"# Path to Oh My Zsh\n",[133,3065,3066,3068,3071,3073,3075,3077],{"class":135,"line":142},[133,3067,1621],{"class":750},[133,3069,3070],{"class":372}," ZSH",[133,3072,751],{"class":750},[133,3074,1629],{"class":332},[133,3076,1632],{"class":372},[133,3078,3079],{"class":332},"\u002F.oh-my-zsh\"\n",[133,3081,3082],{"class":135,"line":148},[133,3083,687],{"emptyLinePlaceholder":686},[133,3085,3086],{"class":135,"line":154},[133,3087,3088],{"class":273},"# 随机主题 + 候选池\n",[133,3090,3091,3093,3095],{"class":135,"line":160},[133,3092,747],{"class":372},[133,3094,751],{"class":750},[133,3096,754],{"class":332},[133,3098,3099,3101,3103],{"class":135,"line":166},[133,3100,768],{"class":372},[133,3102,751],{"class":750},[133,3104,773],{"class":372},[133,3106,3107,3110,3113,3116,3119,3122],{"class":135,"line":706},[133,3108,3109],{"class":332},"  \"robbyrussell\"",[133,3111,3112],{"class":332}," \"ys\"",[133,3114,3115],{"class":332}," \"bureau\"",[133,3117,3118],{"class":332}," \"candy\"",[133,3120,3121],{"class":332}," \"clean\"",[133,3123,3124],{"class":332}," \"fishy\"\n",[133,3126,3127,3130,3133,3136,3139,3142,3145,3148],{"class":135,"line":786},[133,3128,3129],{"class":332},"  \"gnzh\"",[133,3131,3132],{"class":332}," \"jonathan\"",[133,3134,3135],{"class":332}," \"kolo\"",[133,3137,3138],{"class":332}," \"mh\"",[133,3140,3141],{"class":332}," \"muse\"",[133,3143,3144],{"class":332}," \"sorin\"",[133,3146,3147],{"class":332}," \"fox\"",[133,3149,3150],{"class":332}," \"kphoen\"\n",[133,3152,3153],{"class":135,"line":792},[133,3154,636],{"class":372},[133,3156,3157],{"class":135,"line":798},[133,3158,687],{"emptyLinePlaceholder":686},[133,3160,3161],{"class":135,"line":804},[133,3162,871],{"class":273},[133,3164,3165,3167,3169,3171,3173,3175,3177],{"class":135,"line":810},[133,3166,877],{"class":372},[133,3168,751],{"class":750},[133,3170,882],{"class":372},[133,3172,668],{"class":332},[133,3174,887],{"class":332},[133,3176,890],{"class":332},[133,3178,636],{"class":372},[133,3180,3181],{"class":135,"line":816},[133,3182,687],{"emptyLinePlaceholder":686},[133,3184,3185,3187,3190],{"class":135,"line":822},[133,3186,2259],{"class":283},[133,3188,3189],{"class":372}," $ZSH",[133,3191,3192],{"class":332},"\u002Foh-my-zsh.sh\n",[133,3194,3195],{"class":135,"line":828},[133,3196,687],{"emptyLinePlaceholder":686},[133,3198,3199],{"class":135,"line":834},[133,3200,3201],{"class":273},"# ---------- 自定义 ----------\n",[133,3203,3204],{"class":135,"line":840},[133,3205,687],{"emptyLinePlaceholder":686},[133,3207,3208],{"class":135,"line":846},[133,3209,3210],{"class":273},"# 文件描述符上限（大型项目 npm install）\n",[133,3212,3213,3215,3217],{"class":135,"line":852},[133,3214,2123],{"class":283},[133,3216,2126],{"class":283},[133,3218,2129],{"class":283},[133,3220,3221],{"class":135,"line":858},[133,3222,687],{"emptyLinePlaceholder":686},[133,3224,3225],{"class":135,"line":863},[133,3226,3227],{"class":273},"# nvm\n",[133,3229,3230,3232,3234,3236,3238,3240],{"class":135,"line":868},[133,3231,1621],{"class":750},[133,3233,1624],{"class":372},[133,3235,751],{"class":750},[133,3237,1629],{"class":332},[133,3239,1632],{"class":372},[133,3241,1635],{"class":332},[133,3243,3244,3246,3248,3250,3252,3254,3256,3258,3260,3262],{"class":135,"line":874},[133,3245,1640],{"class":372},[133,3247,1643],{"class":750},[133,3249,1646],{"class":332},[133,3251,1649],{"class":372},[133,3253,1652],{"class":332},[133,3255,1655],{"class":372},[133,3257,1658],{"class":279},[133,3259,1646],{"class":332},[133,3261,1649],{"class":372},[133,3263,1665],{"class":332},[133,3265,3267,3269,3271,3273,3275,3277,3279,3281,3283,3285],{"class":135,"line":3266},24,[133,3268,1640],{"class":372},[133,3270,1643],{"class":750},[133,3272,1646],{"class":332},[133,3274,1649],{"class":372},[133,3276,1678],{"class":332},[133,3278,1655],{"class":372},[133,3280,1658],{"class":279},[133,3282,1646],{"class":332},[133,3284,1649],{"class":372},[133,3286,1689],{"class":332},[133,3288,3290],{"class":135,"line":3289},25,[133,3291,687],{"emptyLinePlaceholder":686},[133,3293,3295],{"class":135,"line":3294},26,[133,3296,3297],{"class":273},"# nvm 下载源（淘宝镜像）\n",[133,3299,3301,3303,3305,3307],{"class":135,"line":3300},27,[133,3302,1621],{"class":750},[133,3304,1721],{"class":372},[133,3306,751],{"class":750},[133,3308,1726],{"class":372},[133,3310,3312],{"class":135,"line":3311},28,[133,3313,687],{"emptyLinePlaceholder":686},[133,3315,3317],{"class":135,"line":3316},29,[133,3318,3319],{"class":273},"# 代理开关（备用，TUN 模式下不需要）\n",[133,3321,3323,3326],{"class":135,"line":3322},30,[133,3324,3325],{"class":279},"proxy_on",[133,3327,3328],{"class":372},"() {\n",[133,3330,3332,3335,3338,3340,3343,3346,3349,3352,3354,3357,3359,3361,3363,3366,3369],{"class":135,"line":3331},31,[133,3333,3334],{"class":750},"  export",[133,3336,3337],{"class":372}," hostip",[133,3339,751],{"class":750},[133,3341,3342],{"class":372},"$(",[133,3344,3345],{"class":279},"ip",[133,3347,3348],{"class":332}," route",[133,3350,3351],{"class":332}," show",[133,3353,1587],{"class":750},[133,3355,3356],{"class":279}," grep",[133,3358,336],{"class":283},[133,3360,1766],{"class":332},[133,3362,1587],{"class":750},[133,3364,3365],{"class":279}," awk",[133,3367,3368],{"class":332}," '{print $3}'",[133,3370,636],{"class":372},[133,3372,3374,3376,3379,3381,3384,3387],{"class":135,"line":3373},32,[133,3375,3334],{"class":750},[133,3377,3378],{"class":372}," http_proxy",[133,3380,751],{"class":750},[133,3382,3383],{"class":332},"\"http:\u002F\u002F",[133,3385,3386],{"class":372},"$hostip",[133,3388,3389],{"class":332},":7890\"\n",[133,3391,3393,3395,3398,3400,3402,3404],{"class":135,"line":3392},33,[133,3394,3334],{"class":750},[133,3396,3397],{"class":372}," https_proxy",[133,3399,751],{"class":750},[133,3401,3383],{"class":332},[133,3403,3386],{"class":372},[133,3405,3389],{"class":332},[133,3407,3409,3411,3414,3416,3419,3421],{"class":135,"line":3408},34,[133,3410,3334],{"class":750},[133,3412,3413],{"class":372}," all_proxy",[133,3415,751],{"class":750},[133,3417,3418],{"class":332},"\"socks5:\u002F\u002F",[133,3420,3386],{"class":372},[133,3422,3389],{"class":332},[133,3424,3426,3429,3432,3435],{"class":135,"line":3425},35,[133,3427,3428],{"class":283},"  echo",[133,3430,3431],{"class":332}," \"Proxy on: ",[133,3433,3434],{"class":372},"$http_proxy",[133,3436,3437],{"class":332},"\"\n",[133,3439,3441],{"class":135,"line":3440},36,[133,3442,3443],{"class":372},"}\n",[133,3445,3447,3450],{"class":135,"line":3446},37,[133,3448,3449],{"class":279},"proxy_off",[133,3451,3328],{"class":372},[133,3453,3455,3458,3460,3462],{"class":135,"line":3454},38,[133,3456,3457],{"class":283},"  unset",[133,3459,3378],{"class":332},[133,3461,3397],{"class":332},[133,3463,3464],{"class":332}," all_proxy\n",[133,3466,3468,3470],{"class":135,"line":3467},39,[133,3469,3428],{"class":283},[133,3471,3472],{"class":332}," \"Proxy off\"\n",[133,3474,3476],{"class":135,"line":3475},40,[133,3477,3443],{"class":372},[133,3479,3481],{"class":135,"line":3480},41,[133,3482,687],{"emptyLinePlaceholder":686},[133,3484,3486],{"class":135,"line":3485},42,[133,3487,3488],{"class":273},"# 常用别名\n",[133,3490,3492,3495,3498,3500],{"class":135,"line":3491},43,[133,3493,3494],{"class":750},"alias",[133,3496,3497],{"class":372}," ll",[133,3499,751],{"class":750},[133,3501,3502],{"class":332},"'ls -lah'\n",[133,3504,3506,3508],{"class":135,"line":3505},44,[133,3507,3494],{"class":283},[133,3509,3510],{"class":332}," ..='cd ..'\n",[133,3512,3514,3516],{"class":135,"line":3513},45,[133,3515,3494],{"class":283},[133,3517,3518],{"class":332}," ...='cd ..\u002F..'\n",[102,3520],{},[22,3522,3524],{"id":3523},"十初始化清单按顺序执行","十、初始化清单（按顺序执行）",[124,3526,3528],{"className":264,"code":3527,"language":266,"meta":129,"style":129},"# 1. 换源 + 基础工具\nsudo sed -i 's@\u002F\u002F.*archive.ubuntu.com@\u002F\u002Fmirrors.tuna.tsinghua.edu.cn@g; s@\u002F\u002Fsecurity.ubuntu.com@\u002F\u002Fmirrors.tuna.tsinghua.edu.cn@g' \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fubuntu.sources\nsudo apt update && sudo apt upgrade -y\nsudo apt install -y build-essential git curl wget vim zsh unzip ca-certificates gnupg net-tools dnsutils\n\n# 2. Zsh + Oh My Zsh\nsh -c \"$(curl -fsSL https:\u002F\u002Fgitee.com\u002Fmirrors\u002Foh-my-zsh\u002Fraw\u002Fmaster\u002Ftools\u002Finstall.sh)\"\nchsh -s $(which zsh)\ngit clone https:\u002F\u002Fgithub.com\u002Fzsh-users\u002Fzsh-autosuggestions ~\u002F.oh-my-zsh\u002Fcustom\u002Fplugins\u002Fzsh-autosuggestions\ngit clone https:\u002F\u002Fgithub.com\u002Fzsh-users\u002Fzsh-syntax-highlighting ~\u002F.oh-my-zsh\u002Fcustom\u002Fplugins\u002Fzsh-syntax-highlighting\n# 然后编辑 ~\u002F.zshrc 改主题和 plugins\n\n# 3. Git 基础\ngit config --global user.name \"你的名字\"\ngit config --global user.email \"你的邮箱\"\ngit config --global core.autocrlf input\ngit config --global init.defaultBranch main\n\n# 4. SSH key + GitHub 443\nssh-keygen -t ed25519 -C \"邮箱\"\ncat > ~\u002F.ssh\u002Fconfig \u003C\u003C'EOF'\nHost github.com\n    Hostname ssh.github.com\n    Port 443\n    User git\n    IdentityFile ~\u002F.ssh\u002Fid_ed25519\n    IdentitiesOnly yes\nEOF\nchmod 600 ~\u002F.ssh\u002Fconfig\n# 把 ~\u002F.ssh\u002Fid_ed25519.pub 加到 GitHub\nssh -T git@github.com\n\n# 5. nvm + Node\ncurl -o- https:\u002F\u002Fgitee.com\u002Fmirrors\u002Fnvm\u002Fraw\u002Fmaster\u002Finstall.sh | bash\necho 'export NVM_NODEJS_ORG_MIRROR=https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode' >> ~\u002F.zshrc\nexec zsh\nnvm install --lts\nnvm alias default lts\u002F*\n\n# 6. npm 全局配置\nnpm config set audit false\nnpm config set fund false\n\n# 7. uv (Python)\ncurl -LsSf https:\u002F\u002Fastral.sh\u002Fuv\u002Finstall.sh | sh\nsource ~\u002F.zshrc\nuv python install 3.12\n",[97,3529,3530,3535,3549,3567,3603,3607,3612,3626,3640,3651,3662,3667,3671,3676,3688,3700,3713,3725,3729,3734,3747,3761,3766,3771,3776,3781,3786,3791,3795,3803,3808,3816,3820,3825,3837,3848,3854,3862,3874,3878,3883,3895,3907,3911,3916,3928,3935],{"__ignoreMap":129},[133,3531,3532],{"class":135,"line":136},[133,3533,3534],{"class":273},"# 1. 换源 + 基础工具\n",[133,3536,3537,3539,3541,3543,3546],{"class":135,"line":142},[133,3538,329],{"class":279},[133,3540,333],{"class":332},[133,3542,336],{"class":283},[133,3544,3545],{"class":332}," 's@\u002F\u002F.*archive.ubuntu.com@\u002F\u002Fmirrors.tuna.tsinghua.edu.cn@g; s@\u002F\u002Fsecurity.ubuntu.com@\u002F\u002Fmirrors.tuna.tsinghua.edu.cn@g'",[133,3547,3548],{"class":332}," \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fubuntu.sources\n",[133,3550,3551,3553,3555,3557,3559,3561,3563,3565],{"class":135,"line":148},[133,3552,329],{"class":279},[133,3554,366],{"class":332},[133,3556,369],{"class":332},[133,3558,373],{"class":372},[133,3560,329],{"class":279},[133,3562,366],{"class":332},[133,3564,380],{"class":332},[133,3566,383],{"class":283},[133,3568,3569,3571,3573,3575,3577,3580,3583,3585,3587,3589,3591,3593,3596,3598,3601],{"class":135,"line":154},[133,3570,329],{"class":279},[133,3572,366],{"class":332},[133,3574,401],{"class":332},[133,3576,404],{"class":283},[133,3578,3579],{"class":332}," build-essential",[133,3581,3582],{"class":332}," git",[133,3584,421],{"class":332},[133,3586,424],{"class":332},[133,3588,427],{"class":332},[133,3590,633],{"class":332},[133,3592,437],{"class":332},[133,3594,3595],{"class":332}," ca-certificates",[133,3597,447],{"class":332},[133,3599,3600],{"class":332}," net-tools",[133,3602,460],{"class":332},[133,3604,3605],{"class":135,"line":160},[133,3606,687],{"emptyLinePlaceholder":686},[133,3608,3609],{"class":135,"line":166},[133,3610,3611],{"class":273},"# 2. Zsh + Oh My Zsh\n",[133,3613,3614,3616,3618,3620,3622,3624],{"class":135,"line":706},[133,3615,567],{"class":279},[133,3617,570],{"class":283},[133,3619,573],{"class":332},[133,3621,576],{"class":279},[133,3623,579],{"class":283},[133,3625,582],{"class":332},[133,3627,3628,3630,3632,3634,3636,3638],{"class":135,"line":786},[133,3629,621],{"class":279},[133,3631,624],{"class":283},[133,3633,627],{"class":372},[133,3635,630],{"class":283},[133,3637,633],{"class":332},[133,3639,636],{"class":372},[133,3641,3642,3644,3646,3648],{"class":135,"line":792},[133,3643,668],{"class":279},[133,3645,671],{"class":332},[133,3647,674],{"class":332},[133,3649,3650],{"class":332}," ~\u002F.oh-my-zsh\u002Fcustom\u002Fplugins\u002Fzsh-autosuggestions\n",[133,3652,3653,3655,3657,3659],{"class":135,"line":798},[133,3654,668],{"class":279},[133,3656,671],{"class":332},[133,3658,701],{"class":332},[133,3660,3661],{"class":332}," ~\u002F.oh-my-zsh\u002Fcustom\u002Fplugins\u002Fzsh-syntax-highlighting\n",[133,3663,3664],{"class":135,"line":804},[133,3665,3666],{"class":273},"# 然后编辑 ~\u002F.zshrc 改主题和 plugins\n",[133,3668,3669],{"class":135,"line":810},[133,3670,687],{"emptyLinePlaceholder":686},[133,3672,3673],{"class":135,"line":816},[133,3674,3675],{"class":273},"# 3. Git 基础\n",[133,3677,3678,3680,3682,3684,3686],{"class":135,"line":822},[133,3679,668],{"class":279},[133,3681,1056],{"class":332},[133,3683,1059],{"class":283},[133,3685,1062],{"class":332},[133,3687,1065],{"class":332},[133,3689,3690,3692,3694,3696,3698],{"class":135,"line":828},[133,3691,668],{"class":279},[133,3693,1056],{"class":332},[133,3695,1059],{"class":283},[133,3697,1076],{"class":332},[133,3699,1079],{"class":332},[133,3701,3702,3704,3706,3708,3710],{"class":135,"line":834},[133,3703,668],{"class":279},[133,3705,1056],{"class":332},[133,3707,1059],{"class":283},[133,3709,1104],{"class":332},[133,3711,3712],{"class":332}," input\n",[133,3714,3715,3717,3719,3721,3723],{"class":135,"line":840},[133,3716,668],{"class":279},[133,3718,1056],{"class":332},[133,3720,1059],{"class":283},[133,3722,1090],{"class":332},[133,3724,1093],{"class":332},[133,3726,3727],{"class":135,"line":846},[133,3728,687],{"emptyLinePlaceholder":686},[133,3730,3731],{"class":135,"line":852},[133,3732,3733],{"class":273},"# 4. SSH key + GitHub 443\n",[133,3735,3736,3738,3740,3742,3744],{"class":135,"line":858},[133,3737,1166],{"class":279},[133,3739,1169],{"class":283},[133,3741,1172],{"class":332},[133,3743,1175],{"class":283},[133,3745,3746],{"class":332}," \"邮箱\"\n",[133,3748,3749,3751,3754,3757,3759],{"class":135,"line":863},[133,3750,1201],{"class":279},[133,3752,3753],{"class":750}," >",[133,3755,3756],{"class":332}," ~\u002F.ssh\u002Fconfig",[133,3758,2177],{"class":750},[133,3760,2180],{"class":332},[133,3762,3763],{"class":135,"line":868},[133,3764,3765],{"class":332},"Host github.com\n",[133,3767,3768],{"class":135,"line":874},[133,3769,3770],{"class":332},"    Hostname ssh.github.com\n",[133,3772,3773],{"class":135,"line":3266},[133,3774,3775],{"class":332},"    Port 443\n",[133,3777,3778],{"class":135,"line":3289},[133,3779,3780],{"class":332},"    User git\n",[133,3782,3783],{"class":135,"line":3294},[133,3784,3785],{"class":332},"    IdentityFile ~\u002F.ssh\u002Fid_ed25519\n",[133,3787,3788],{"class":135,"line":3300},[133,3789,3790],{"class":332},"    IdentitiesOnly yes\n",[133,3792,3793],{"class":135,"line":3311},[133,3794,2195],{"class":332},[133,3796,3797,3799,3801],{"class":135,"line":3316},[133,3798,1314],{"class":279},[133,3800,1326],{"class":283},[133,3802,1455],{"class":332},[133,3804,3805],{"class":135,"line":3322},[133,3806,3807],{"class":273},"# 把 ~\u002F.ssh\u002Fid_ed25519.pub 加到 GitHub\n",[133,3809,3810,3812,3814],{"class":135,"line":3331},[133,3811,1409],{"class":279},[133,3813,1412],{"class":283},[133,3815,1415],{"class":332},[133,3817,3818],{"class":135,"line":3373},[133,3819,687],{"emptyLinePlaceholder":686},[133,3821,3822],{"class":135,"line":3392},[133,3823,3824],{"class":273},"# 5. nvm + Node\n",[133,3826,3827,3829,3831,3833,3835],{"class":135,"line":3408},[133,3828,576],{"class":279},[133,3830,1581],{"class":283},[133,3832,1584],{"class":332},[133,3834,1587],{"class":750},[133,3836,1590],{"class":279},[133,3838,3839,3841,3844,3846],{"class":135,"line":3425},[133,3840,2143],{"class":283},[133,3842,3843],{"class":332}," 'export NVM_NODEJS_ORG_MIRROR=https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode'",[133,3845,2149],{"class":750},[133,3847,2152],{"class":332},[133,3849,3850,3852],{"class":135,"line":3440},[133,3851,905],{"class":283},[133,3853,908],{"class":332},[133,3855,3856,3858,3860],{"class":135,"line":3446},[133,3857,1742],{"class":279},[133,3859,401],{"class":332},[133,3861,1756],{"class":283},[133,3863,3864,3866,3868,3870,3872],{"class":135,"line":3454},[133,3865,1742],{"class":279},[133,3867,1763],{"class":332},[133,3869,1766],{"class":332},[133,3871,1769],{"class":332},[133,3873,1028],{"class":283},[133,3875,3876],{"class":135,"line":3467},[133,3877,687],{"emptyLinePlaceholder":686},[133,3879,3880],{"class":135,"line":3475},[133,3881,3882],{"class":273},"# 6. npm 全局配置\n",[133,3884,3885,3887,3889,3891,3893],{"class":135,"line":3480},[133,3886,1831],{"class":279},[133,3888,1056],{"class":332},[133,3890,1876],{"class":332},[133,3892,1945],{"class":332},[133,3894,1124],{"class":283},[133,3896,3897,3899,3901,3903,3905],{"class":135,"line":3485},[133,3898,1831],{"class":279},[133,3900,1056],{"class":332},[133,3902,1876],{"class":332},[133,3904,1958],{"class":332},[133,3906,1124],{"class":283},[133,3908,3909],{"class":135,"line":3491},[133,3910,687],{"emptyLinePlaceholder":686},[133,3912,3913],{"class":135,"line":3505},[133,3914,3915],{"class":273},"# 7. uv (Python)\n",[133,3917,3918,3920,3922,3924,3926],{"class":135,"line":3513},[133,3919,576],{"class":279},[133,3921,2414],{"class":283},[133,3923,2417],{"class":332},[133,3925,1587],{"class":750},[133,3927,2422],{"class":279},[133,3929,3931,3933],{"class":135,"line":3930},46,[133,3932,2259],{"class":283},[133,3934,2152],{"class":332},[133,3936,3938,3940,3942,3944],{"class":135,"line":3937},47,[133,3939,2390],{"class":279},[133,3941,2570],{"class":332},[133,3943,401],{"class":332},[133,3945,3946],{"class":283}," 3.12\n",[18,3948,3949],{},"跑完上面这一坨，你的 WSL 开发环境就和我现在一样了。",[102,3951],{},[22,3953,3954],{"id":3954},"结语",[18,3956,3957,3958,3961],{},"WSL2 不是 Linux 的\"轻量替代品\"，而是 Windows 上",[180,3959,3960],{},"真正能用","的 Linux 开发环境。配好之后：",[174,3963,3964,3970,3976],{},[177,3965,3966,3969],{},[180,3967,3968],{},"编辑用 Windows","（VS Code 体验、字体、显示）",[177,3971,3972,3975],{},[180,3973,3974],{},"运行用 Linux","（命令行、容器、原生工具）",[177,3977,3978,3981],{},[180,3979,3980],{},"资源用 Hyper-V","（隔离、限制、快照）",[18,3983,3984],{},"第一次配会有不少坑，但只要把这份文档跟着走一遍，能少踩 90% 的坑。剩下 10% 是新版本的新坑（笑）。",[18,3986,3987,3988,205],{},"如果你的网络环境也有 Clash TUN + 火绒，强烈建议同时看我另一篇：",[950,3989,3991],{"href":3990},"\u002Fblog\u002Fwsl2-clash-huorong-troubleshooting","WSL2 + Clash TUN + 火绒的网络踩坑记录",[18,3993,3994,3995,205],{},"如果需要让 WSL 内的服务给局域网其他机器访问，看：",[950,3996,3998],{"href":3997},"\u002Fblog\u002Fwsl2-port-forwarding-guide","WSL2 端口转发完整指南",[4000,4001,4002],"style",{},"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 .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}",{"title":129,"searchDepth":148,"depth":148,"links":4004},[4005,4006,4013,4017,4026,4037,4054,4059,4064,4065,4067,4068],{"id":24,"depth":142,"text":24},{"id":106,"depth":142,"text":4007,"children":4008},"一、.wslconfig —— WSL2 全局配置",[4009,4010,4011,4012],{"id":122,"depth":148,"text":122},{"id":172,"depth":148,"text":172},{"id":236,"depth":148,"text":236},{"id":261,"depth":148,"text":261},{"id":300,"depth":142,"text":301,"children":4014},[4015,4016],{"id":304,"depth":148,"text":305},{"id":386,"depth":148,"text":387},{"id":546,"depth":142,"text":547,"children":4018},[4019,4020,4021,4022,4023,4024],{"id":556,"depth":148,"text":557},{"id":610,"depth":148,"text":611},{"id":652,"depth":148,"text":653},{"id":724,"depth":148,"text":725},{"id":921,"depth":148,"text":922},{"id":963,"depth":148,"text":4025},"3.6 常见踩坑：compinit 报错",{"id":1039,"depth":142,"text":1040,"children":4027},[4028,4029,4034,4035,4036],{"id":1043,"depth":148,"text":1044},{"id":1150,"depth":148,"text":1151,"children":4030},[4031,4032,4033],{"id":1155,"depth":154,"text":1156},{"id":1212,"depth":154,"text":1213},{"id":1363,"depth":154,"text":1364},{"id":1395,"depth":148,"text":1396},{"id":1479,"depth":148,"text":1480},{"id":1528,"depth":148,"text":1529},{"id":1564,"depth":142,"text":1565,"children":4038},[4039,4040,4041,4042,4050,4052,4053],{"id":1568,"depth":148,"text":1569},{"id":1692,"depth":148,"text":1693},{"id":1784,"depth":148,"text":1785},{"id":1916,"depth":148,"text":4043,"children":4044},"5.4 .npmrc 配置最佳实践",[4045,4047,4049],{"id":1924,"depth":154,"text":4046},"用户级 ~\u002F.npmrc（一次配，全局生效）",{"id":1973,"depth":154,"text":4048},"项目级 .npmrc（commit 到 git，团队共享）",{"id":2011,"depth":154,"text":2012},{"id":2055,"depth":148,"text":4051},"5.5 npm 安装报 EPIPE 怎么办",{"id":2198,"depth":148,"text":2199},{"id":2305,"depth":148,"text":2306},{"id":2384,"depth":142,"text":2385,"children":4055},[4056,4057,4058],{"id":2401,"depth":148,"text":2402},{"id":2438,"depth":148,"text":2439},{"id":2557,"depth":148,"text":2558},{"id":2638,"depth":142,"text":2639,"children":4060},[4061,4062,4063],{"id":2642,"depth":148,"text":2643},{"id":2718,"depth":148,"text":2719},{"id":2750,"depth":148,"text":2751},{"id":2841,"depth":142,"text":2842},{"id":3049,"depth":142,"text":4066},"九、~\u002F.zshrc 完整参考",{"id":3523,"depth":142,"text":3524},{"id":3954,"depth":142,"text":3954},"devops","2026-05-27","从安装发行版到搭好可用的前端开发环境，涵盖磁盘迁移、镜像加速、终端配置与常见初始化陷阱。",false,"md",{},"\u002Fblog\u002Fwsl2-setup-guide",{"title":5,"description":4071},null,"blog\u002Fwsl2-setup-guide",[4080,4081,4082,4083],"wsl2","linux","windows","guide","u45uFn9WTYfbMBZS-YCLd2tWjdAluODI0hSZH0DoTlU",{"prev":4086,"next":4077},{"path":3997,"title":3998,"description":4087},"WSL2 里跑起 dev server 本机能开、同事却访问不到？讲透 NAT 网络拓扑、portproxy 方案、防火墙放行与开机自动化脚本。",1788337377921]