mise:替代 nvm + pyenv + rbenv + ... 的多语言版本管理器

起因

机器上同时维护 4 个项目:
- 一个 Node 16 老仓库
- 一个 Node 20 新项目
- 一个 Python 3.9 后端
- 一个 Python 3.12 数据 pipeline

之前装了 nvm + pyenv + rbenv + goenv。每个工具一套 shell hook,
shell 启动时间 1.5 秒(全是 PATH 操作)。切项目时 nvm use pyenv shell
排队按。

mise(前身 rtx)一个工具管所有语言版本,shell 启动只加 50ms。

安装

# 一行装
curl https://mise.run | sh

# 或包管理器
brew install mise
sudo apt install mise

# 装完接到 shell
echo 'eval "$(mise activate bash)"' >> ~/.bashrc
echo 'eval "$(mise activate zsh)"'  >> ~/.zshrc
echo 'mise activate fish | source'  >> ~/.config/fish/config.fish

mise --version

装语言

# 全局装版本
mise use --global node@20
mise use --global [email protected]
mise use --global [email protected]
mise use --global rust@stable

# 在某项目目录里指定(写入 .mise.toml 或 .tool-versions)
cd ~/projects/legacy-app
mise use node@16    # 这个目录用 Node 16

cd ~/projects/data-pipeline
mise use [email protected]

# 自动切换:cd 进目录 mise 自动 use 对应版本

.mise.toml 项目配置

# .mise.toml
[tools]
node = "20"
python = "3.12"
go = "1.22"
rust = "stable"
"npm:pnpm" = "latest"            # 通过 npm 装 pnpm
"pipx:poetry" = "latest"         # 通过 pipx 装 poetry
"go:github.com/jesseduffield/lazygit" = "latest"

[env]
DATABASE_URL = "postgresql://localhost/myapp"
PYTHONDONTWRITEBYTECODE = "1"

[tasks.test]
description = "Run tests"
run = ["pytest", "npm test"]

[tasks.dev]
description = "Start dev server"
run = "npm run dev"

之后:

mise install                # 装 .mise.toml 声明的所有工具
mise run test               # 跑 [tasks.test]
mise run dev
mise tasks                  # 列所有 tasks

列出 / 切换

mise ls                     # 看当前激活的工具版本
mise ls --installed         # 看本机装了哪些版本
mise outdated               # 看哪些工具有新版本

mise current                # 当前目录最终生效的版本(含继承)
mise where node             # 当前 node 二进制路径

env 管理

mise.toml[env] 段在 mise activate 后 cd 进目录自动注入:

[env]
AWS_PROFILE = "dev"
DATABASE_URL = "postgresql://localhost/myapp"
_.path = ["./bin", "./node_modules/.bin"]   # 加 PATH
_.file = ".env"                              # 也读 .env 文件

替代了 direnv 大部分用法。

与 .tool-versions(asdf 兼容)

asdf 用户已有 .tool-versions

nodejs 20.10.0
python 3.12.1
ruby 3.2.0

mise 直接读,零迁移。新项目也建议用更强大的 .mise.toml 格式。

团队协作

.mise.toml 进 git:

git add .mise.toml
git commit -m 'chore: pin tool versions via mise'

新人 clone 后:

cd repo
mise install   # 装齐所有工具版本

CI 里:

- uses: jdx/mise-action@v2
  with:
    cache: true
- run: mise run test

性能对比

启动延迟 多语言
nvm 500-1500ms
pyenv 200-400ms
asdf 200-500ms
mise 30-50ms

Rust 写的 + 智能 PATH shim 让启动几乎瞬时。

替代了什么

机器上以前装的:

  • nvm → 删
  • pyenv → 删
  • rbenv → 删
  • goenv → 删
  • direnv(大部分用法)→ 删(保留给复杂 shell 逻辑)

.zshrc 从 80 行清到 30 行,shell 启动 1.5s → 0.2s。

mise tasks vs Makefile

mise tasks 比 Makefile 优势:

  • 不需要 tab 缩进
  • 跨平台一致(make 在 Windows 不友好)
  • 自动激活该项目的工具版本
  • TOML 比 Makefile 易读
[tasks.lint]
run = ["ruff check .", "mypy src/"]

[tasks.fmt]
run = ["ruff format .", "ruff check --fix ."]

[tasks.ci]
depends = ["lint", "test"]
run = "echo all green"

[tasks.test]
run = "pytest --cov"
mise run ci   # 自动跑 lint + test

效果

  • 4 个项目切换无感(cd 进去自动切版本)
  • shell 启动 < 0.2s
  • 一个工具管所有语言:心智模型干净
  • .mise.toml 进 git 让新同事 onboard "git clone + mise install" 完事
  • task runner 顺带替代了一半 Makefile / package.json scripts

踩过的坑

  1. 从 nvm 迁过来 PATH 顺序乱:nvm 残留 PATH 里。彻底清 nvm:
    bash rm -rf ~/.nvm # ~/.bashrc 里删掉所有 nvm 相关行

  2. mise 后台编译 Python / Ruby 慢:源码编译需要 build-essential +
    libssl-dev 等系统库。Debian/Ubuntu:
    bash sudo apt install -y build-essential libssl-dev libffi-dev \ libsqlite3-dev libbz2-dev libreadline-dev zlib1g-dev \ libncurses-dev liblzma-dev tk-dev

  3. CI 没缓存导致每次都重装:mise-action 加 cache: true

  4. 某些工具用 GitHub release 装:网络问题在国内有时拉不下来。
    MISE_GITHUB_TOKEN 或者镜像源。

  5. VSCode Python 解释器找不到:mise 装的 Python 在
    ~/.local/share/mise/installs/python/3.12.0/bin/python
    .vscode/settings.json"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python" 让它用项目 venv。

精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。