Windows下npm全局安装目录配置与PATH环境变量实战指南
搞 Windows 前端开发的人多半都听过、甚至被 npm 的全局安装目录坑过。很多新手第一次执行npm install -g create-react-app之后发现命令死活不能用最后才意识到是 npm 全局安装目录没有加入系统环境变量。这类问题说大不大说小不小却能卡住大半天的排查时间。今天这篇专门围绕 Windows 系统中 npm 的全局安装目录展开把默认位置、查看方式、修改方案、权限坑、以及它对你日常命令行的实际影响一次性讲清楚。适合刚接触 Node.js 的初学者适合需要在多台 Windows 机器统一环境的开发者也适合团队里负责初始化前端环境的同学。1. 先搞明白npm 全局安装目录到底是什么1.1 全局安装和本地安装的根本区别npm 安装依赖有两种姿势本地安装和全局安装。本地安装是npm install 包名它会把文件放到当前项目目录下的node_modules文件夹里随后写入当前项目的package.json。全局安装是npm install 包名 -g它会把包放到的不是项目目录而是一个专门留给 npm 的全局目录然后根据包里面声明的可执行文件在这个全局目录下生成对应的命令入口。很多人不理解为什么要区分这两种方式。本地安装的包更像是“项目自带的工具箱”只在当前工程里有效别人 Clone 项目后执行npm install就能复原全局安装的包则像是“公共工具房”只要这台机器上配置好了任何时候在命令行都能直接用不需要进到某个特定项目。全局工具常见的场景是脚手架、命令行辅助工具、linter、构建工具例如create-vite、vue/cli、typescript、eslint、nodemon等等。但全局安装有个关键点npm 只是把文件放进全局目录并不会自动帮你把命令“注册”到系统里。Windows 在命令行中查找可执行程序时只会去当前目录和环境变量PATH里列出的目录里搜索。如果你的 npm 全局安装目录不在PATH中哪怕包装得再干净命令也照样提示“不是内部或外部命令”。1.2 Windows 上的默认位置和 prefix 机制在 Windows 上如果你是用官方安装包安装的 Node.jsnpm 的全局安装目录默认是C:\Users\你的用户名\AppData\Roaming\npm。这个AppData\Roaming是 Windows 用来存放应用程序数据的标准目录通常和用户配置文件放一起。在这个目录下你还能看到node_modules子文件夹它里面才是真正下载的全局依赖包。npm 生成的可执行命令入口例如.cmd、.ps1和 shell 脚本则会直接放在C:\Users\你的用户名\AppData\Roaming\npm这个根目录下。也就是说这个目录既承担了“全局包存放目录”的角色也承担了“命令入口目录”的角色。控制这个位置的核心参数叫prefix。它由 npm 配置文件.npmrc控制不同项目、不同用户、甚至不同包的安装方式都可能读到不同的 prefix。想快速确认当前实际使用的全局目录可以执行下面两条命令npm config get prefix npm root -g其中npm config get prefix返回的是 npm 全局目录的顶层路径npm root -g返回的是该目录下node_modules的完整路径。在默认设置下前者大概是C:\Users\你\AppData\Roaming\npm后者则是C:\Users\你\AppData\Roaming\npm\node_modules。初看会有点绕但记住一层关系就好npm root -g一定是npm config get prefix再加上node_modules。2. 怎么查、怎么改必备命令与配置流程2.1 查看当前全局目录四组命令组合判断很多专业教程只叫你敲一条命令实际排查时却需要多角度确认因为环境变量和 npm 配置是两个层面稍不留神就会出现“某个命令能查到另一个命令又指向别处”的错觉。我建议养成组合使用命令的习惯。第一组是看 npm 自己的配置输入npm config get prefix拿到的是理论上的全局安装根目录。第二组是看实际模块目录输入npm root -g拿到的是全局依赖的node_modules完整路径。第三组是看已经安装了什么包输入npm ls -g --depth0它会列出当前全局顶层包名和版本适合确认迁移前后状态。第四组是直接看这个目录是否在环境变量里在 CMD 中输入echo %PATH%或者在 PowerShell 中输入echo $env:Path然后在里面找有没有 npm 全局目录对应的字符串。这四组命令各盯一个层面结合起来才能定位问题出在“npm 配置没改”还是“环境变量没配置”还是“包根本没装上”。比如npm ls -g --depth0里能看到create-vite但命令行输入create-vite报“命令不存在”那多半就是 PATH 缺失而不是安装失败。2.2 修改全局安装目录的两种方案知道了默认位置接下来就是怎么改。Windows 上最常见的场景是用户不想让 npm 把全局包塞进C:\Users\xxx\AppData\Roaming觉得这占系统盘空间、不好清理或者公司电脑的用户目录有同步策略容易引发权限问题。于是大家想把全局目录换到其他盘符。方案一继续沿用默认位置但只做规范化管理。这种做法适合没有强烈迁移需求的人只需保证目录加入 PATH同时定期用npm cache clean或删除node_modules下不用的包即可。优点是不需要额外配置缺点是没有解决 C 盘空间问题多版本 Node 切换时也容易留下杂乱的旧包。方案二自定义全局目录例如D:\nodejs\npm-global或D:\npm。需要修改prefix配置并把新目录加入环境变量PATH。我推荐把目录放在数据盘或独立分区。注意不要直接修改C:\Program Files\nodejs下的默认 prefix那样通常需要管理员权限还会提高后续误操作的风险。自定义目录的好处是彻底摆脱系统盘限制也方便统一迁移和清理。3. 实操演示把全局目录迁到自定义位置3.1 迁移前规划和现有包备份迁移全局目录并不是简单修改一个配置就行。最稳妥的做法是先记录现状再动刀。打开终端执行npm ls -g --depth0把输出的包名和版本保存到一个文本文件里。我习惯把这份列表直接存到项目仓库或者自己的运维笔记中这样后续重新安装时不会漏包。接着确认旧全局目录路径执行npm config get prefix和npm root -g。如果机器里还装了其他 Node 版本管理器例如最常见的多版本管理工具需要额外注意这类工具会在切换 Node 版本时自动改变当前环境里的 Node 路径但不会自动同步 npm 的 prefix 配置迁移前要把这一点想清楚。最后再检查一下当前终端有没有正在使用全局包最好先把正在跑的构建服务或命令行工具停掉。迁移过程中如果旧 global 目录里的文件正被占用Windows 会报“另一个程序正在使用此文件”。3.2 一步步迁移新建目录、改 prefix、配 PATH整个迁移可以拆成几个动作。第一步在目标盘符下创建目录例如mkdir D:\nodejs\npm-global如果目录不存在npm 后续安装时不一定能自动创建所以提前手动建好更稳妥。第二步修改 npm 的全局 prefix 配置npm config set prefix D:\nodejs\npm-global可以通过npm config get prefix确认返回值已经是新目录。需要注意的是这一步只影响之后安装的全局包旧目录里的文件不会自动搬过去所以迁移后需要重新安装全局依赖。第三步把新目录写入用户环境变量 PATH。这里我强烈建议不要直接使用setx PATH %PATH%;D:\nodejs\npm-global因为%PATH%会展开成系统变量和用户变量的合并值再回写给用户 PATH既可能造成变量重复也可能因为字符长度限制截断内容导致系统命令失灵。推荐用 PowerShell 的方式只往用户 PATH 后面追加[Environment]::SetEnvironmentVariable(Path, $env:Path ;D:\nodejs\npm-global, User)如果希望立即在当前终端生效还需要刷新当前会话的环境变量最简单的办法是重开一个终端窗口。之后在 CMD 或 PowerShell 里执行where 包名或者Get-Command 包名确认新命令能被找到。第四步按照第一步里备份的包列表重新执行全局安装。例如npm install -g typescript eslint prettier装完之后用npm ls -g --depth0对照备份列表确认没有遗漏。一切正常后再动手删除旧目录C:\Users\你\AppData\Roaming\npm。删除时注意保留AppData\Roaming本身不要手滑删错到用户配置目录。3.3 权限问题和管理员模式的那些坑Windows 上安装全局包最常见的问题之一就是权限错误报错信息里经常出现EPERM、EACCES、ENOTEMPTY。很多人的第一反应是用管理员身份打开终端重试一次。这样做确实能“压制”部分报错但也会带来两个隐患一是某些全局包在安装时会写入缓存或生命周期脚本长期使用管理员权限会留下权限残留二是后续如果不用管理员身份运行又出现同样问题等于没解决根因。我的建议是尽量把 npm 全局目录放在用户有完全控制权的路径下而不是放在C:\Program Files这类系统目录。用户目录和独立数据盘目录通常不需要管理员权限安装时会省掉很多麻烦。如果报错来自旧目录正在被占用或权限继承混乱可以先用icacls检查目录权限而不是一味爆改管理员模式。4. 常见问题排查实录全局命令失效与目录异常4.1 问题速查表我把这几年遇到的高频问题整理成一张速查表方便大家按症状定位。症状可能原因解决思路刚全局安装完命令提示“不是内部或外部命令”全局目录不在 PATH 环境变量中把 prefix 目录追加到用户 PATH重开终端npm ls -g --depth0里看得到包但命令找不到PATH 目录和 npm prefix 目录不一致用npm config get prefix对比 PATH 里的路径安装时报EPERM、EACCES目录权限不足或被杀毒软件锁定检查用户权限避免使用 Program Files 目录全局包占满 C 盘空间prefix 是默认的 AppData 目录按第 3 节步骤迁移到其他磁盘修改 prefix 后原有全局命令全部失效旧目录中的包未重新安装用npm ls -g --depth0备份后重新安装切换 Node 版本后全局命令找不到npm prefix 未被新版本同步重新检查前缀配置必要时重新安装全局包安装时进度条卡住随后报ENOTCACHEDnpm 缓存目录异常或权限问题清理缓存npm cache verify后重试4.2 排查思路从 PATH 开始查起不管问题描述得多么花哨全局命令失效的大概率根因都出在 PATH 上。先说排查顺序。第一步确认 npm 知道的全局目录是什么执行npm config get prefix。第二步确认命令解释器在哪些目录里找可执行文件执行$env:Path。第三步看目标全局目录是否在 PATH 列表里注意检查有没有中英文路径、大小写问题。第四步确认新开的终端确实加载了最新的环境变量。Windows 上修改 PATH 后已经打开的 CMD、PowerShell、VS Code 终端不会自动刷新必须重开终端。这个坑我踩过不止三次经常改完配置后因为没重开终端而怀疑自己操作错了。另外还要注意用户 PATH 和系统 PATH 的合并顺序。Windows 默认先执行系统 PATH再执行用户 PATH。如果两个 PATH 里出现了同名的可执行文件前面的会覆盖后面的。企业电脑经常会在系统 PATH 里预置一个老版本 Node用户 PATH 里装了新版本就会导致命令行里node -v和安装的版本对不上这类问题没法改 npm 全局目录解决要去调整两条 PATH 的顺序。4.3 我踩过的坑npmrc 残留配置有一次我帮同事迁移全局目录明明已经执行了npm config set prefix再次npm config get prefix也显示新目录但是全局安装还是装到了旧位置。后来才查出来他的用户目录下有个.npmrc文件里面手工写着一行旧 prefix 配置。npm 配置有层级项目级.npmrc、用户级.npmrc、全局.npmrc、内置配置优先级不同用户级文件里的旧配置会把新设置顶掉。解决办法是检查配置来源执行npm config list这个命令会列出所有生效配置并且标注每一条来自哪个配置文件。如果发现旧 prefix 还在再打开用户级配置文件看看npm config edit删掉里面的旧prefix行再保存。这个教训说明排查全局目录问题不能只看当前值还要搞清楚是谁设置了它。4.4 避坑技巧环境变量里用变量名还是绝对路径有人喜欢在 PATH 里写%APPDATA%\npm这实际上是动态展开到当前用户的 AppData 目录。好处是当用户名变更或者系统盘迁移时不用继续调整坏处是如果你想迁移到自定义目录%APPDATA%本身还在 C 盘达不到换盘目的。自定义目录则建议在 PATH 里直接写绝对路径例如D:\nodejs\npm-global。绝对路径更直观也方便其他人接手排查。不过要注意如果机器不止一个用户账户用%APPDATA%会让每个用户都有自己的一套全局目录全局工具互不相同。团队统一环境时我更倾向于让大家都配同一个固定目录比如D:\npm-global前提是这台机器只有开发者自己使用否则可能碰到多用户权限问题。5. 全局安装目录背后的影响范围5.1 对前端工具链的实际影响很多人意识不到npm 全局安装目录不仅是一个“存放位置”它还直接决定了你命令行的习惯、工具链版本和项目启动方式。如果你习惯全局安装typescript、eslint、webpack那么当全局包版本和项目依赖版本不一致时命令行执行的结果就可能和项目预期效果不同甚至出现“在我电脑上明明是好的”的经典问题。这也是为什么新项目越来越多地推荐用npx而不是把构建工具安装到全局目录。全局目录对脚手架类工具的影响更明显。比如create-vite、vue/cli这类命令它们会在全局目录生成可执行入口。如果多个全局包共享同一目录且版本发生过升级旧项目脚手架可能会意外用到新全局版本导致模板结构不符合预期。这时候最干净的解决办法是把全局目录里的旧包卸载只保留与当前工作匹配的版本。5.2 对团队协作和 CI/CD 的影响团队协作中全局安装目录最大的问题是不确定性。成员 A 的全局目录默认在C:\Users\A\AppData\Roaming\npm成员 B 手动改到D:\npm虽然不影响他们各自跑命令但交流时会发现“你安装的这个命令我没法直接用”。再加上 Windows 的差异通常需要额外指导同事配置 PATH无形中增加了很多沟通成本。我建议团队建立一个约定能用项目本地依赖解决的绝不全局安装必须以全局方式提供的工具统一约定 prefix 路径和环境变量格式。比如在开发环境初始化文档里写明“所有全局工具请安装在 D 盘 npm-global 目录”并附上设置命令这样新同事第一天就不会卡在环境问题上。CI/CD 又是另一回事。流水线里执行的机器通常是临时实例或专用构建机每次构建都会重新安装依赖这时候不建议全局安装任何工具更不能依赖开发机上的全局目录。正确做法是在构建脚本里使用npx或通过项目依赖声明保证每个环境拿到相同版本。如果强行在 CI 里用全局安装一旦构建机被重置流水线立刻全线飘红排查起来十分痛苦。5.3 npx 和全局目录的关系为什么我更推荐优先用 npxnpx是 npm 自带的命令执行器。它会在当前项目的node_modules/.bin中寻找目标命令如果找不到会去 npm 缓存里临时下载并执行不会污染全局目录。比如你不需要全局安装create-vite就能直接npx create-vite my-app。背后的包会放进缓存使用完之后不会一直留在全局工具列表里。这样做的最大好处是避免版本位移。全局目录里的包常常是“静止的版本”当项目需要的版本升级了全局工具跟不上冲突就产生了。而npx每次按需拉取用完即走更符合现代前端开发“依赖随项目走”的原则。因此我处理全局目录时会刻意控制全局安装包的规模尽量让全局目录只保留少数高频、与项目无关的命令行工具。6. 经验总结我一般怎么管理全局目录这几年来回折腾下来我自己形成了一个固定的管理习惯。首先绝不轻易在全局目录里安装各种脚手架能用npx就用npx只有像npm本身、pnpm、yarn这类需要高频出现在终端里的包才考虑全局安装。其次全局目录一定会迁出 C 盘我会固定放在D:\nodejs\npm-global然后在用户 PATH 中追加该目录避免后续重装系统或者用户目录同步影响命令。最后每次更换电脑或者重装 Node 版本我都会先用npm ls -g --depth0导出包列表再在新环境里逐项恢复。整个过程不复杂但能让很多看上去莫名其妙的命令失效问题消失得一干二净。如果你现在正被 Windows 的 npm 全局安装目录搞得很烦其实不必惊慌。梳理清楚路径、prefix、PATH 三者的关系再配合备份和迁移方案这类问题很快就能形成一套稳定可复用的操作流程。希望这篇内容能帮你省下那些我曾经熬夜排查的时间。

相关新闻

手把手推导:从状态向量确定轨道六要素的完整流程

手把手推导:从状态向量确定轨道六要素的完整流程

拿到一组数字,你能在十分钟内准确说出它描述的是一条什么样的卫星轨道吗?这不是在考验记忆力,而是轨道力学里最基本功的一环:从状态向量确定轨道。所谓状态向量,就是某个时刻卫星在地心惯性系下的位置矢量r和速度矢量v…

2026/10/14 4:39:55 阅读更多 →
IDEA 2020+Maven创建Spring Boot项目完整配置指南与避坑手册

IDEA 2020+Maven创建Spring Boot项目完整配置指南与避坑手册

在 IDEA 2020 里配好 Maven,再创建一个 Spring Boot 项目,这套流程网上教程很多,但不少教程还在用旧版本的界面截图,照着做第一步就对不上。真正自己动手时,版本差异、配置路径不同、网络导致依赖下载失败,…

2026/10/14 4:39:55 阅读更多 →
Virtuoso 使用技巧:从版图编辑到后仿收敛的实战避坑指南

Virtuoso 使用技巧:从版图编辑到后仿收敛的实战避坑指南

简介:这份PPT面向模拟、混合信号、射频及定制数字电路设计的学习者与工程师,系统梳理Cadence Virtuoso定制设计平台的使用技巧,帮助初学者快速上手、进阶用户查漏补缺。内容覆盖Virtuoso简介与正确进入方式、电路图绘制、基于specture的仿真分…

2026/10/14 4:38:55 阅读更多 →

最新新闻

电商AI视觉生产流水线:12个可编排图像生成Skill开源实践

电商AI视觉生产流水线:12个可编排图像生成Skill开源实践

1. 这不是又一个“AI画图工具”,而是电商视觉生产流水线的底层能力拆解你有没有遇到过这样的场景:运营同事凌晨两点发来消息,“明天大促主图要换,三套风格,带卖点文案,尺寸必须是800800和1200628双规格&…

2026/10/14 5:25:13 阅读更多 →
JavaScript正则方法全解析:从exec到replaceAll的实战指南

JavaScript正则方法全解析:从exec到replaceAll的实战指南

写正则的人最怕的不是正则写不出来,而是同一个需求,每个方法看起来都“差不多能用”,但真上线之后,Bug一个接一个。我见过好几次这样的情况:有人用match想拿捕获组,结果返回了一堆字符串;有人在…

2026/10/14 5:25:13 阅读更多 →
Apache Mesos 0.28.0 特性深度解析:net_cls 网络隔离、统一容器化与 v1 Executor HTTP API

Apache Mesos 0.28.0 特性深度解析:net_cls 网络隔离、统一容器化与 v1 Executor HTTP API

云原生 【免费下载链接】mesos Apache Mesos 项目地址: https://gitcode.com/gh_mirrors/mesos2/mesos 点击查看 免费下载 Apache Mesos 0.28.0 是 Mesos 发展历程中承上启下的一个重要版本:它在 Linux cgroups 网络隔离、标量资源精度、动态预留资源元…

2026/10/14 5:25:13 阅读更多 →
人体供暖系统:科学激活产热机制抵御寒冬

人体供暖系统:科学激活产热机制抵御寒冬

1. 寒冬里的主动发热之道最近几年冬天越来越难熬,特别是南方没有集中供暖的地区。作为一个在杭州生活了十年的北方人,我深刻体会到南方湿冷的威力——那种冷是往骨头缝里钻的。开空调太干燥,电热毯又只能局部取暖,于是我开始研究如…

2026/10/14 5:25:13 阅读更多 →
UE5 C++单播代理实战:DECLARE_DELEGATE与TDelegate全面解析

UE5 C++单播代理实战:DECLARE_DELEGATE与TDelegate全面解析

做游戏逻辑的时候,最常干的一件事就是把“某个行为”传递给“另一个系统”。按键按下的那一刻要通知谁,异步加载完关卡要提醒谁,血量掉到某个阈值要唤起谁——这些在UE5 C里最直接的落地方案就是代理(Delegate)。其中单…

2026/10/14 5:25:13 阅读更多 →
VC++ FTP服务器与客户端完整源码解析:从协议到断点续传实战

VC++ FTP服务器与客户端完整源码解析:从协议到断点续传实战

简介:一套面向VC/MFC与网络通信初学者的FTP客户端与服务器完整示例工程,基于VC6.0调试通过。工程同时提供控制台版本的FTP服务器和MFC界面客户端,源码头文件结构清晰,关键功能均以类接口形式开放,便于在此基础上扩展成…

2026/10/14 5:24:12 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →