[{"data":1,"prerenderedAt":987},["ShallowReactive",2],{"blog-\u002Fblog\u002Fnvm-pnpm-notes":3,"blog-siblings-\u002Fblog\u002Fnvm-pnpm-notes":982},{"id":4,"title":5,"body":6,"category":965,"date":966,"description":967,"draft":968,"extension":969,"meta":970,"navigation":971,"path":972,"seo":973,"source":974,"stem":975,"tags":976,"__hash__":981},"blog\u002Fblog\u002Fnvm-pnpm-notes.md","nvm 版本管理与 pnpm 对比笔记",{"type":7,"value":8,"toc":956},"minimark",[9,14,23,27,34,63,89,109,190,195,209,214,217,222,226,230,253,267,270,288,299,304,324,408,413,428,431,438,464,468,497,501,510,552,555,558,621,627,644,649,716,719,723,772,777,952],[10,11,13],"h1",{"id":12},"nvm-版本管理","nvm 版本管理",[15,16,18,22],"h2",{"id":17},"nvm-list-available-查看版本为空",[19,20,21],"code",{},"nvm list available"," 查看版本为空",[24,25,26],"p",{},"解决办法：",[28,29,30],"ul",{},[31,32,33],"li",{},"查看配置的镜像地址",[35,36,41],"pre",{"className":37,"code":38,"language":39,"meta":40,"style":40},"language-shell shiki shiki-themes github-light github-dark","$    npm config get registry\nhttps:\u002F\u002Fregistry.npmmirror.com\u002F\n\u002F\u002F 已经配置了镜像地址\n","shell","",[19,42,43,51,57],{"__ignoreMap":40},[44,45,48],"span",{"class":46,"line":47},"line",1,[44,49,50],{},"$    npm config get registry\n",[44,52,54],{"class":46,"line":53},2,[44,55,56],{},"https:\u002F\u002Fregistry.npmmirror.com\u002F\n",[44,58,60],{"class":46,"line":59},3,[44,61,62],{},"\u002F\u002F 已经配置了镜像地址\n",[28,64,65,71,77,82],{},[31,66,67],{},[68,69],"img",{"alt":40,"src":70},"\u002Fimages\u002Fb-tools\u002F2024-07-13-20-40-29-image.png",[31,72,73,76],{},[19,74,75],{},"npm config list","，查看目录",[31,78,79],{},[68,80],{"alt":40,"src":81},"\u002Fimages\u002Fb-tools\u002F71251598d3d915ad7536f8aaf185f23cf56cdeeb.png",[31,83,84,85,88],{},"找到",[19,86,87],{},".npmrc","文件，并进入修改",[35,90,92],{"className":37,"code":91,"language":39,"meta":40,"style":40},"输入：\nhome=https:\u002F\u002Fnpmmirror.com\nregistry=https:\u002F\u002Fregistry.npmmirror.com\u002F\n",[19,93,94,99,104],{"__ignoreMap":40},[44,95,96],{"class":46,"line":47},[44,97,98],{},"输入：\n",[44,100,101],{"class":46,"line":53},[44,102,103],{},"home=https:\u002F\u002Fnpmmirror.com\n",[44,105,106],{"class":46,"line":59},[44,107,108],{},"registry=https:\u002F\u002Fregistry.npmmirror.com\u002F\n",[28,110,111,116,119,124,137],{},[31,112,113],{},[68,114],{"alt":40,"src":115},"\u002Fimages\u002Fb-tools\u002F09aa738b0f5bc60195246f96e9cd73210d821e9c.png",[31,117,118],{},"再次查看，修改成功",[31,120,121],{},[68,122],{"alt":40,"src":123},"\u002Fimages\u002Fb-tools\u002Fad01032e5165f07bb427ef759734f8001a6d0c59.png",[31,125,84,126,129,130,133,134],{},[19,127,128],{},"nvm","安装路径，打开 ",[19,131,132],{},"setting.txt"," 文件。没有则创建一下",[68,135],{"alt":40,"src":136},"\u002Fimages\u002Fb-tools\u002Faf215104aa59abc8f572f51a48398cfe23fac0d3.png",[31,138,139,140,142,143,146,147,150,151],{},"修改完",[19,141,132],{},"文件的镜像配置即可，设置 ",[19,144,145],{},"node_mirror"," 和 ",[19,148,149],{},"npm_mirror","为：",[35,152,156],{"className":153,"code":154,"language":155,"meta":40,"style":40},"language-js shiki shiki-themes github-light github-dark","node_mirror: https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\u002F\nnpm_mirror: https:\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnpm\u002F\n","js",[19,157,158,177],{"__ignoreMap":40},[44,159,160,163,167,170,173],{"class":46,"line":47},[44,161,145],{"class":162},"sScJk",[44,164,166],{"class":165},"sVt8B",": ",[44,168,169],{"class":162},"https",[44,171,172],{"class":165},":",[44,174,176],{"class":175},"sJ8bj","\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnode\u002F\n",[44,178,179,181,183,185,187],{"class":46,"line":53},[44,180,149],{"class":162},[44,182,166],{"class":165},[44,184,169],{"class":162},[44,186,172],{"class":165},[44,188,189],{"class":175},"\u002F\u002Fnpmmirror.com\u002Fmirrors\u002Fnpm\u002F\n",[24,191,192],{},[68,193],{"alt":40,"src":194},"\u002Fimages\u002Fb-tools\u002Fefcf2e0efee939e38357c0d94230b0d417b0a874.png",[24,196,197,205,206,208],{},[198,199,200,201,204],"strong",{},"查看可安装的 ",[19,202,203],{},"node"," 版本"," ，",[19,207,21],{}," 即可看到可安装版本信息",[24,210,211],{},[68,212],{"alt":40,"src":213},"\u002Fimages\u002Fb-tools\u002Fad88662d80955421b8e77de696c5a9033250273c.png",[24,215,216],{},"安装使用 14版本的node成功",[24,218,219],{},[68,220],{"alt":40,"src":221},"\u002Fimages\u002Fb-tools\u002F2024-07-13-20-57-59-image.png",[10,223,225],{"id":224},"pnpm-vs-npm","pnpm vs npm",[15,227,229],{"id":228},"npm-的平铺目录结构","npm 的平铺目录结构",[28,231,232,244],{},[31,233,234,235,239,240,243],{},"从 npm v3 开始，npm 使用",[236,237,238],"em",{},"平铺的依赖结构","。 这可以减少磁盘空间占用， 但却导致 ",[19,241,242],{},"node_modules"," 目录的混乱。",[31,245,246,247,249,250,252],{},"pnpm 通过使用硬链接和符号链接到全局磁盘内容可寻址存储来管理 ",[19,248,242],{},"。 带来减少磁盘空间使用的好处，同时还保持您的 ",[19,251,242],{}," 是干净的。",[24,254,255,256,258,259,262,263,266],{},"pnpm 正确的 ",[19,257,242],{}," 结构的好处在于，它",[236,260,261],{},"有助于避免愚蠢的错误","，因为它让你无法使用不是 ",[19,264,265],{},"package.json"," 中指定的模块。",[15,268,269],{"id":269},"安装",[24,271,272,273,275,276,279,280,283,284,287],{},"pnpm 不允许安装 ",[19,274,265],{}," 中没有包含的包。 如果没有参数传递给 ",[19,277,278],{},"pnpm add","，包将保存为常规依赖项。 与 npm 一样， ",[19,281,282],{},"--save-dev"," 和 ",[19,285,286],{},"--save-optional"," 可以是用于安装包作为开发或可选的依赖。",[24,289,290,291,298],{},"由于此限制，项目在使用 pnpm 时不会有任何无关的包，除非它们删除依赖项并将其保留为孤立的。 这就是为什么 pnpm 的实现的 ",[292,293,297],"a",{"href":294,"rel":295},"https:\u002F\u002Fwww.bookstack.cn\u002Fread\u002Fpnpm-8-zh\u002Fb9d1169af3b94232.md",[296],"nofollow","prune command"," 不允许你指定包来修剪 - 它总是去除所有多余的和孤儿包。",[24,300,301],{},[198,302,303],{},"安装 pnpm",[35,305,307],{"className":37,"code":306,"language":39,"meta":40,"style":40},"npm install -g pnpm\n或者\nnpm install -g @pnpm\u002Fexe\n",[19,308,309,314,319],{"__ignoreMap":40},[44,310,311],{"class":46,"line":47},[44,312,313],{},"npm install -g pnpm\n",[44,315,316],{"class":46,"line":53},[44,317,318],{},"或者\n",[44,320,321],{"class":46,"line":59},[44,322,323],{},"npm install -g @pnpm\u002Fexe\n",[325,326,327,349],"table",{},[328,329,330],"thead",{},[331,332,333,337,340,343,346],"tr",{},[334,335,336],"th",{},"Node.js",[334,338,339],{},"pnpm5",[334,341,342],{},"pnpm6",[334,344,345],{},"pnpm7",[334,347,348],{},"pnpm8",[350,351,352,368,381,395],"tbody",{},[331,353,354,358,361,363,366],{},[355,356,357],"td",{},"node V12",[355,359,360],{},"√",[355,362,360],{},[355,364,365],{},"×",[355,367,365],{},[331,369,370,373,375,377,379],{},[355,371,372],{},"node V14",[355,374,360],{},[355,376,360],{},[355,378,360],{},[355,380,365],{},[331,382,383,386,389,391,393],{},[355,384,385],{},"node V16",[355,387,388],{},"未知",[355,390,360],{},[355,392,360],{},[355,394,360],{},[331,396,397,400,402,404,406],{},[355,398,399],{},"node V18",[355,401,388],{},[355,403,360],{},[355,405,360],{},[355,407,360],{},[24,409,410],{},[198,411,412],{},"查看安装位置",[35,414,416],{"className":37,"code":415,"language":39,"meta":40,"style":40},"使用 Git Bash 查看\n $ which pnpm\n",[19,417,418,423],{"__ignoreMap":40},[44,419,420],{"class":46,"line":47},[44,421,422],{},"使用 Git Bash 查看\n",[44,424,425],{"class":46,"line":53},[44,426,427],{}," $ which pnpm\n",[15,429,430],{"id":430},"目录依赖",[24,432,433,434,437],{},"目录依赖以 ",[19,435,436],{},"file:"," 前缀开始，指向文件系统的目录。 与 npm 一样，pnpm 符号链接这些依赖项。 与 npm 不同的是，pnpm 不执行这些文件依赖项的安装。",[24,439,440,441,444,445,448,449,452,453,455,456,459,460,463],{},"这意味着如果您有一个名为 ",[19,442,443],{},"foo"," (",[19,446,447],{},"\u003Croot>\u002Ffoo",") 的包，它有 ",[19,450,451],{},"bar@file:..\u002Fbar"," 作为依赖项，则当你在 ",[19,454,443],{}," 上执行 ",[19,457,458],{},"pnpm install"," 时， pnpm 将不会为 ",[19,461,462],{},"\u003Croot>\u002Fbar"," 安装。",[10,465,467],{"id":466},"pnpm的局限","PNPM的局限",[469,470,471,487],"ol",{},[31,472,473,283,476,479,480,483,484,486],{},[19,474,475],{},"npm-shrinkwrap.json",[19,477,478],{},"package-lock.json"," 被忽略。 与 pnpm 不同，npm可以多次安装相同的 ",[19,481,482],{},"name@version"," ，并且具有不同的依赖项组合。 npm 的锁文件旨在反映平铺的 ",[19,485,242],{}," 布局，但是，由于 pnpm 默认创建隔离布局，它无法由 npm 的锁文件格式反映出来。",[31,488,489,490,493,494,496],{},"Binstubs（在 ",[19,491,492],{},"node_modules\u002F.bin","中的文件）总是 shell 文件，而不是指向 JS 文件的符号链接。 创建 shell 文件是为了帮助支持插件的 CLI 的程序在特殊的 ",[19,495,242],{}," 结构中能够正确地找到它们的插件。 这是很少有的问题，如果您希望文件是 JS 文件，请直接引用原始文件",[10,498,500],{"id":499},"pnpm-add-和-install","pnpm add 和 install",[24,502,503,506,507,509],{},[19,504,505],{},"pnpm add ","和",[19,508,458],{},"命令的本质是相同的，都可以用来安装依赖包。它们的区别在于用法和语法。",[28,511,512,538,546],{},[31,513,514,516,517,506,520,523,524,526,527,530,531,534,535,537],{},[19,515,278],{},"会将安装的",[236,518,519],{},"包名",[236,521,522],{},"版本号","添加到",[19,525,265],{},"文件的",[19,528,529],{},"dependencies","或",[19,532,533],{},"devDenpendencies","中，",[19,536,458],{},"不会",[31,539,540,542,543],{},[19,541,278],{},"支持一次性安装多个包。eg:",[19,544,545],{},"pnpm add package0 package1 package……",[31,547,548,551],{},[19,549,550],{},"install"," 用来安装项目的全部依赖",[15,553,278],{"id":554},"pnpm-add",[24,556,557],{},"安装软件包以及其依赖的任何软件包。 默认情况下，任何新添加的软件包都将作为生产依赖项。",[325,559,560,571],{},[328,561,562],{},[331,563,564,568],{},[334,565,567],{"align":566},"center","命令",[334,569,570],{"align":566},"用法",[350,572,573,581,589,597,605,613],{},[331,574,575,578],{},[355,576,577],{"align":566},"pnpm add sax",[355,579,580],{"align":566},"保存到dependencies",[331,582,583,586],{},[355,584,585],{"align":566},"pnpm add -D sax",[355,587,588],{"align":566},"保存到devDependencies",[331,590,591,594],{},[355,592,593],{"align":566},"pnpm add -O sax",[355,595,596],{"align":566},"保存到optionalDependencies",[331,598,599,602],{},[355,600,601],{"align":566},"pnpm add -g sax",[355,603,604],{"align":566},"安装到全局",[331,606,607,610],{},[355,608,609],{"align":566},"pnpm add sax@next",[355,611,612],{"align":566},"安装标记为 next 的版本",[331,614,615,618],{},[355,616,617],{"align":566},"pnpm add sax@3.1.0",[355,619,620],{"align":566},"安装指定版本 3.1.0",[24,622,623,626],{},[19,624,625],{},"add","命令的来源：",[28,628,629,632,635,638,641],{},[31,630,631],{},"npm 源",[31,633,634],{},"workspace内",[31,636,637],{},"本地文件",[31,639,640],{},"从远端tar包安装",[31,642,643],{},"从git安装",[24,645,646,648],{},[19,647,625],{},"命令支持的参数：",[28,650,651,661,670,679,688,694,700,710],{},[31,652,653,656,657,660],{},[19,654,655],{},"–save-prod",", ",[19,658,659],{},"-P","：安装到dependencies",[31,662,663,656,666,669],{},[19,664,665],{},"–save-dev",[19,667,668],{},"-D","：安装到devDependencies",[31,671,672,656,675,678],{},[19,673,674],{},"–save-optional",[19,676,677],{},"-O","：安装到optionalDependencies",[31,680,681,656,684,687],{},[19,682,683],{},"–save-exact",[19,685,686],{},"-E","：保存的版本号会是一个具体的值，相当于锁死版本",[31,689,690,693],{},[19,691,692],{},"–save-peer","：安装到peerDependencies和devDependencies中",[31,695,696,699],{},[19,697,698],{},"–ignore-workspace-root-check","：允许在项目根目录添加依赖包",[31,701,702,705,706,709],{},[19,703,704],{},"–global","，",[19,707,708],{},"-g","：安装到全局",[31,711,712,715],{},[19,713,714],{},"–workspace","：仅添加在 workspace 内找到的依赖项",[15,717,458],{"id":718},"pnpm-install",[24,720,721,551],{},[19,722,550],{},[325,724,725,735],{},[328,726,727],{},[331,728,729,732],{},[334,730,731],{},"Command 命令",[334,733,734],{},"Meaning 意义",[350,736,737,747,760],{},[331,738,739,744],{},[355,740,741],{},[19,742,743],{},"pnpm i --offline",[355,745,746],{},"使用本地缓存离线安装",[331,748,749,754],{},[355,750,751],{},[19,752,753],{},"pnpm i --frozen-lockfile",[355,755,756,759],{},[19,757,758],{},"pnpm-lock.yaml"," is not updated",[331,761,762,767],{},[355,763,764],{},[19,765,766],{},"pnpm i --lockfile-only",[355,768,769,770],{},"只更新",[19,771,758],{},[24,773,774,776],{},[19,775,550],{},"支持的参数：",[28,778,779,785,799,809,840,854,860,866,872,883,940,946],{},[31,780,781,784],{},[19,782,783],{},"–force","：强制重新安装依赖。",[31,786,787,790,791,794,795,798],{},[19,788,789],{},"–offline","： 默认值：",[19,792,793],{},"false","。如果设置了",[19,796,797],{},"--offline","参数，pnpm会只使用本地缓存的包，如果本地没有找到某个包，最终安装就会失败。可以理解为离线模式。",[31,800,801,804,805,808],{},[19,802,803],{},"–prefer-offline","：默认值：false。如果设置了",[19,806,807],{},"--prefer-offline","参数，本地没有的包会从远端安装，其他会优先使用本地缓存的包。",[31,810,811,814,815,817,818,821,822,825,826,829,830,833,834],{},[19,812,813],{},"–prod",",",[19,816,659],{},"：如果环境变量中",[19,819,820],{},"NODE_ENV","被设置为",[19,823,824],{},"production","，那么pnpm不会安装任何属于",[19,827,828],{},"devDependencies","的包，如果有相关的包已经被安装了，则会",[236,831,832],{},"清除","这些包。",[198,835,836,837,839],{},"使用这个指令pnpm会忽略",[19,838,820],{},"，强制pnpm以production的方式执行install命令。",[31,841,842,814,845,847,848,850,851],{},[19,843,844],{},"–dev",[19,846,668],{},"：仅安装",[19,849,828],{},"并",[236,852,853],{},"删除已安装的dependencies。",[31,855,856,859],{},[19,857,858],{},"–no-optional","：不安装optionalDependencies依赖。",[31,861,862,865],{},[19,863,864],{},"–lockfile-only","：使用时，只更新 pnpm-lock.yaml 和 package.json。 不写入 node_modules 目录。",[31,867,868,871],{},[19,869,870],{},"–fix-lockfile","：自动修复损坏的lock文件入口。",[31,873,874,877,878],{},[19,875,876],{},"–frozen-lockfile","：默认值：非 CI: false。CI: true, 如果存在 lock 文件",[28,879,880],{},[31,881,882],{},"如果设置 true， pnpm 不会生成 lockfile，而且如果 lockfile是偏旧或不存在lockfile则会安装失败.",[31,884,885,888,889,705,892,895,896],{},[19,886,887],{},"–reporter=name","：默认值：",[19,890,891],{},"TTY stdout: default",[19,893,894],{},"非 TTY stdout: append-only"," 允许您选择将调试信息记录到终端, 以了解安装进度.",[28,897,898,904,914,920,926],{},[31,899,900,903],{},[19,901,902],{},"silent ","- 控制台不展示任何信息",[31,905,906,909,910,913],{},[19,907,908],{},"default "," - ",[198,911,912],{},"TTY","的默认输出",[31,915,916,919],{},[19,917,918],{},"append-only"," - 始终向末尾追加输出",[31,921,922,925],{},[19,923,924],{},"ndjson ","- 打印所有ndjson格式日志，最详细的版本",[31,927,928,931,932,939],{},[19,929,930],{},"–use-store-server","：通过本地的store服务安装，安装完成后store服务不会自动关闭，",[236,933,934,935,938],{},"需要使用",[19,936,937],{},"pnpm server stop","停止","。",[31,941,942,945],{},[19,943,944],{},"–shamefully-hoist","：创建一个扁平化node_modules目录结构, 类似于npm 或 yarn。不推荐使用，可能会导致未知问题。",[31,947,948,951],{},[19,949,950],{},"–ignore-scripts","：不执行任何项目中package.json以及依赖内定义的任何脚本。",[953,954,955],"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 .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":40,"searchDepth":59,"depth":59,"links":957},[958,960,961,962,963,964],{"id":17,"depth":53,"text":959},"nvm list available 查看版本为空",{"id":228,"depth":53,"text":229},{"id":269,"depth":53,"text":269},{"id":430,"depth":53,"text":430},{"id":554,"depth":53,"text":278},{"id":718,"depth":53,"text":458},"devops","2024-07-13","解决 nvm list available 返回空的镜像配置问题，并对比 pnpm 与 npm 在依赖存储与安装速度上的差异。",false,"md",{},true,"\u002Fblog\u002Fnvm-pnpm-notes",{"title":5,"description":967},null,"blog\u002Fnvm-pnpm-notes",[128,977,978,979,980],"npm","pnpm","nodejs","troubleshooting","j4nADtHRQxLb1lf8WhudxX7AI9nClm89gVYN5GqpiMw",{"prev":974,"next":983},{"path":984,"title":985,"description":986},"\u002Fblog\u002Fvue-reactivity-principle","Vue 响应式原理源码解析","从 Vue 初始化流程切入，逐层剖析 initState 如何将 props 与 data 转为响应式，讲清依赖收集与派发更新的完整链路。",1788337377923]