mise 开发环境管理——多项目多语言版本管理不再头疼
mise 开发环境管理——多项目多语言版本管理不再头疼
适读人群:AI 工程师、全栈开发者 | 阅读时长:约 11 分钟 | 核心价值:用 mise 管理多项目多语言版本的完整实践
上个月我的电脑里同时跑着这些项目:
- 一个 Java 17 的 Spring AI 应用(公司的)
- 一个 Python 3.10 的 LangChain 项目(旧客户维护)
- 一个 Python 3.12 的 FastAPI 服务(新项目)
- 一个 Node 20 的前端配套工具(用来处理 PDF 转文本)
- 偶尔还要跑一些 Python 3.9 的旧脚本
不同项目用不同版本,切来切去很烦。以前我用 pyenv 管 Python,用 nvm 管 Node,用 sdkman 管 Java。三个工具,三套配置,三套 shell 集成。每次新开发机设置环境,光是把这三个工具装好、配置好就要两三个小时。
然后我发现了 mise。
一个工具把上面三件事全干了,而且比每个专用工具都好用。
mise 是什么
mise(读作 "meez",法语"准备就绪"的意思)是一个开发工具版本管理器,原名 rtx,用 Rust 写的。
它的定位是替代 asdf、pyenv、nvm、rbenv、sdkman 这一整个工具生态。支持几乎所有主流语言的版本管理,包括 Python、Node.js、Java、Go、Ruby、Rust 等。
关键特性:
- 基于目录的版本切换(进入项目目录,自动切换到该项目要求的版本)
- 支持
.tool-versions文件(asdf 兼容格式) - 支持
.mise.toml文件(mise 原生格式,功能更强) - 比 asdf 快很多(Rust 实现)
- 同时支持 tasks(类似 Makefile 的任务系统)
安装
# macOS
brew install mise
# Linux/macOS(通用安装脚本)
curl https://mise.run | sh
# 配置 shell 集成(选你用的 shell)
# zsh
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
source ~/.zshrc
# bash
echo 'eval "$(mise activate bash)"' >> ~/.bashrc
source ~/.bashrc
# 验证
mise --version
# mise 2024.x.x基础用法
安装语言版本
# 安装 Python
mise install python@3.12.0
mise install python@3.10.14
mise install python@3.9.19
# 安装 Node.js
mise install node@20.18.0
mise install node@18.20.0
# 安装 Java(使用 Eclipse Temurin)
mise install java@temurin-17.0.13
mise install java@temurin-21.0.5
# 查看已安装的版本
mise list
# 查看可安装的版本
mise ls-remote python设置全局默认版本
# 全局默认用 Python 3.12、Node 20、Java 17
mise use --global python@3.12.0
mise use --global node@20.18.0
mise use --global java@temurin-17.0.13
# 查看全局配置(保存在 ~/.config/mise/config.toml)
mise config为特定项目设置版本
# 进入项目目录
cd /path/to/my-langchain-project
# 设置该项目使用 Python 3.10
mise use python@3.10.14
# 这会在项目根目录创建 .mise.toml
cat .mise.toml
# [tools]
# python = "3.10.14"从此,每次你 cd 进这个目录,mise 就会自动把 python 命令切换到 3.10.14。离开目录,自动切回全局默认。
真实场景:我的多项目配置
我的几个项目根目录各自有一个 .mise.toml:
旧 LangChain 项目(Python 3.10):
# /projects/legacy-rag/.mise.toml
[tools]
python = "3.10.14"
[env]
PYTHONPATH = "src"
OPENAI_API_KEY = "{{env.OPENAI_API_KEY_LEGACY}}" # 从系统环境变量读取新 FastAPI AI 服务(Python 3.12):
# /projects/fastapi-ai/.mise.toml
[tools]
python = "3.12.0"
[env]
PYTHONPATH = "src"
APP_ENV = "development"Spring AI 项目(Java 17):
# /projects/spring-ai-app/.mise.toml
[tools]
java = "temurin-17.0.13"
[env]
JAVA_HOME = "{{env.MISE_JAVA_HOME}}" # mise 自动设置的 Java home
MAVEN_OPTS = "-Xmx2g"全栈项目(Python + Node):
# /projects/fullstack-ai/.mise.toml
[tools]
python = "3.12.0"
node = "20.18.0"
[env]
NODE_ENV = "development"这个设计的妙处:.mise.toml 提交到 git,团队里所有人 mise install 一下就有了完全一致的工具版本。
mise tasks:把项目的常用命令也管起来
这是我后来发现的功能,非常实用。mise 支持定义 tasks,类似 Makefile 但更好用:
# .mise.toml
[tools]
python = "3.12.0"
[tasks.install]
description = "安装项目依赖"
run = "uv sync"
[tasks.dev]
description = "启动开发服务器"
run = "uvicorn src.main:app --reload --port 8000"
[tasks.test]
description = "运行测试"
run = "pytest tests/ -v"
[tasks.format]
description = "格式化代码"
run = """
ruff format src/
ruff check src/ --fix
"""
[tasks.embedding]
description = "重建向量索引"
run = "python scripts/rebuild_embeddings.py"
depends = ["install"] # 先运行 install task
[tasks.clean]
description = "清理缓存和临时文件"
run = """
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
find . -name "*.pyc" -delete 2>/dev/null || true
rm -rf .pytest_cache dist build
"""使用:
# 列出所有可用 tasks
mise tasks
# install 安装项目依赖
# dev 启动开发服务器
# test 运行测试
# format 格式化代码
# embedding 重建向量索引
# clean 清理缓存和临时文件
# 运行 task
mise run dev
mise run test
mise run format
# 简写
mise dev
mise test我以前每个项目都有一个 Makefile,现在这个功能完全可以用 mise tasks 替代,而且还有版本感知(task 运行时自动用该项目的正确语言版本)。
迁移:从 pyenv + nvm 切换
如果你已经在用 pyenv,迁移步骤:
# 查看 pyenv 里已有的版本
pyenv versions
# 在 mise 里安装同样的版本
mise install python@3.10.14
mise install python@3.12.0
# 对于有 .python-version 文件的项目,mise 会自动读取
# 不需要改任何配置文件
# 确认切换正常后,可以禁用 pyenv
# 从 .zshrc 里移除 pyenv 的初始化代码
# (建议先保留一段时间,确认稳定后再删)nvm 同理:
# 查看 nvm 里的版本
nvm list
# mise 安装同样的版本
mise install node@20.18.0
mise install node@18.20.0
# 项目里的 .nvmrc 文件,mise 会自动读取
# 不需要迁移配置mise 的一个贴心设计:它会自动读取 .python-version(pyenv 格式)、.nvmrc(nvm 格式)、.tool-versions(asdf 格式),向下兼容,迁移成本极低。
一些实用技巧
临时使用某个版本,不想修改 .mise.toml:
# 临时切换,只对当前 shell 会话有效
mise shell python@3.9.19
python --version # 3.9.19
# 新开一个 shell,回到项目默认版本查看某个命令来自哪个版本:
mise which python
# /Users/xiaozhangge/.local/share/mise/installs/python/3.12.0/bin/python
mise exec python -- python --version
# Python 3.12.0更新 mise 本身:
mise self-update团队 onboarding 脚本:
新同事加入,在项目目录执行一个命令就装好所有工具:
mise install # 读取 .mise.toml,安装所有声明的工具版本
mise run install # 运行 install task(比如 uv sync 或 npm install)和 uv 配合使用
mise 管 Python 版本,uv 管 Python 包。两者配合是目前我认为最好的 Python 开发体验:
# mise 确保用对的 Python 版本
mise use python@3.12.0
# uv 在这个 Python 版本上管理包
uv venv # 用 mise 管理的 Python 3.12 创建虚拟环境
uv sync # 安装依赖
uv run python main.py # 运行值不值得换
如果你只用 Python,pyenv 已经够了,迁移的动力不那么强。
但如果你像我一样同时维护 Python、Java、Node 项目,mise 把三个工具的事情一个工具干了,配置统一,切换无缝。光是设置新开发机的时间,从两三个小时缩到了二十分钟。
这个时间差,值得换。
