饮墨

子安饮墨馀三斗,留与卿儿作赋来

Mise:一个工具统一管理所有开发语言版本,彻底告别 nvm/pyenv/rbenv

痛点

运维团队的开发环境管理是个老问题:项目 A 需要 Node 18 + Python 3.11,项目 B 需要 Node 20 + Python 3.12 + Go 1.22。传统方案是装一堆 *env 工具——nvm 管 Node、pyenv 管 Python、goenv 管 Go、rbenv 管 Ruby。

实际痛点:

  • 工具碎片化:每个语言一个版本管理器,shell 初始化慢,.bashrc 越来越臃肿
  • asdf 虽好但慢:asdf 解决了统一管理的问题,但它是纯 Shell 实现,每次切换目录都有明显延迟(尤其在有几十个插件时)
  • CI 环境难复现:本地和 CI 用不同的版本管理方式,版本漂移导致"本地能跑线上挂"
  • 团队协作不一致:新人入职配环境半天,还经常配错版本

方案

Mise(原名 rtx)是用 Rust 编写的下一代开发工具版本管理器。它兼容 asdf 插件生态,但性能快 10-100 倍,并且内置任务运行器(Task Runner),可以替代 Makefile/Just。

核心优势:

维度 asdf Mise
实现语言 Shell Rust
切换速度 ~200ms ~5ms
兼容 .tool-versions
兼容 .node-version / .python-version
内置 Task Runner
环境变量管理 ✅(类 direnv)
独立二进制

实操步骤

第一步:安装 Mise

# 推荐方式:一行安装
curl https://mise.run | sh

# 或用包管理器
# macOS
brew install mise
# Arch Linux
pacman -S mise
# APT (Ubuntu/Debian)
apt install -y gpg curl
curl https://mise.jdx.dev/gpg-key.pub | gpg --dearmor -o /usr/share/keyrings/mise-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/mise-archive-keyring.gpg] https://mise.jdx.dev/deb stable main" | tee /etc/apt/sources.list.d/mise.list
apt update && apt install -y mise

激活 shell 集成:

# Bash
echo 'eval "$(mise activate bash)"' >> ~/.bashrc

# Zsh
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc

# Fish
echo 'mise activate fish | source' >> ~/.config/fish/config.fish

第二步:管理工具版本

# 安装指定版本
mise install node@20.14.0
mise install python@3.12.4
mise install go@1.22.4

# 设置项目级版本(写入 .mise.toml)
cd /path/to/project
mise use node@20.14.0
mise use python@3.12.4

# 设置全局默认版本
mise use --global node@20
mise use --global python@3.12

# 查看当前激活版本
mise current
# node   20.14.0  ~/project/.mise.toml
# python 3.12.4   ~/project/.mise.toml
# go     1.22.4   ~/.config/mise/config.toml

生成的 .mise.toml 文件(提交到 Git):

[tools]
node = "20.14.0"
python = "3.12.4"

[env]
DATABASE_URL = "postgresql://localhost:5432/mydb"
ENVIRONMENT = "development"

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

[tasks.test]
run = "pytest -v"
description = "Run test suite"

[tasks.lint]
run = ["ruff check .", "eslint src/"]
description = "Run all linters"

第三步:利用内置 Task Runner 替代 Makefile

# 列出可用任务
mise tasks
# dev   Start development server
# test  Run test suite
# lint  Run all linters

# 执行任务
mise run dev
mise run test
mise run lint

# 任务支持依赖关系

.mise.toml 中定义复杂任务:

[tasks.deploy]
run = """
#!/usr/bin/env bash
set -euo pipefail
echo "Building..."
npm run build
echo "Deploying to $ENVIRONMENT..."
rsync -avz dist/ deploy@server:/app/
"""
depends = ["lint", "test"]
description = "Build and deploy (runs lint + test first)"

第四步:CI/CD 集成

GitHub Actions 示例:

name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: jdx/mise-action@v2
        # 自动读取 .mise.toml 安装对应版本
      - run: mise run test

这样 CI 环境与本地完全一致——都从同一个 .mise.toml 读取版本,零配置漂移。

避坑

1. 从 asdf 迁移时插件不兼容

少数 asdf 插件可能有问题。Mise 对主流工具(Node、Python、Go、Java、Ruby、Rust)有内置 backend,优先使用内置而非 asdf 插件:

# 查看工具的可用 backend
mise registry | grep python
# python  core:python  (内置,推荐)
# python  asdf:asdf-community/asdf-python

# 强制使用 asdf 插件(不推荐)
mise use asdf:asdf-community/asdf-python@3.12.4

2. direnv 用户切换注意

Mise 内置环境变量管理可完全替代 direnv。如果之前用 direnv,迁移步骤:

# 将 .envrc 中的 export 移到 .mise.toml 的 [env] 段
# 然后禁用 direnv
# .envrc 中的 layout python 替换为 mise use python@3.12

如果想两者共存,在 .envrc 中加 use mise 即可。

3. Python virtualenv 的正确姿势

Mise 管理 Python 版本,但虚拟环境需要额外配置:

# .mise.toml
[tools]
python = "3.12.4"

[settings]
python_venv_auto_create = true  # 自动创建 .venv

[env]
_.python.venv = ".venv"  # 自动激活虚拟环境

进入项目目录时自动创建并激活 venv,离开时自动停用,无需手动 source .venv/bin/activate

总结

Mise 解决了开发环境版本管理的三大痛点:碎片化(一个工具管所有语言)、性能(Rust 实现,毫秒级切换)、一致性(单一 .mise.toml 覆盖本地 + CI)。

对运维团队的实际收益:

  • 新人入职:git clone && mise install,一条命令搞定环境
  • CI/CD 统一:用 mise-action 保证版本与开发环境完全一致
  • 替代 Makefile:内置 Task Runner 管理构建/测试/部署任务
  • 替代 direnv:内置环境变量管理,减少工具依赖

如果你还在维护一堆 *env 工具或者受够了 asdf 的启动延迟,Mise 值得立即切换。

您还没有登录,请登录后发表评论。