MacOS前端环境一键搭建:脚本化实战与避坑指南
新MacBook Air到手那天我想着装个Node、装个Git、装个VS Code半小时搞定前端环境结果从下午四点折腾到晚上九点半。中间踩了Command Line Tools安装卡死、Homebrew下载超时、nvm装好后node -v还是旧版本、pnpm装上了但pnpm -v提示command not found这一堆坑。后来换了台预装MacOS 13.7.8的新机器我把所有步骤整理成了一套一键搭建脚本重装系统后只要跑一条命令几分钟就能恢复到能写代码的状态。这篇文章就是那套方案的完整复盘在MacOS 13.7.8上做前端环境一键搭建覆盖组件选型、脚本设计、执行验证和避坑记录。适合刚入手Mac的前端新人也适合需要批量给团队新同事配环境的人参考。文中所有命令和脚本片段都是我在Apple Silicon和Intel两台机器上实际跑过的不是从文档里抄出来的理想化步骤。1. 为什么我要把前端环境搭建写成脚本1.1 手动搭建的真实成本先说个实际数字手动配置一次前端环境顺利的话90分钟不顺利的话三小时起步而且大概率会在某个环节卡住。我把第一次手动搭建的过程大致拆过账时间主要花在等待和排查上。Command Line Tools下载安装本身要15到30分钟Homebrew安装要看GitHub连接状况有时候光是Updating阶段就卡得让人怀疑网络是不是坏了。nvm和Node装完以为结束了结果打开新的终端窗口node -v又变回系统自带的版本还要回头查PATH配置。等所有工具装齐Oh My Zsh的主题和插件又花掉半小时。这些时间加起来比实际动手敲命令的时间多得多而且每台机器遇到的报错还不一样网上一搜答案五花八门越搜越乱。1.2 脚本化解决的三个核心问题一键搭建听起来就是把命令按顺序塞进一个.sh文件实际设计的时候远没那么简单。我梳理下来脚本化真正要解决的是三个问题。第一是依赖顺序。前端环境不是一堆独立工具的集合很多组件之间有严格的先后关系。比如必须先有Command Line ToolsHomebrew才能编译依赖必须先有nvm才能用Node必须先把Node装好pnpm才能全局安装。想清楚这个依赖链脚本才不会在某个步骤上报脆弱的错。第二是幂等性。所谓幂等就是同一个脚本跑两遍、三遍结果是一样的不会因为某项工具已存在就重复安装导致冲突。我见过很多一键配置脚本第一次跑成功第二次跑直接报错原因就是没有判断是否已安装这个前置条件。好的脚本里每个模块都应该检查状态已安装就跳过。第三是环境可复现。入职新公司要配新电脑重装系统后要恢复开发环境这些场景下有一份可执行的脚本和没有是两种完全不同的体验。脚本不只是节省时间它把我当时到底装了哪些东西这个记忆负担变成了版本化、可审计的代码。2. 动手之前先把系统状态摸清楚2.1 确认芯片架构和安装路径MacOS 13.7.8既支持Apple SiliconM1/M2/M3系列也支持Intel芯片的老机器这两类机器在前端环境搭建上有一个关键区别Homebrew的安装前缀完全不同。Apple Silicon的Homebrew默认装在/opt/homebrewIntel的装在/usr/local。这个区别直接影响后续所有环境变量的配置。如果在Apple Silicon机器上继续沿用Intel时代的/usr/local/bin路径运行brew会提示找不到命令。判断架构只需要一条命令uname -m输出arm64就是Apple Silicon输出x86_64就是Intel。确认之后脚本里所有涉及路径的地方都要围绕这个结果来设置if [[ $(uname -m) arm64 ]]; then HOMEBREW_PREFIX/opt/homebrew else HOMEBREW_PREFIX/usr/local fi很多一键脚本在这个细节上翻车直接把路径写死导致部分机器执行到一半报错。凡是标榜一键的脚本架构兼容性是第一道关。2.2 系统版本对搭建的影响MacOS 13.7.8属于Ventura的长期维护版本从环境搭建的角度看它和14.x、15.x在前端工具链上没有本质差异。系统自带Python3、Ruby、Git、zsh这些都是前端环境的基础依赖Ventura之后依然沿用同样的结构。真正需要注意的是系统和工具链的默认策略。MacOS 13开始默认shell已经是zsh而不是bash这意味着所有环境变量的持久化配置要写入~/.zshrc而不是~/.bash_profile或~/.bashrc。很多教程还停留在改bash配置文件的阶段跟着做会发现新开的终端窗口根本不生效。另外一个容易忽视的地方是系统自带的Git版本。Ventura自带的Git可能不是最新版但对前端开发来说已经够用不需要额外从源码编译。我的建议是直接用系统Git只做用户级配置不要去动/usr/bin/git否则容易引入一堆编译依赖问题。2.3 Command Line Tools第一块拼图我见过不少新手跳过了这一步直接去装Homebrew结果报错信息指向clang: command not found才意识到少了基础组件。Command Line ToolsCLT包含了Git、C/C编译器、make等前端工具链的底层依赖没有它Homebrew会失败node-gyp编译原生模块也会失败。安装命令很简单xcode-select --install系统会弹出图形化安装窗口等待下载完成即可。比较坑的是下载速度和安装进度不直观看起来像卡住了实际上后台还在跑。可以用下面这条命令确认CLT是否已安装xcode-select -p如果输出/Library/Developer/CommandLineTools说明已经就绪。如果提示error: unable to locate说明还需要安装。有的机器会遇到弹窗提示网络连接失败或者安装失败。这种情况不要反复重试可以先执行sudo rm -rf /Library/Developer/CommandLineTools把残留清掉再重新执行xcode-select --install。如果还是不行去苹果开发者官网下载对应版本的Command Line Tools安装包手动安装这个笨办法反而最稳。2.4 网络源与镜像选择前端环境涉及的下载源非常多Homebrew的安装脚本在国内连接GitHub经常不稳定npm官方源的下载速度让人着急Node安装包也未必能稳定从nodejs.org拉下来。这不是什么玄学问题在国内网络环境下属于开发者的日常。我的处理方式很朴素不折腾特殊工具用国内镜像源解决。Homebrew可以配置清华、中科大或阿里的镜像npm registry用npmmirror原淘宝镜像Node的二进制文件从nodejs.cn或npmmirror的二进制镜像下载。这些都是在正式动手搭建之前就应该想清楚的事否则脚本写到一半被网络问题打断体验会非常糟糕。3. 前端环境要装什么我的选型清单与理由环境搭建的第一步是明确要装什么这比怎么装更考验经验。不同技术栈的人需要的环境不完全一样下面这张表是我针对前端开发整理的刚需清单每一项后面都会解释为什么这么选。组件选型理由系统包管理器HomebrewmacOS生态最成熟的包管理器图形应用和命令行工具都能管理Node版本管理nvm安装在用户目录无需sudo权限可随时切换Node版本JS包管理器pnpm安装快、节省磁盘npm保留作为兜底备选版本控制系统Git无需额外安装只需做全局配置和SSH密钥终端环境zsh Oh My Zsh系统默认shell插件生态丰富提升日常操作效率编辑器VS Code前端工具链支持最完善插件覆盖全面容器环境Docker可选需要模拟后端服务时才有必要资源占用大所以默认跳过3.1 Node版本管理选择nvm而不是直接brew install node很多人图省事直接用brew install node一把梭。这个方案初期看不出问题等你在两个项目之间切换Node版本时就痛苦了A项目要用Node 18B项目要用Node 22系统全局只有一个版本要么升级降级反复折腾要么就得去查各种骚操作。nvmNode Version Manager把每个版本的Node独立安装在用户目录~/.nvm/versions/node/下通过修改PATH环境变量快速切换版本整个过程不需要sudo不会污染系统目录逻辑非常干净。安装nvm的官方命令curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash如果这个地址拉取很慢可以在安装前把环境变量NVM_SOURCE指向镜像或者直接下载脚本内容审核后本地执行。装完后编辑~/.zshrc确认下面这段加载逻辑存在export NVM_DIR$HOME/.nvm [ -s $NVM_DIR/nvm.sh ] . $NVM_DIR/nvm.sh然后安装最新LTS版本并设置为默认版本nvm install --lts nvm alias default lts/*设置默认版本这个动作很容易漏漏掉之后每次新开终端还得手动nvm use体验大打折扣。3.2 包管理器pnpm为主npm兜底Node装完之后npm会跟着一并安装。npm在项目中做依赖管理完全够用但遇到Monorepo或者大依赖项目时安装速度和磁盘占用会比较吃亏。pnpm的核心优势是内容寻址存储所有依赖包都存放在一个全局仓库里项目通过硬链接引用多个项目共享同一份依赖磁盘占用大幅下降安装速度也明显更快。全局安装pnpmnpm install -g pnpm不过npm官方源在国内安装速度不稳定建议先切换镜像源npm config set registry https://registry.npmmirror.com切换之后安装速度通常会从几十KB/s提升到几MB/s。pnpm本身也会读取npm的registry配置所以这一条命令同时解决了pnpm的下载速度问题。对个人的建议是不要安装yarn。Yarn过去在依赖锁定和安装机制上有优势但pnpm和npm都吸收了这些优点新项目直接pnpm老项目用npm也够用没必要给环境再增加一个包管理器少一个工具就少一类版本冲突问题。3.3 Git配置与SSH密钥系统自带Git跳过安装但有两件事必须做全局用户信息和SSH Key。没有用户信息commit时会报错或者写入错误的作者没有SSH Key走HTTPS每次push都要输密码效率极低。全局配置git config --global user.name 你的名字 git config --global user.email 你的邮箱SSH Key用ed25519算法生成现代GitHub和GitLab都支持ssh-keygen -t ed25519 -C 你的邮箱生成过程中可以直接按三次回车跳过设置密码。然后把~/.ssh/id_ed25519.pub的内容添加到GitHub或GitLab的SSH Keys里。验证是否成功ssh -T gitgithub.com如果看到Hi username! Youve successfully authenticated说明SSH链路已经通了。这里有个小细节检查~/.ssh目录权限如果权限过于开放SSH会拒绝使用密钥文件报错通常是Permissions 0664 for id_ed25519 are too open需要执行chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519。3.4 终端体验zsh Oh My Zsh 高频插件MacOS 13.x默认shell就是zsh所以不用装shell本身重点在On My Zsh和插件。Oh My Zsh提供了主题和插件管理让终端从呆板的黑白变成了有git信息、有命令提示的工作台。安装命令sh -c $(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)我用的主题是robbyrussellOh My Zsh默认主题没有额外装powerlevel10k原因是后者需要配置Nerd Font对前端开发本身没有帮助属于锦上添花里的过度工程。如果你喜欢折腾可以自己选如果你追求实用默认主题足够。两个插件建议必装。一个是zsh-autosuggestions会根据历史命令给出灰色提示按右方向键直接补全另一个是zsh-syntax-highlighting让合法命令显示为绿色、非法命令显示为红色能直观发现敲错字。git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting然后编辑~/.zshrc里的plugins(git)这一行改成plugins(git zsh-autosuggestions zsh-syntax-highlighting)保存后执行source ~/.zshrc生效。注意如果先执行了source再改plugins顺序反了插件不会加载必须是先改配置文件再source。3.5 VS Code与code命令行VS Code是目前前端开发的主流编辑器核心优势在于插件生态ESLint、Prettier、VolarVue、TS Language Server这些前端工具链都有完善的支持。安装方式推荐Homebrewbrew install --cask visual-studio-code装完之后有个很容易忽略的步骤在VS Code里按CmdShiftP输入Shell Command: Install code command in PATH让终端可以执行code命令。这个能力意味着你可以直接在项目目录输入code .打开整个项目不用每次用鼠标点图标再找目录效率差距明显。3.6 Docker按需安装不进默认脚本很多前端项目需要本地启动Mock服务、Redis或MySQL这些场景依赖Docker。但Docker Desktop在MacOS上的资源占用和启动速度一直不太理想如果不确定项目用得到我不建议放在默认安装列表里。更合理的做法是给脚本留一个开关参数需要的时候才安装。后面讲脚本设计时我会专门说这个开关怎么实现。4. 一键脚本的完整设计与核心代码4.1 脚本的整体结构我设计的脚本分成六个区域环境检测、Homebrew、nvm与Node、Git配置、应用安装、验证输出。每个区域是一个函数函数内部先检查当前系统状态再决定执行还是跳过。这样设计的好处是易读、易维护、易排错。某个模块出问题时日志里能看到是哪个函数执行失败直接定位不用从头看到尾。4.2 脚本骨架颜色日志与环境检测#!/usr/bin/env bash set -euo pipefail GREEN\033[32m RED\033[31m YELLOW\033[33m RESET\033[0m info() { echo -e ${GREEN}[INFO]${RESET} $1; } warn() { echo -e ${YELLOW}[WARN]${RESET} $1; } error() { echo -e ${RED}[ERROR]${RESET} $1; } check_arch() { local arch arch$(uname -m) if [[ $arch arm64 ]]; then HOMEBREW_PREFIX/opt/homebrew else HOMEBREW_PREFIX/usr/local fi info 检测到芯片架构: $arch info Homebrew安装前缀: $HOMEBREW_PREFIX } install_command_line_tools() { if xcode-select -p /dev/null; then info Command Line Tools 已安装跳过 else info 正在安装 Command Line Tools... xcode-select --install warn 请在弹出的窗口中点击安装并等待完成 until xcode-select -p /dev/null; do sleep 5 done info Command Line Tools 安装完成 fi }set -euo pipefail是bash脚本的安全模式-e表示任何命令返回非零状态就退出-u表示使用未定义变量时报错-o pipefail让管道命令中的任何一个环节失败都能被感知到。不过在用这个模式时要注意某些安装脚本本身会返回非零状态但其实成功了所以有些函数内部要加入容错逻辑不能全交给-e处理。4.3 Homebrew安装与镜像配置install_homebrew() { if command -v brew /dev/null; then info Homebrew 已安装跳过 brew --version | head -n 1 return fi info 开始安装 Homebrew... /bin/bash -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh) # 将 Homebrew 的 bin 目录加入 PATH if [[ -d $HOMEBREW_PREFIX/bin ]]; then export PATH$HOMEBREW_PREFIX/bin:$PATH if ! grep -q HOMEBREW_PREFIX/bin ~/.zshrc 2/dev/null; then echo export PATH\$HOMEBREW_PREFIX/bin:\$PATH\ ~/.zshrc fi fi info Homebrew 安装完成 }这里有一个实操细节很多人在脚本里导出PATH后发现当前终端能用了关掉终端再开又不行了。因为export只对当前shell会话生效要让配置永久生效必须写入~/.zshrc。上面的代码同时做了这两件事当前会话和持久化配置。关于镜像配置我把它单独放到了脚本后半部分因为要等Homebrew本身可用之后才能执行brew命令。配置方式如下configure_brew_mirror() { export HOMEBREW_BREW_GIT_REMOTEhttps://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git export HOMEBREW_API_DOMAINhttps://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api export HOMEBREW_BOTTLE_DOMAINhttps://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles export HOMEBREW_CORE_GIT_REMOTEhttps://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git }这些环境变量不只在安装时需要日常执行brew install时也需要。所以脚本里我把它们同时追加到了~/.zshrc里不然下次终端配置一刷新下载又回到慢速状态。4.4 nvm、Node与pnpm安装install_nvm_node() { if [ -s $HOME/.nvm/nvm.sh ]; then info nvm 已安装跳过 else info 安装 nvm... curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash fi export NVM_DIR$HOME/.nvm [ -s $NVM_DIR/nvm.sh ] . $NVM_DIR/nvm.sh if ! command -v node /dev/null; then info 安装 Node.js LTS... nvm install --lts fi nvm alias default lts/* info 默认 Node 版本: $(node -v) } install_pnpm() { if command -v pnpm /dev/null; then info pnpm 已安装: $(pnpm -v) else info 安装 pnpm... npm install -g pnpm fi }一个很重要的细节是脚本执行时nvm是个shell函数而不是可执行文件所以在非交互式shell里直接调用nvm命令可能会报command not found。解决方式就是先sourcenvm脚本这一步不能省而且要在调用nvm之前完成。4.5 Git、VS Code与可选Dockerconfigure_git() { git config --global user.name ${GIT_USERNAME:-你的名字} git config --global user.email ${GIT_EMAIL:-youexample.com} if [ ! -f $HOME/.ssh/id_ed25519 ]; then info 生成 SSH Key... ssh-keygen -t ed25519 -C ${GIT_EMAIL:-youexample.com} -N -f $HOME/.ssh/id_ed25519 info 请将以下公钥添加到 GitHub/GitLab: cat $HOME/.ssh/id_ed25519.pub else info SSH Key 已存在跳过 fi } install_vscode() { if [ -d /Applications/Visual Studio Code.app ]; then info VS Code 已安装跳过 else info 安装 VS Code... brew install --cask visual-studio-code fi } install_docker() { if [ -d /Applications/Docker.app ]; then info Docker 已安装跳过 else info 安装 Docker Desktop... brew install --cask docker fi }Git的用户名和邮箱不应该硬编码在脚本里更合理的做法是通过环境变量传入脚本里给一个默认值兜底。SSH Key在脚本生成时会直接输出公钥内容这一步之后需要你自己去GitHub添加。4.6 幂等性、可选参数与执行入口脚本做到这个程度已经具备基本的幂等性每个安装函数都先检查目标是否已存在存在就跳过。重复执行不会导致重复安装或冲突。为了让Docker这类可选组件能自由控制我加了环境变量开关OPTIONAL${OPTIONAL:-none} run() { check_arch install_command_line_tools install_homebrew configure_brew_mirror install_nvm_node install_pnpm configure_git install_vscode if echo $OPTIONAL | grep -q docker; then install_docker fi print_versions } run执行方式bash install.sh # 需要Docker时 OPTIONALdocker bash install.shOPTIONAL支持逗号分隔方便以后扩展更多可选组件。4.7 验证输出函数最后一个函数把关键版本统一打印出来方便确认环境状态。这一步看似简单实际上价值很大它能让你在30秒内判断全部组件是否正常。print_versions() { echo info 环境版本验证 echo Arch : $(uname -m) echo System : $(sw_vers -productName) $(sw_vers -productVersion) echo Brew : $(brew --version | head -n 1) echo Node : $(node -v) echo npm : $(npm -v) echo pnpm : $(pnpm -v 2/dev/null || echo 未安装) echo Git : $(git --version) echo VS Code : $(code --version 2/dev/null | head -n 1 || echo code命令未配置) }5. 执行脚本后必须做的验证别急着进入写代码状态脚本跑完终端会打出一堆版本号但输出的版本号只能说明命令能找到不能完全说明环境真的可用。我会额外走一遍验证流程。5.1 版本体检清单第一步新开一个终端窗口逐项执行下面这张表的命令。这里强调新开窗口是因为脚本里的export只在当前shell生效新窗口加载~/.zshrc后才是真正的日常状态。命令预期输出不正常的信号node -vv22.x.xLTS版本command not found或显示系统旧版本npm -v10.x.xcommand not foundpnpm -v9.x.xcommand not found说明pnpm全局bin目录不在PATHgit --versiongit version 2.x.xcommand not foundcode --version1.x.xcommand not found说明还没安装code命令brew --versionHomebrew 4.x.xcommand not found说明PATH配置有问题ssh -T gitgithub.comHi username!Permission deniedSSH密钥未生效如果node -v显示的不是nvm管理的版本最常见的原因是系统自带Node位于/usr/local/binIntel机器且PATH顺序里它排在nvm前面。可以执行which -a node看看所有路径然后检查~/.zshrc中nvm的加载语句是否真的生效。正常的which node应该指向~/.nvm/versions/node/...。5.2 用真实项目跑通依赖安装链路版本命令全部正常建议再克隆一个真实的前端项目把依赖安装、本地启动跑一遍这是最接近日常开发的环境验证。git clone gitgithub.com:vuejs/create-vue.git cd create-vue pnpm install pnpm devpnpm install阶段如果出现node-gyp相关的编译错误通常意味着系统缺少Python或C编译环境。虽然Command Line Tools自带clang但部分原生模块仍需要Python3。MacOS 13自带Python3一般不用额外处理如果报错提示找不到python执行brew install python3即可。还有一个高频问题是pnpm在安装过程中提示Cannot read properties of null或Failed to resolve之类这往往不是pnpm本身的问题而是registry配置指向了一个失效的源。检查一下npm config get registry确保输出是https://registry.npmmirror.com或官方源。5.3 验证变量持久化环境变量持久化是很多人忽略的验证项。前面的脚本已经把需要的变量写入了~/.zshrc但最好确认一下grep -n NVM_DIR\|HOMEBREW_PREFIX\|pnpm ~/.zshrc如果你看到类似下面的输出说明持久化配置正常export NVM_DIR$HOME/.nvm export PATH/opt/homebrew/bin:$PATH export PATH$HOME/Library/pnpm:$PATH特别注意pnpm的全局bin目录。pnpm通常把全局可执行文件放在~/Library/pnpmApple Silicon或者~/.local/share/pnpm这个目录如果不在PATH里通过pnpm i -g安装的任何命令行工具都无法直接执行。6. 我在这套脚本上踩过的坑从日志里翻出来的问题这一部分是我最想写的。很多环境搭建教程只给标准路径但真实世界里的报错五花八门。下面几个坑是我在MacOS 13.7.8上反复踩过的几乎每条都和文档里的理想流程对不上。6.1 Homebrew安装卡在Updating阶段现象执行Homebrew安装脚本后终端长时间停留在 Tapping homebrew/core或Updating Homebrew...进度条不动看着像死机。原因Homebrew默认从GitHub拉取仓库国内网络环境下git fetch经常超时。解决安装前先设置镜像变量。我在脚本里把HOMEBREW_BREW_GIT_REMOTE和HOMEBREW_CORE_GIT_REMOTE指到清华镜像安装过程从20分钟缩短到3分钟。还有一个思路如果你的网络环境实在差到连curl都拉不动安装脚本可以去第三方平台找用户备份好的安装脚本或者从镜像站下载Homebrew的tar包手动解压。手动解压方式有点麻烦但也是可行方案。6.2 nvm装好了node -v却显示系统旧版本现象脚本执行完nvm list能看到nvm管理的新Node版本但新开终端后node -v显示的是v18.x甚至更老的系统自带版本。原因Mac系统自带Node一般在/usr/local/binIntel机器或者之前手动装过brew install node这两个路径在PATH中的优先级高于~/.nvm/versions/node。解决先执行which -a node查看所有Node路径然后检查~/.zshrc中nvm的加载语句是不是在PATH设置之前。我的经验是把nvm的加载语句尽量放在~/.zshrc靠前的位置并且在追加Homebrew PATH时不要用覆盖语法要用切片语法保留已有PATHexport PATH$HOMEBREW_PREFIX/bin:$PATH这里顺便说一个新手容易搞错的点export PATH/opt/homebrew/bin:$PATH和export PATH$PATH:/opt/homebrew/bin的优先级是相反的。前者让Homebrew的路径排在最前面正确后者会让系统路径优先如果系统路径里有同名的旧命令就会出现明明装了新版却执行旧版的问题。6.3 pnpm全局安装的命令找不到现象pnpm i -g typescript执行成功但输入tsc -v提示command not found。原因pnpm的全局bin目录没有加入PATH。pnpm的全局bin目录在~/Library/pnpmApple Silicon它不在系统默认PATH范围内。解决执行pnpm config get global-bin-dir查看当前全局bin目录然后把它加入~/.zshrcexport PATH$HOME/Library/pnpm:$PATH这里还有个隐藏问题如果你把pnpm本身也放在这个目录里删除重装pnpm时会遇到Windows风格的文件占用问题。实际表现是npm uninstall -g pnpm后pnpm命令还在因为指向同一个目录的硬链接没有清理干净。解决方法是先删掉~/Library/pnpm下的相关文件再重新安装。6.4 oh-my-zsh的插件不生效现象~/.zshrc里明明有plugins(git zsh-autosuggestions zsh-syntax-highlighting)但终端没有自动建议、命令也没有颜色高亮。原因插件目录没有正确clone到~/.oh-my-zsh/custom/plugins/。尤其是网络不稳定的情况git clone在后台静默失败但脚本没有检测git clone的返回值于是你以为装上了。解决安装完插件后先检查目录存在再继续ls ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/如果目录为空或不存在重新clone。然后在~/.zshrc里确认插件名和目录名完全一致包括大小写和连字符。zsh-autosuggestions这个目录名就和它的插件名一致如果把插件名写成了autosuggestions虽然看起来像但Oh My Zsh找不到对应目录就不会加载。6.5 Command Line Tools出现license弹窗现象第一次运行git或clang时终端会弹出一个让人误以为是系统卡死的授权协议界面有Agree和Disagree两个选项但键盘怎么按都没反应。原因CLT安装后第一次使用时需要接受Xcode license但终端窗口里的license提示并不支持键盘选择需要用鼠标点击或者通过命令方式接受。解决直接sudo xcodebuild -license accept提前接受协议就不会有弹窗打断了。我通常把它放在脚本里CLT安装完成之后自动执行。6.6 Docker Desktop安装后启动异常现象通过brew install --cask docker装好了Docker Desktop但双击启动后一直转圈或提示Docker Desktop requires a newer macOS version。原因Docker Desktop对macOS版本有最低要求有些版本要求13或更高13.7.8本身满足条件但部分机器的内存或虚拟化特性不满足Docker Desktop的要求。解决这类问题通常出现在老旧Intel Mac上处理方式是检查sysctl kern.hv_support如果返回0说明当前机器不支持Hypervisor.frameworkDocker Desktop基本没法用只能考虑改用云环境或轻量替代方案。所以我才把Docker设计成脚本里的可选项能不用就不折腾。最后再分享一点经验这套脚本前前后后跑了半年在Apple Silicon和Intel两台机器上各执行过好几次。第一次线上跑通大概花了七八分钟后续再跑时因为大部分组件已经存在30秒内就能完成全部验证输出。日常维护也很简单哪个工具出了新版本直接在函数里把版本号或者安装命令更新一下就好。有一点必须提醒脚本是我自己写的我清楚每一步在做什么所以敢直接执行。如果你从网上下载了别人的一键配置脚本或者从本文复制代码强烈建议先通读一遍再跑尤其是涉及curl ... | bash这种直接执行的写法。不是说不信任别人而是你至少要知道这个脚本会在你的机器上创建哪些目录、修改哪些配置、执行哪些命令。这个习惯比任何脚本都值钱。另外这个脚本只是一个起点。前端生态变化很快也许过两年nvm被更快的运行时管理器取代、pnpm成为官方内置工具到时候改造思路依然是一致的环境检测控制依赖顺序、幂等逻辑控制重复安装、版本验证保证结果可见。把这三件事想明白不管环境怎么变一套脚本就能长期用下去。