mini 折腾记(四):用 mise 统一开发环境,彻底告别版本地狱
mini 折腾记(四):用 mise 统一开发环境,彻底告别版本地狱
Prorisemini 折腾记(四):用 mise 统一开发环境,彻底告别版本地狱
前三篇文章里,我们搞定了硬件选购、系统设置、软件安装。现在 Mac 已经可以正常使用了,但作为开发者,最重要的事情还没做:搭建开发环境。
这一步,我在 Windows 上吃过大亏。
Windows 上的噩梦
我的 Windows 电脑用了五年,开发环境已经乱成一锅粥。
Node.js 装了三个版本,一个在 C 盘,一个在 D 盘,还有一个不知道装哪了。Python 更离谱,系统自带一个 3.7,我自己装了 3.10 和 3.13,每次运行脚本都要先确认用的是哪个版本。
Java 就更不用说了,JDK 8、JDK 11、JDK 17、GraalVM,全都装了,环境变量改来改去,经常出现 “找不到 JAVA_HOME” 的错误。
最要命的是各种缓存。npm 的缓存在 C 盘用户目录,pip 的缓存在 E 盘,Maven 的仓库在 C 盘,Gradle 的缓存又在用户目录。这些缓存加起来占了几十 GB 空间,而且散落在各个角落,想清理都不知道从哪里下手。
每次装新工具,都要:
- 去官网下载安装包
- 手动设置环境变量
- 配置缓存目录
- 测试是否生效
装一个工具至少要半小时,而且经常出问题。
这次换 Mac,我不想重蹈覆旧。我要从一开始就建立一套清晰的规则:
- 所有语言版本统一管理
- 所有缓存统一存放
- 所有数据都在外置硬盘
- 系统盘保持干净
寻找 “秦始皇”
在 Windows 上,每个语言都有自己的版本管理工具:
- Node.js 用 nvm
- Python 用 pyenv
- Ruby 用 rbenv
- Java 用 SDKMAN
这些工具各自为政,命令不统一,配置方式也不一样。我需要记住每个工具的用法,很麻烦。
我想找一个 “秦始皇”,能统一管理所有语言的版本。
我在网上搜索 “Mac 多语言版本管理”,找到了三个工具:
- asdf:老牌工具,插件生态丰富
- mise:新兴工具,用 Rust 写的,性能更好
- vfox:国产工具,功能类似
我仔细对比了一下,最后选择了 mise。
原因很简单:
- 性能好:mise 用 Rust 写的,比 asdf 快 24 倍
- 兼容性好:完全兼容 asdf 的插件生态
- 功能强:不仅管理版本,还能管理环境变量和任务
最重要的是,mise 支持通过环境变量控制所有数据的存放位置。这意味着我可以把所有语言运行时、所有缓存,全部放到外置硬盘,系统盘一点都不占用。
开始动手
第一步:理解~/.zshrc
在动手之前,我需要先搞清楚一个概念:~/.zshrc 是什么?
在 Windows 上,我们设置环境变量是这样的:
- 右键 “此电脑”
- 属性 → 高级系统设置 → 环境变量
- 在那里设置 PATH、JAVA_HOME 这些
在 Mac 上,~/.zshrc 就是 你个人的环境变量配置文件。
~代表你的用户主目录(/Users/你的用户名).zshrc是一个隐藏文件(以.开头)zsh是 Mac 默认的 Shell(命令行解释器)- 每次打开终端,系统会自动执行这个文件里的命令
类比 Windows:
~/.zshrc≈ Windows 的 “用户环境变量” + “开机启动脚本”- 每次打开终端 = 每次登录 Windows
搞清楚这个概念后,我就知道该怎么做了:把所有的环境变量配置写到 ~/.zshrc 里,这样每次打开终端,这些配置就自动生效了。
第二步:规划目录结构
我的外置硬盘叫 DataDisk,之前已经规划了这些目录:
1 | DataDisk/ |
现在我需要新增一个 DevEnv 目录,专门存放开发环境相关的东西。
打开终端,执行:
1 | cd /Volumes/DataDisk |
执行完后,目录结构变成:
1 | DataDisk/ |
这样一来,所有开发相关的东西都集中在 DevEnv 目录下,清晰明了。
第三步:安装 mise
mise 本身很小,可以装在系统盘。我用 Homebrew 安装:
1 | brew install mise |
安装完成后,验证一下:
1 | mise --version |
如果输出版本号,说明安装成功。
第四步:配置环境变量
这是最关键的一步。我需要在 ~/.zshrc 里配置所有的环境变量,让 mise 和各种缓存都指向外置硬盘。
打开终端,执行:
1 | code ~/.zshrc |
这会用 VS Code 打开 ~/.zshrc 文件。如果文件不存在,VS Code 会自动创建。
在文件末尾,添加以下内容:
1 | # ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== ==== |
保存文件(Command+S),然后关闭 VS Code。
回到终端,执行:
1 | source ~/.zshrc |
这个命令会重新加载配置文件,让刚才的配置立即生效。
验证一下配置是否成功:
1 | echo $MISE_DATA_DIR |
如果输出 /Volumes/DataDisk/DevEnv/mise,说明配置成功。
第五步:安装第一个语言(Node.js)
配置好环境变量后,就可以开始安装语言了。
我先装 Node.js,因为我在 Windows 上用的是 22.14.0 版本,想保持一致。
1 | # 查看可用的 Node 版本 |
执行后,mise 会自动下载并安装 Node.js 22 的最新版本。这个过程可能需要几分钟,耐心等待。
安装完成后,验证一下:
1 | node --version |
如果输出版本号,说明安装成功。
最关键的是,确认 Node.js 确实安装在外置硬盘:
1 | which node |
输出应该是:/Volumes/DataDisk/DevEnv/mise/installs/node/22.22.0/bin/node
看到这个路径,我心里踏实了。Node.js 确实装在外置硬盘,系统盘一点都没占用。
第六步:升级 npm 和安装 pnpm
Node.js 自带的 npm 版本可能不是最新的,我习惯用最新版。
1 | npm install -g npm@latest |
然后安装 pnpm(我在 Windows 上用的包管理器):
1 | npm install -g pnpm |
安装完成后,mise 会自动 “reshim”(重新生成快捷方式),这样 pnpm 就能直接使用了。
第七步:批量安装其他语言
Node.js 装好了,接下来批量安装其他语言。
Python:
1 | mise use --global python@3.13 |
Java (GraalVM):
1 | mise use --global java@graalvm-21 |
Rust:
1 | mise use --global rust@latest |
Deno:
1 | mise use --global deno@latest |
Maven:
1 | mise use --global maven@latest |
uv(Python 的现代化包管理器):
1 | mise use --global uv@latest |
每个命令执行后,mise 会自动下载并安装对应的工具。整个过程大概需要 10-15 分钟。
安装完成后,查看所有已安装的工具:
1 | mise list |
输出类似这样:
1 | deno 2.6.7 |
所有工具都装好了,而且全部在外置硬盘。
第八步:配置各语言的包管理器
虽然环境变量已经配置好了,但有些工具还需要单独的配置文件。
Python pip 配置:
1 | mkdir -p ~/.config/pip |
这个配置做了两件事:
- 把 pip 的缓存目录指向外置硬盘
- 使用清华大学的镜像源,下载速度更快
pnpm 配置:
1 | pnpm config set store-dir /Volumes/DataDisk/DevEnv/caches/pnpm/store |
Maven 配置:
1 | mkdir -p ~/.m2 |
Cargo (Rust)配置:
1 | cat > /Volumes/DataDisk/DevEnv/caches/cargo/config.toml << 'EOF' |
这些配置文件的作用是:
- 指定缓存目录到外置硬盘
- 使用国内镜像源,加快下载速度
- 优化构建参数
验证成果
所有工具都装好了,配置也都完成了。现在验证一下成果。
执行这个命令,查看所有工具的安装位置:
1 | echo "=== Node.js ===" |
输出显示,所有工具的路径都是 /Volumes/DataDisk/DevEnv/mise/installs/...,说明全部安装在外置硬盘。
查看外置硬盘的占用情况:
1 | du -sh /Volumes/DataDisk/DevEnv/mise/installs/* |
输出:
1 | 89M /Volumes/DataDisk/DevEnv/mise/installs/deno |
所有语言运行时加起来约 1GB,缓存约 150MB,全部在外置硬盘。系统盘只有 mise 本身(几 MB)和配置文件。
实战测试
理论上配置好了,但实际能不能用?我创建一个测试项目验证一下。
1 | mkdir -p /Volumes/DataDisk/Projects/test-env |
测试 Node.js:
1 | echo "console.log('Hello from Node.js')" > test.js |
输出:Hello from Node.js
测试 Python:
1 | echo "print('Hello from Python')" > test.py |
输出:Hello from Python
测试 npm 缓存:
1 | npm init -y |
安装完成后,查看 npm 缓存:
1 | ls -lh /Volumes/DataDisk/DevEnv/caches/npm |
能看到 _cacache 和 _logs 目录,说明 npm 的缓存确实在外置硬盘。
所有测试都通过了。开发环境搭建完成。
这套方案的优势
折腾了一下午,终于把开发环境搭建好了。回顾一下这套方案的优势:
1. 系统盘干净
系统盘只有 mise 本身(几 MB)和配置文件,所有语言运行时、所有缓存都在外置硬盘。
对于 256G 的系统盘来说,这太重要了。
2. 统一管理
以前装 Node.js 要去官网下载,装 Python 要去另一个官网,装 Java 又要去另一个地方。
现在只需要一个命令:mise use --global 语言名@版本号。
所有语言的安装、升级、卸载,都用同样的命令,不需要记住每个工具的用法。
3. 版本切换方便
mise 支持全局版本和项目版本。
全局版本是默认使用的版本,刚才我们装的就是全局版本。
项目版本是针对某个项目的版本。比如我有个老项目需要用 Node.js 16,我可以在项目目录下创建一个 .tool-versions 文件:
1 | cd /Volumes/DataDisk/Projects/old-project |
以后每次进入这个项目目录,mise 会自动切换到 Node.js 16。离开这个目录,又会切换回全局版本。
这个功能太实用了。以前我要手动切换版本,经常忘记切回来,导致其他项目跑不起来。
4. 易于迁移
如果以后换电脑,我只需要:
- 把外置硬盘插到新电脑
- 安装 mise
- 复制
~/.zshrc配置文件
所有语言运行时、所有缓存,都能直接用,不需要重新安装。
5. 配置透明
所有的配置都在 ~/.zshrc 里,一目了然。
如果某个工具出问题了,我可以直接去配置文件里查,不需要到处找环境变量。
一些注意事项
这套方案虽然好用,但也有一些需要注意的地方。
1. 外置硬盘必须一直插着
因为所有语言运行时都在外置硬盘,如果硬盘没插,所有命令都会报错。
对于 Mac mini 这种台式机,这不是问题,硬盘可以一直插着。
但如果是 MacBook,出门的时候可能不想带硬盘,那就需要在系统盘也装一套开发环境。
2. 第一次安装比较慢
mise 下载语言运行时的时候,需要从官网下载,速度可能比较慢。
我装 Rust 的时候,下载了 10 分钟,后来换国内源下载速度就快很多了
但这是一次性的成本,装好之后就不需要再下载了。
3. 有些工具可能不兼容
mise 兼容 asdf 的插件生态,理论上支持几百种工具。
但有些小众工具可能没有插件,或者插件不稳定。
遇到这种情况,只能用传统方式安装(Homebrew 或官网下载)。
4. 需要定期清理缓存
虽然缓存都在外置硬盘,但时间长了也会占用不少空间。
npm 的缓存、pip 的缓存、Maven 的仓库,都会越来越大。
建议每隔几个月清理一次:
1 | # 清理 npm 缓存 |
小结
从 Windows 转到 Mac,开发环境的搭建是最大的挑战。
Windows 上的那套工具(nvm、pyenv、SDKMAN)在 Mac 上也能用,但我不想重复 Windows 上的混乱。
mise 给了我一个全新的思路:用一个工具管理所有语言,用环境变量控制所有数据的存放位置。
这套方案不仅适用于 Mac,也适用于 Linux。如果以后我要在服务器上搭建开发环境,也可以用同样的方式。
现在,我的 Mac mini 有了一套干净、统一、易于管理的开发环境。系统盘保持干净,所有数据都在外置硬盘,版本切换方便,配置透明。
这才是我想要的开发环境。
下一篇文章,我会讲如何安装和配置 IDE(VS Code、Cursor、IntelliJ IDEA),以及如何配置数据库(MySQL、Redis、MongoDB)。



