重要
- ① mise 确保所有工具、配置和任务都井井有条且准备就绪,无论你的项目使用哪种编程语言或框架。
- ② mise 完全支持 Linux 和 MacOS;但是,对于 Windows ,请使用 powershell7+ ,而不是 cmd 。
- ③ cmd 实在太古老了,微软目前也在主推 powershell7+ 。
第一章:介绍和安装
1.1 介绍
1.1.1 概述
- mise 是一个现代化的
统一开发环境管理工具,它将三种核心功能整合到一个强大而单一的 CLI 中。mise 使用 Rust 编写,旨在提供高性能和高可靠性,作为一个“开发环境的前端”,用一个连贯的系统替代了多个专用工具。

- 其实,从官网的定位来说,mise 是开发环境的前端。
提醒
问:如何理解开发环境的前端?
答:在 mise 出现之前,市面上已经有了 asdf 、nvm、pyenv、sdkman 等工具,但是它们都有缺陷,如:nvm 仅支持 Node.js、pyenv 仅支持 Python,sdkman 仅支持 JVM,虽然 asdf 支持很多工具(windows 支持有限),而 mise 是 asdf 的现代化替代品,保留生态兼容性的同时大幅提升性能和体验。
- mise 和同类工具的对比,如下所示:
| 工具 | 管理范围 | 跨语言 | 性能 | Windows 支持 |
|---|---|---|---|---|
| mise | ✅ 50+ 工具 | ✅ 统一管理 | ⚡ 极快(Rust) | ✅ 原生支持 |
| asdf | ✅ 100+ 工具 | ✅ 统一管理 | 🐢 较慢(Shell) | ⚠️ 有限 |
| nvm | ❌ 仅 Node.js | ❌ | ⚡ 快 | ✅ |
| pyenv | ❌ 仅 Python | ❌ | ⚡ 快 | ⚠️ 需 WSL |
| sdkman | ❌ 仅 JVM 工具 | ❌ | 🐢 中等 | ⚠️ 有限 |
1.1.2 独特之处
- 本质上,mise 将传统上由独立工具提供的功能整合到了统一的工作流中,如下所示:
| 核心功能 | 传统工具 | mise 方案 | 优点 |
|---|---|---|---|
| 开发工具版本管理(Dev Tools) | asdf、nvm、pyenv、rbenv、gvm 等(每种语言一个) | 单一工具管理数百种开发工具 | 学习成本更低,所有语言行为一致 |
| 环境变量(Environments) | direnv、手动 .env 文件、shell 脚本 | 内置环境管理,支持目录作用域配置 | 根据项目目录自动切换环境变量和配置,提供类似 direnv 的功能,但灵活性更强 |
| 任务运行(Tasks) | make、npm scripts、shell 脚本 | 统一任务系统,支持依赖管理 | 执行构建、测试和部署任务,支持依赖管理、并行执行,相比 make 或 npm scripts 提供了增强的功能 |
- 这种统一的方法消除了学习和维护多个工具的需要,降低了配置的复杂性,以及在整个开发工作流中提供一致的行为。
1.2 mise 安装(Windows)
1.2.1 更新 PowerShell
- 命令:
cmd
:: 安装/更新到最新版 PowerShell 7
winget install --id Microsoft.PowerShell --source winget
:: 启用自动更新
winget upgrade Microsoft.PowerShell --silent
:: 查看 Windows PowerShell 5.1 版本
powershell -command "$PSVersionTable.PSVersion"
:: 查看 PowerShell 7.x 版本
pwsh -command "$PSVersionTable.PSVersion"1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
提醒
PowerShell 分为 5.1 版本和 7.x 版本,如下所示:
- 5.1 版本是 Windows 11 内置的版本,无法单独升级,只会随 Windows Update 自动更新安全补丁。
- 7.x 版本是微软推出的跨平台开源版本,与 Windows PowerShell 5.1 并行运行,功能更强大、性能更好,并且 mise 的智能目录切换也需要 7.x 的支持。
- 示例:更新 PowerShell :
cmd
:: 安装/更新到最新版 PowerShell 7
winget install --id Microsoft.PowerShell --source winget
:: 启用自动更新
winget upgrade Microsoft.PowerShell --silent1
2
3
4
5
2
3
4
5

- 示例:验证是否安装成功:
cmd
:: 查看 Windows PowerShell 5.1 版本
powershell -command "$PSVersionTable.PSVersion"
:: 查看 PowerShell 7.x 版本
pwsh -command "$PSVersionTable.PSVersion"1
2
3
4
5
2
3
4
5

1.2.2 mise 卸载
- 命令:
cmd
winget uninstall --id jdx.mise1
cmd
scoop uninstall mise1
提醒
- ① winget 和 scoop 是两个独立的 Windows 包管理器,它们互不依赖。
- ② 使用什么包管理器安装 mise ,就使用对应的包管理器卸载 mise 。
- 示例:winget 卸载
cmd
winget uninstall --id jdx.mise1

- 示例:scoop 卸载
cmd
scoop uninstall mise1

1.2.3 mise 安装
- 命令:
cmd
scoop install mise1
cmd
winget install --id jdx.mise1
提醒
- ① 推荐 Scoop 方式,因为其会自动将 Shims 添加到 PATH 中;但是,如果使用 winget 安装,需要手动在 PowerShell 中激活 Shims 。
- ② 如果后续需要更新 mise ,请执行如下的命令:
cmd
scoop update mise1
cmd
winget upgrade --id jdx.mise1
- 示例:winget 安装
cmd
winget install --id jdx.mise1

- 示例:scoop 安装
cmd
scoop install mise1

1.2.4 mise 激活
- 命令:
powershell
# ① 创建目录
# PowerShell 5.1 用户
if (!(Test-Path "$HOME\Documents\WindowsPowerShell")) {
New-Item -Path "$HOME\Documents\WindowsPowerShell" -ItemType Directory
}
# PowerShell 7+ 用户
if (!(Test-Path "$HOME\Documents\PowerShell")) {
New-Item -Path "$HOME\Documents\PowerShell" -ItemType Directory
}
# ② 写入 mise 初始化命令
# PowerShell 5.1 用户
"`n`$env:MISE_PWSH_CHPWD_警告 = 0" | Add-Content $PROFILE
'(&mise activate pwsh) | Out-String | Invoke-Expression' | Add-Content -Path "$HOME\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1"
# PowerShell 7+ 用户
"`n`$env:MISE_PWSH_CHPWD_警告 = 0" | Add-Content $PROFILE
'(&mise activate pwsh) | Out-String | Invoke-Expression' | Add-Content -Path "$HOME\Documents\PowerShell\Microsoft.PowerShell_profile.ps1"
# ③ 验证配置文件内容
notepad $PROFILE # (&mise activate pwsh) | Out-String | Invoke-Expression
# 重新加载配置
. $PROFILE1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
提醒
- ① 不管 winget 或 scoop,都需要手动在 PowerShell 中激活 mise ,这样可以实现切换目录自动加载 mise.toml ,以便自动切换工具。
- ② 不推荐使用 cmd ,因为 cmd 不能实现这项功能。
- 示例:
powershell
# ① 创建目录
# PowerShell 5.1 用户
if (!(Test-Path "$HOME\Documents\WindowsPowerShell")) {
New-Item -Path "$HOME\Documents\WindowsPowerShell" -ItemType Directory
}
# PowerShell 7+ 用户
if (!(Test-Path "$HOME\Documents\PowerShell")) {
New-Item -Path "$HOME\Documents\PowerShell" -ItemType Directory
}
# ② 写入 mise 初始化命令
# PowerShell 5.1 用户
"`n`$env:MISE_PWSH_CHPWD_警告 = 0" | Add-Content $PROFILE
'(&mise activate pwsh) | Out-String | Invoke-Expression' | Add-Content -Path "$HOME\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1"
# PowerShell 7+ 用户
"`n`$env:MISE_PWSH_CHPWD_警告 = 0" | Add-Content $PROFILE
'(&mise activate pwsh) | Out-String | Invoke-Expression' | Add-Content -Path "$HOME\Documents\PowerShell\Microsoft.PowerShell_profile.ps1"
# ③ 验证配置文件内容
notepad $PROFILE # (&mise activate pwsh) | Out-String | Invoke-Expression
# 重新加载配置
. $PROFILE1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

1.3 mise 安装(Linux)
1.3.1 mise 卸载
- 命令:
shell
# 自毁式卸载命令
mise implode [-y|--yes]1
2
2
cmd
# 推荐方式,根据各自的系统版本使用对应的包管理器
dnf -y remove mise1
2
2
shell
# 推荐方式,根据各自的系统版本使用对应的包管理器
apt -y remove mise1
2
2
注意
- ① 自毁式卸载命令(前提条件是:通过脚本安装)执行该命令,会移除 mise 本身及其所有管理的数据(所有由 mise 安装的工具版本、配置、缓存、状态数据)。
- ② 也可以手动移除以下目录以彻底清理,如下所示:
| 目录 | 说明 | 环境变量覆盖 |
|---|---|---|
~/.local/share/mise | 数据目录 | MISE_DATA_DIR / XDG_DATA_HOME/mise |
~/.local/state/mise | 状态目录 | MISE_STATE_DIR / XDG_STATE_HOME/mise |
~/.config/mise | 配置目录 | MISE_CONFIG_DIR / XDG_CONFIG_HOME/mise |
~/.cache/mise (Linux) | 缓存目录 | MISE_CACHE_DIR / XDG_CACHE_HOME/mise |
~/Library/Caches/mise (MacOS) | 缓存目录 | MISE_CACHE_DIR |
- ③ 不可逆操作:
implode会永久删除所有已安装的工具版本,请提前备份重要数据。 - ④
-y|--yes:该命令默认会询问用户是否删除,一旦加上 -y 参数,用户无需回答直接删除。 - ⑤ 如果通过 bash、zsh 以及 fish ,还需要在卸载之后,手动将
~/.zshrc、~/.bashrc或~/.config/fish/config.fish中的激活配置删除。
- 示例:脚本方式卸载
shell
# 卸载自身
mise implode -y
# 清理的配置文件列表
sed -i '/mise activate/d' ~/.bashrc && source ~/.bashrc
sed -i '/mise activate/d' ~/.zshrc && source ~/.zshrc
sed -i '/mise activate/d' ~/.config/fish/config.fish && source ~/.config/fish/config.fish1
2
3
4
5
6
7
2
3
4
5
6
7

- 示例:AlmaLinux 卸载(推荐)
shell
dnf -y remove mise1

- 示例:Ubuntu 卸载(推荐)
shell
apt -y remove mise1

1.3.2 mise 安装&激活
- 命令:
shell
# 通用安装方式,需要根据提示手动激活
curl https://mise.run | sh1
2
2
shell
# 推荐方式,根据各自的系统版本使用对应的包管理器
# Fedora 41+,RHEL 9+,CentOS Stream 9+
# 安装
dnf copr enable jdxcode/mise -y
dnf install mise -y
# 激活
grep -q "mise activate" ~/.bashrc || echo 'eval "$(mise activate bash)"' >> ~/.bashrc
grep -q "mise activate" ~/.zshrc || echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
grep -q "mise activate" ~/.config/fish/config.fish || echo "mise activate fish | source" >> ~/.config/fish/config.fish1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
shell
# 推荐方式,根据各自的系统版本使用对应的包管理器
# Ubuntu 26.04 之前的版本
# 安装
sudo apt update -y && sudo apt install -y curl
sudo install -dm 755 /etc/apt/keyrings
curl -fSs https://mise.jdx.dev/gpg-key.pub | sudo tee /etc/apt/keyrings/mise-archive-keyring.asc 1> /dev/null
echo "deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.asc] https://mise.jdx.dev/deb stable main" | sudo tee /etc/apt/sources.list.d/mise.list
sudo apt update -y
sudo apt install -y mise
# 激活
grep -q "mise activate" ~/.bashrc || echo 'eval "$(mise activate bash)"' >> ~/.bashrc
grep -q "mise activate" ~/.zshrc || echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
grep -q "mise activate" ~/.config/fish/config.fish || echo "mise activate fish | source" >> ~/.config/fish/config.fish
# Ubuntu 26.04+ 之后的版本
# 安装
sudo add-apt-repository -y ppa:jdxcode/mise
sudo apt update -y
sudo apt install -y mise
# 激活
grep -q "mise activate" ~/.bashrc || echo 'eval "$(mise activate bash)"' >> ~/.bashrc
grep -q "mise activate" ~/.zshrc || echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
grep -q "mise activate" ~/.config/fish/config.fish || echo "mise activate fish | source" >> ~/.config/fish/config.fish1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
提醒
- ① 包管理器(apt、dnf、brew、pacman 等)在更新系统包时会更新 mise 。
- ② 通过
curl的方式可以通过mise self-update进行更新。
- 示例:脚本方式安装,并根据提示激活
shell
curl https://mise.run | sh1

- 示例:AlmaLinux 安装&激活
shell
# 安装
dnf copr enable jdxcode/mise -y
dnf install mise -y
# 激活
grep -q "mise activate" ~/.bashrc || echo 'eval "$(mise activate bash)"' >> ~/.bashrc
grep -q "mise activate" ~/.zshrc || echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
grep -q "mise activate" ~/.config/fish/config.fish || echo "mise activate fish | source" >> ~/.config/fish/config.fish1
2
3
4
5
6
7
2
3
4
5
6
7

- 示例:Ubuntu 安装&激活
shell
# 安装
sudo apt update -y && sudo apt install -y curl
sudo install -dm 755 /etc/apt/keyrings
curl -fSs https://mise.jdx.dev/gpg-key.pub | sudo tee /etc/apt/keyrings/mise-archive-keyring.asc 1> /dev/null
echo "deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.asc] https://mise.jdx.dev/deb stable main" | sudo tee /etc/apt/sources.list.d/mise.list
sudo apt update -y
sudo apt install -y mise
# 激活
grep -q "mise activate" ~/.bashrc || echo 'eval "$(mise activate bash)"' >> ~/.bashrc
grep -q "mise activate" ~/.zshrc || echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
grep -q "mise activate" ~/.config/fish/config.fish || echo "mise activate fish | source" >> ~/.config/fish/config.fish1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11

1.3.3 命令自动补全
- 命令:
shell
# 安装 usage 包
mise use -g usage
# 安装命令自动补全脚本
mkdir -p ~/.local/share/bash-completion/completions/
echo 'mise completion bash --include-bash-completion-lib' > ~/.local/share/bash-completion/completions/mise
# 重启 shell
exec bash1
2
3
4
5
6
7
2
3
4
5
6
7
shell
# 安装 usage 包
mise use -g usage
# 安装命令自动补全脚本
echo $fpath | tr ' ' '\n'
mkdir -p /usr/local/share/zsh/site-functions
mise completion zsh > /usr/local/share/zsh/site-functions/_mise
# 重启 shell
exec zsh1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
shell
# 安装 usage 包
mise use -g usage
# 安装命令自动补全脚本
mise completion fish > ~/.config/fish/completions/mise.fish
# 重启 shell
exec fish1
2
3
4
5
6
2
3
4
5
6
提醒
命令自动补全:当我们输入命令的部分内容时,按特定按键(Tab),系统会自动帮助我们 补全剩余部分 或 列出可能的选项,如:mise inst → mise install 。
- 示例:演示 fish 命令自动补全
shell
# 安装 usage 包
mise use -g usage
# 安装命令自动补全脚本
mise completion fish > ~/.config/fish/completions/mise.fish
# 重启 shell
exec fish1
2
3
4
5
6
2
3
4
5
6

1.4 Docker
如果是使用 Docker ,就需要使用
jdxcode/mise镜像了。示例:Docker 命令行方式
shell
docker run jdxcode/mise x node@20 -- node -v1

- 示例:Dockerfile 方式
dockerfile
FROM jdxcode/mise:latest AS mise
FROM ubuntu:24.04
RUN apt -y update && \
apt -y upgrade && \
apt -y install curl && \
rm -rf /var/lib/apt/lists/*
COPY --from=mise /usr/local/bin/mise /usr/local/bin/mise
RUN mise trust -a
RUN mise use -g node@lts
ENTRYPOINT ["/bin/bash", "-c", "source <(mise activate --shims bash) && exec \"$@\"", "--"]
CMD ["bash"]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bash
docker build --progress=plain --no-cache -t test . && \
docker run -it test1
2
2

第二章:演示 mise 的功能
2.1 运行指定版本工具的 shell 命令
- mise 提供的重要的功能是运行指定版本工具的 shell 命令,并且无需修改 Shell 会话。
bash
mise exec|x [OPTIONS] [TOOL@VERSION]... [-- <COMMAND>...]1
提醒
- ①
[OPTIONS]:参数
| 参数 | 说明 | 场景 |
|---|---|---|
-c, --command <C> | 将后面的字符串作为一个完整的命令执行 | 当需要运行多个命令(如 cmd1 && cmd2)或者命令包含复杂空格时使用,如:"node -v && python -V"。 |
-j, --jobs <JOBS> | 并行安装或准备工具的任务数量,默认是 4 。 | 如果同时加载很多工具,增加此值可能加快速度。 |
-C, --cd <DIR> | 在执行命令前,先切换到指定目录 | 相当于 cd <DIR> && 命令,但不需要手动 cd |
-E, --env | 指定加载特定的环境配置文件。 | 默认加载 mise.toml,如果设为 prod,则会加载 mise.prod.toml。 |
q, --quiet | 安静模式。 | 抑制非错误信息的输出。 |
-v, --verbose | 详细模式。 | 显示更多调试信息。使用 -vv 会显示更多信息。 |
- ②
[TOOL@VERSION]:工具版本,如:node@20、python@3.10 等。 - ③
[-- <COMMAND>...]:用于执行的命令;其中,--用于分隔运行时环境与传递给子进程的命令。
注意
- ① 该命令是一个
“用完即焚”的命令,它只在执行那一条指令的瞬间生效,执行完毕之后,终端环境会像什么都没发生过一样保持原样。我们不需要为了跑这一个命令而去改变整个终端的状态。 - ② 该命令会从
mise.toml加载配置;但是,会优先加载命令中包含的工具版本[TOOL@VERSION];但是,如果mise.toml中包含了node 20,即使我们mise exec python@3.11,node@20 依然会被加载。
- 示例:基本用法(临时加载 node@25,并打印其版本)
bash
mise exec node@25 -- node -v1

- 示例:别名用法(临时加载 node@24,并打印其版本)
bash
mise x node@24 -- node -v1

- 示例:命令字符串(临时加载 node@20 和 python@3.11,并打印其版本)
bash
mise exec node@20 python@3.11 --command "node -v && python -V"1

- 示例:切换目录运行
bash
echo "console.log('node@20')" > /var/app.js
mise x -C /var node@20 -- node ./app.js1
2
2

2.2 全局安装
mise exec|x非常适合运行一次性的命令;但是有的时候,我们需要将其设置为全局,即:激活 mise 。
bash
mise use [OPTIONS] [TOOL@VERSION]...1
提醒
- ①
[OPTIONS]:参数
| 参数 | 说明 |
|---|---|
-g, --global | 写入全局配置文件(~/.config/mise/config.toml)中的信息,而非局部 |
-p,--path <PATH> | 写入指定路径的配置文件 |
-e,--env <ENV> | 写入 mise.<ENV>.toml ,如: mise.staging.toml |
- ②
[TOOL@VERSION]:工具版本,如:node@20、python@3 等。
注意
- ① 激活 mise 后,mise 会自动更新 PATH 设置,使其包含已安装的工具,从而可以直接使用它们。
- ② 激活 mise 后,得到的是真实的路径,而不是垫片。
- 示例:安装并设置为全局默认工具
bash
# 将 node@lts、jq、go 等设置为全局默认工具
mise use -g node@lts jq go
# 查询全局默认工具的版本
node -v
jq --version
go version1
2
3
4
5
6
2
3
4
5
6

- 示例:查看是否更新 PATH
bash
# 查看环境变量
echo $PATH
# 安装指定版本的工具
mise use -g node@22
# 查看环境变量
echo $PATH1
2
3
4
5
6
2
3
4
5
6

- 示例:查看工具设置为全局,返回的是否是真实路径
bash
which node1

2.3 开发中如何管理多个环境
- 在项目开发中,可能不同的目录,使用不同的工具,如:Vue3.x 需要 Node.js 和 pnpm ,而 SpringBoot 3.5.x 需要 JDK17 和 Gradle ,如下所示:
bash
mall
├── mise.toml # [重要] 项目级工具锁定
├── frontend/ # 前端代码
├──── mise.toml # 前端项目工具锁定
├── backend/ # 后端代码
├──── mise.toml # 后端项目工具锁定1
2
3
4
5
6
2
3
4
5
6
- 示例:创建项目目录
bash
mkdir -pv mall/{frontend,backend}1

- 示例:在顶级目录 mall 中安装 node、jdk、gradle 以及 pnpm
bash
# 进入顶级目录 mall
cd mall
# 安装依赖
mise use node@lts java@25 gradle@9 pnpm@101
2
3
4
2
3
4

- 示例:在前端项目 mall/frontend 中安装 node(20)和 pnpm(9)
bash
# 进入前端项目 mall/frontend
cd frontend
# 在前端项目中安装工具
mise use --path mise.toml node@20 pnpm@9
# 使用 vite 脚手架生成对应的 Vue 项目模板
pnpm create vite . --template vue-ts1
2
3
4
5
6
2
3
4
5
6

- 示例:在后端项目 mall/backend 中安装 JDK(17) 和 Gradle(8)
bash
# 进入后端项目 mall/backend
cd ../backend
# 在后端项目中安装工具
mise use --path mise.toml java@17 gradle@8
# 使用 SpringBoot 脚手架生成对应的 SpringBoot 项目模板
mise use spring-boot@3.5.0
spring init \
--dependencies=web,lombok \
--type=gradle-project \
--language=java \
--boot-version=3.5.0 \
--name=demo \
--description="演示项目" \
--groupId=com.github \
--artifactId=demo \
--version=v1.0 \
--package-name=com.github.demo \
--java-version=17 \
--extract
# Gradle 加速
sed -i 's|services.gradle.org/distributions|mirrors.cloud.tencent.com/gradle|g' \
./gradle/wrapper/gradle-wrapper.properties
sed -i '/^rootProject.name/i\
pluginManagement {\
repositories {\
maven { url "https://mirrors.cloud.tencent.com/nexus/repository/maven-public/" }\
maven { url "https://maven.aliyun.com/repository/public/" }\
gradlePluginPortal()\
mavenCentral()\
}\
}\
\
dependencyResolutionManagement {\
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)\
repositories {\
maven { url "https://mirrors.cloud.tencent.com/nexus/repository/maven-public/" }\
maven { url "https://maven.aliyun.com/repository/public/" }\
mavenCentral()\
}\
}\
' settings.gradle
# Gradle 编译
./gradlew clean build -x test
# 启动
./gradlew bootRun1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

第三章:TOML
3.1 概述
- TOML 是为人而生的配置文件格式,即:TOML 旨在成为一个语义明显且易于阅读的最小化配置文件格式,TOML 被设计成可以无歧义地映射为哈希表。TOML 应该能很容易地被解析成各种语言中的数据结构。

3.2 注释
- 语法:TOML 支持以
#开头的注释 ,除非它在字符串中。
toml
# 这就是注释1
- 示例:全行注释
toml
# 这是 TOML 中的全行注释
key = "value"1
2
2

- 示例:行末注释
toml
key = "value" # 这是 TOML 中的行末注释1

- 示例:
#在字符串中,就不是注释
toml
key = "# 这真的不是注释"1

3.3 键值对
- 语法:键、等号和值必须在同一行(不过有些值可以跨多行)。
toml
key = "value"1
提醒
- ①
值只能是字符串、整数、浮点型、布尔值、日期时刻、数组以及内联表。 - ② 不指定
值是非法的。 - ③
键值对后必须换行或结束文件,除非是内联表。 - ④ 在不引起歧义的情况下,
键是可以省略""的,即:键可以是裸露的。 - ⑤
键中可以使用.分隔,这样可以将相近的属性放在一起。 - ⑥
键中.分隔符周围的空格会被忽略(不建议)。 - ⑦
键只能包含 ASCII 字母,ASCII 数字,下划线和短横线;但是,如果是纯 ASCII 数字,将被解释为字符串。 - ⑧ 多次定义同一个
键是非法的,因为哈希表中键是不同重复的。 - ⑨ 只要
键还没有直接被定义,依然可以对它和它下属的键赋值。 - ⑩ 不建议以
乱序的方式定义点状键。
- 示例:正常键值对
toml
key = "value"
bare_key = "value"
bare-key = "value"
1234 = "value"1
2
3
4
2
3
4

- 示例:在引起歧义的情况下,
键名是不可以省略""的(不建议,尽量见名知意)
toml
"127.0.0.1" = "value"
"character encoding" = "value"
"ʎǝʞ" = "value"
'key2' = "value"
'quoted "value"' = "value"1
2
3
4
5
2
3
4
5

- 示例:
点分隔键是一系列通过点相连的裸键或引号键
toml
name = "Orange"
# 这样可以将相近的属性放在一起。
physical.color = "orange"
physical.shape = "round"
site."google.com" = true1
2
3
4
5
2
3
4
5

- 示例:
键中.分隔符周围的空格会被忽略(不建议)
toml
fruit.name = "banana"
fruit. color = "yellow"
fruit . flavor = "banana"1
2
3
2
3

- 示例:多次定义同一个
键是非法的
toml
# ❌️`哈希表` 中 `键` 是不同重复的
name = "Tom"
name = "Pradyun"1
2
3
2
3

- 示例:只要
键还没有直接被定义,依然可以对它和它下属的键赋值
toml
# 这使“fruit”键作为表存在。
fruit.apple.smooth = true
# 接下来可以对“fruit”表添加内容
fruit.orange = 21
2
3
4
5
2
3
4
5

- 示例:只要
键还没有直接被定义,依然可以对它和它下属的键赋值
toml
# 这将 fruit.apple 的值定义为一个整数。
fruit.apple = 1
# 但接下来这将 fruit.apple 像表一样对待了。
# ❌️ 整数不能变成表。
fruit.apple.smooth = true1
2
3
4
5
6
2
3
4
5
6

- 示例:不建议以
乱序的方式定义点状键
toml
# 合法但不鼓励
apple.type = "水果"
orange.type = "水果"
apple.skin = "薄"
orange.skin = "厚"
apple.color = "红"
orange.color = "橙"1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10

- 示例:不建议以
乱序的方式定义点状键
toml
# 建议
apple.type = "水果"
apple.skin = "薄"
apple.color = "红"
orange.type = "水果"
orange.skin = "厚"
orange.color = "红"1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9

3.4 值的数据类型
3.4.1 字符串
- 语法:字符串使用
""包裹
toml
str = "我是字符串"1
提醒
- ①
基本字符串使用"包裹,可以使用转义字符,如:\n、\"等。 - ②
多行基本字符串使用"""包裹,允许折行,并且紧随开头引号的那个换行会被去除,其它空白和换行会被原样保留。 - ③
字面量字符串使用'包裹,类似于基本字符串;但是,不支持转义字符。 - ④
多行字面量字符串使用'''包裹,类似于多行基本字符串,允许折行;但是,不支持转义字符。
- 示例:基本字符串
toml
str = "我是一个字符串"1

- 示例:多行基本字符串
toml
str = """
你是谁?
我是谁?
哈哈?
"""1
2
3
4
5
2
3
4
5

- 示例:字面量字符串(不常用)
toml
winpath = 'C:\Users\nodejs\templates'
winpath2 = '\\ServerX\admin$\system32\'
quoted = 'Tom "Dubs" Preston-Werner'
regex = '<\i\c*\s*>'1
2
3
4
2
3
4

- 示例:多行字面量字符串(不常用)
toml
winpath = 'C:\Users\nodejs\templates'
winpath2 = '\\ServerX\admin$\system32\'
quoted = 'Tom "Dubs" Preston-Werner'
regex = '<\i\c*\s*>'1
2
3
4
2
3
4

3.4.2 整数
- 语法:支持纯数字、二进制(八进制、十六进制)
toml
num = 1001
提醒
- ①
整数可以是自然数,正数可以在前面加+(通常不需要),负数可以在前面加-。 - ② 对于
大数,为了增强阅读性,可以在数字之间使用_来分隔;但是,每个下划线两侧必须至少有一个数字,如:1_000、5_234_222等。 - ③
整数中也支持二进制、八进制以及十六进制,规则和编程语言中一样。
- 示例:纯数字
toml
# 正数可以以加号为前缀,负数以减号为前缀。
int1 = +99
int2 = 42
int3 = 0
int4 = -17
# 对于大数,可以使用 _ 来增强可读性
int5 = 1_000
int6 = 5_349_2211
2
3
4
5
6
7
8
2
3
4
5
6
7
8

- 示例:二进制、八进制、十六进制
toml
# 带有 `0x` 前缀的十六进制
hex1 = 0xDEADBEEF
hex2 = 0xdeadbeef
hex3 = 0xdead_beef
# 带有 `0o` 前缀的八进制
oct1 = 0o01234567
oct2 = 0o755 # 对于表示 Unix 文件权限很有用
# 带有 `0b` 前缀的二进制
bin1 = 0b110101101
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11

3.4.3 浮点数
- 语法:支持 IEEE 754 标准
toml
d = 3.141
提醒
浮点数 还支持 无穷 和 非数(几乎不用),如下所示:
toml
# 无穷
sf1 = inf # 正无穷
sf2 = +inf # 正无穷
sf3 = -inf # 负无穷
# 非数
sf4 = nan # 实际上对应信号非数码还是静默非数码,取决于实现
sf5 = +nan # 等同于 `nan`
sf6 = -nan # 有效,实际码取决于实现1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 示例:小数、指数
toml
# 小数
flt1 = +1.0
flt2 = 3.1415
flt3 = -0.01
# 指数
flt4 = 5e+22
flt5 = 1e06
flt6 = -2E-2
# 都有
flt7 = 6.626e-341
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12

3.4.4 布尔型
- 语法:只支持 true 或 false
toml
bool = true1
提醒
布尔型 中的 true 或 false 必须小写,和 python 中的不一样!!!
- 示例:
toml
bool1 = true
bool2 = false1
2
2

3.4.5 日期时刻
- 语法:支持 RFC 3339 格式
toml
date = 1979-05-27T07:32:00Z1
- 示例:
toml
odt1 = 1979-05-27T07:32:00Z
odt2 = 1979-05-27T00:32:00-07:00
odt3 = 1979-05-27T00:32:00.999999-07:001
2
3
2
3

3.4.6 数组
- 语法:使用
[]包裹,空格会被忽略,元素之间使用,分隔
toml
arr = [1,2,3]1
提醒
- ①
数组允许相同数据类型的值,也可以混用不同数据类型的值(不建议)。 - ②
数组可以跨行,数值中的最后一个值后面可以有尾逗号(也可以没有,类似于 JavaScript)。 - ③
数组支持嵌套。
- 示例:数组允许相同数据类型的值
toml
nums = [ 1, 2, 3 ]
colors = [ "红", "黄", "绿" ]1
2
2

- 示例:数组允许混用不同数据类型的值(不建议)
toml
numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
contributors = [
"Foo Bar <foo@example.com>",
{ name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
]1
2
3
4
5
2
3
4
5

- 示例:数组可以跨行
toml
integers2 = [
1, 2, 3
]1
2
3
2
3

- 示例:数值中的最后一个值后面可以有尾逗号
toml
integers3 = [
1,
2, # 这是可以的
]1
2
3
4
2
3
4

- 示例:数组支持嵌套
toml
coordinates = [
[ 10, 20 ],
[ 30, 40 ]
]
string_array = [
"all",
'strings',
"""are the same""",
'''type'''
]1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10

3.5 表
- 语法:表(哈希表或字典)是键值对的集合
toml
[table] # 表头
key1 = value # 键值对1
2
2
提醒
- ①
表由表头和下面的键值对组成,表头单独作为行出现,而下面的键值对直到遇到下一个表头或文件结束。 - ②
表头的命名规则和键的命名规则保持一致。 - ③
空表是允许的,只要里面没有键值对就行了。 - ④ 和
键类似,不可以重复定义一个表。 - ⑤ 顶层表(根表),于文档开始处开始并在第一个表头(或文件结束处)前结束(不同于其它表,它没有名字且无法后置)。
- ⑥ 点分隔键为最后一个键名前的每个键名创建并定义一个表,倘若这些表尚未被创建的话。
- ⑦ 使用点分隔键来重定义已经以
[table]形式定义过的表也是不允许的;但是,[table]形式可以被用来定义通过点分隔键定义的表中的子表。 - ⑧
表头不同于数组,因为数组中只有值。
- 示例:键值对
toml
profile.age = 18
profile.address = "shanghai"1
2
2

- 示例:键值对的正式写法(表)
toml
[profile]
age = 18
address = "shanghai"1
2
3
2
3

- 示例:
表头的命名规则和键的命名规则保持一致
toml
[dog.tater.man]
type.name = "pug"1
2
2

- 示例:表不可以重复定义
toml
[fruit]
apple = "红"
# ❌️ 表不能重复定义
[fruit]
orange = "橙"1
2
3
4
5
6
2
3
4
5
6

- 示例:表不可以再次被赋值
toml
[fruit]
apple = "红"
# ❌️ 表不可以再次被赋值
[fruit.apple]
texture = "光滑"1
2
3
4
5
6
2
3
4
5
6

- 示例:顶层表(根表),于文档开始处开始并在第一个表头(或文件结束处)前结束
toml
# 顶层表开始。
name = "Fido"
breed = "pug"
# 顶层表结束。
[owner]
name = "Regina Dogman"
member_since = 1999-08-041
2
3
4
5
6
7
8
2
3
4
5
6
7
8

- 示例:点分隔键为最后一个键名前的每个键名创建并定义一个表,倘若这些表尚未被创建的话
toml
# 定义一个名为 fruit 的表
# 定义一个名为 fruit.apple 的表
fruit.apple.color = "red"
# 定义一个名为 fruit.apple.taste 的表
# fruit 和 fruit.apple 已经创建过了
fruit.apple.taste.sweet = true1
2
3
4
5
6
7
2
3
4
5
6
7

- 示例:
[table]形式可以被用来定义通过点分隔键定义的表中的子表。
toml
[fruit]
apple.color = "红"
apple.taste.sweet = true
# [fruit.apple] # 非法
# [fruit.apple.taste] # 非法
[fruit.apple.texture] # 可以添加子表
smooth = true1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9

3.6 内联表
- 语法:内联表提供了一种更为紧凑的语法来表示表
toml
name = { first = "Tom", last = "Preston-Werner" }1
提醒
- ① 内联表被完整地定义在花括号之中:
{和},括号中,可以出现零或更多个以逗号分隔的键值对。 - ② 键值对采取与标准表中的键值对相同的形式。并且,值的类型什么都可以,包括内联表。
- ③ 内联表必须出现在同一行内。
- ④ 内联表中,最后一对键值对后不允许终逗号(也称为尾逗号)。
- ⑤ 强烈不建议把一个内联表搞成纵跨多行的样子;换言之,如果发现自己真的需要,那意味着你应该使用标准表。
- 示例:标准表
toml
[name]
first = "Tom"
last = "Preston-Werner"
[point]
x = 1
y = 2
[animal]
type.name = "pug"1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10

- 示例:内联表
toml
name = { first = "Tom", last = "Preston-Werner" }
point = { x = 1, y = 2 }
animal = { type.name = "pug" }1
2
3
2
3

- 示例:内联表不能在括号以外的地方,再添加键与子表
toml
[product]
type = { name = "Nail" }
# type.edible = false # 非法1
2
3
2
3

3.7 表数组
- 语法:表数组就是值是数组的表,使用
[[]]包裹
toml
[[products]]
name = "Hammer"
sku = 738594937
[[products]] # 数组里的空表
[[products]]
name = "Nail"
sku = 284758393
color = "gray"1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
提醒
- ① 任何对表数组的引用都指向该数组里最近定义的表元素,即:允许在最近的表内定义子表,甚至子表数组。
- ② 如果一个表或表数组的父级是一个数组元素,该元素必须在定义子级前先定义。
- ③ 若试图向一个静态定义的数组追加内容,即便数组尚且为空,也必须在解析时报错。
- ④ 若试图用已经确定为数组的名称定义表,必须在解析时报错。
- ⑤ 不同于
表,表数组中的表头可以出现多次。
- 示例:不同于表头,同名的表数组可以出现多次
toml
[[profile]]
name = "Jason Yu"
age = 18
[[profile]]
name = "Alice"
age = 201
2
3
4
5
6
2
3
4
5
6

- 示例:任何对表数组的引用都指向该数组里最近定义的表元素(允许在最近的表内定义子表,甚至子表数组)
toml
[[fruits]] # 表数组
name = "apple"
[fruits.physical] # 子表
color = "red"
shape = "round"
[[fruits.varieties]] # 嵌套表数组
name = "red delicious"
[[fruits.varieties]] # 嵌套表数组
name = "granny smith"
[[fruits]] # 表数组
name = "banana"
[[fruits.varieties]] # 嵌套表数组
name = "plantain"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

- 示例:如果一个表或表数组的父级是一个数组元素,该元素必须在定义子级前先定义
toml
[fruit.physical] # ❌️ 子表,但它应该隶属于哪个父元素?
color = "red"
shape = "round"
[[fruit]] # 解析器必须在发现“fruit”是数组而非表时抛出错误
name = "apple"1
2
3
4
5
6
2
3
4
5
6

- 示例:若试图向一个静态定义的数组追加内容,即便数组尚且为空,也必须在解析时报错
toml
fruits = []
[[fruits]] # ❌️ 不允许1
2
3
2
3

- 示例:若试图用已经确定为数组的名称定义表,必须在解析时报错
toml
[[fruits]]
name = "apple"
[[fruits.varieties]]
name = "red delicious"
[fruits.varieties] # ❌️ 非法:该表与之前的表数组相冲突
name = "granny smith"1
2
3
4
5
6
7
8
2
3
4
5
6
7
8

- 示例:若将数组重定义为普通表的行为,也必须在解析时报错
toml
[fruits.physical]
color = "red"
shape = "round"
# ❌️ 非法:该表数组与之前的表相冲突
[[fruits.physical]]
color = "green"1
2
3
4
5
6
7
2
3
4
5
6
7

3.8 表 VS 表数组
3.8.1 基本定义和语法
表和表数组的基本定义和语法,如下所示:
| 特性 | 表 (Table) | 表数组 (Table Array) |
|---|---|---|
| 语法符号 | 单中括号 [name] | 双中括号 [[name]] |
| 数据结构 | 单个对象 / 字典 (Object / Dict) | 对象数组 / 列表 (Array of Objects) |
| JSON 对应 | { "name": { ... } } | { "name": [ { ... }, { ... } ] } |
| 用途 | 定义唯一的配置块 | 定义多个结构相同的配置块 |
- 示例:
表用于表示单个实体,如下所示:
toml
[server]
ip = "192.168.1.1"
port = 8080
enabled = true1
2
3
4
2
3
4

- 示例:
表数组用于表示多个同类型的实体列表,如下所示:
toml
[[servers]]
ip = "192.168.1.1"
port = 8080
[[servers]]
ip = "192.168.1.2"
port = 80811
2
3
4
5
6
7
2
3
4
5
6
7

3.8.2 核心区别
表和表数组的核心区别,如下所示:
| 区别 | 表 (Table) | 表数组 (Table Array) |
|---|---|---|
| 数量限制 | 在同一个层级下,同一个表名通常只能定义一次,即:它代表“一个” | 可以重复多次出现同一个名称,即:每一次 [[name]] 都向该数组中添加一个新的元素,即:它代表“多个”。 |
| 数据层级 | 直接包含键值对。 | 包含的是一个列表,列表中的每一项才是一个包含键值对的表。 |
| 嵌套行为 | 可以通过点号嵌套,如: [parent.child] | 可以在表数组内部嵌套普通表或另一个表数组 |
3.8.3 常见误区
3.8.3.1 误区 1
- 误区:表数组不是“包含数组的表”。
toml
[[servers]]
ip = "192.168.1.1"
port = 8080
[[servers]]
ip = "192.168.1.2"
port = 80811
2
3
4
5
6
7
2
3
4
5
6
7
- 示例:❌️ 错误理解
txt
[[servers]] 意味着 servers 表里有一个数组字段。1
- 示例:✅️ 正确理解
txt
[[servers]] 意味着 servers 本身就是一个数组,数组里的元素是表。1
3.8.3.2 误区 2
误区:不能先定义一个普通表,再定义同名的表数组,反之亦然。
示例:❌️ 错误范例
toml
[fruit]
variety = "apple"
# ❌️ fruit 已经被定义为普通表,不能变成表数组
[[fruit]]
variety = "banana"1
2
3
4
5
6
2
3
4
5
6

3.8.3.3 误区 3
误区:在 TOML 中,表数组的定义顺序通常对应生成列表的顺序。
示例:
toml
[[items]]
name = "First"
# 解析后列表顺序为 [First, Second]
[[items]]
name = "Second"1
2
3
4
5
6
7
2
3
4
5
6
7

3.8.4 总结
- 表 VS 表数组,如下所示:
| 维度 | 表 [name] | 表数组 [[name]] |
|---|---|---|
| 直观理解 | 一个配置块 | 一堆配置块 |
| 编程模型 | Config.Server | Config.Servers[0], Config.Servers[1] |
| 适用场景 | 数据库连接、应用元数据、单例配置 | 集群节点、多用户列表、多个插件配置 |
| 语法特征 | 单括号 | 双括号 |
- 如果只需要配置
一个东西(主数据库),使用表。 - 如果需要配置
一堆相同结构的东西(多个从数据库节点),使用表数组。
第四章:Mise 的核心功能
4.1 概述
- mise 决了通常需要使用不同工具来解决的三个基本开发挑战,如下所示:
| 挑战 | 传统方式 | mise 解决方案 |
|---|---|---|
| 多工具版本管理 | 分别使用 nvm, pyenv, rbenv | 所有语言的统一接口 |
| 环境变量管理 | 手动 export 或 direnv 配置 | 按项目自动加载 |
| 任务执行 | Make, npm scripts, shell scripts | 带有自动发现功能的统一任务系统 |
- 这意味着我们可以使用一个一致的接口来管理 Node.js、Python、Ruby、Go、Terraform 以及数百种其他工具。
- 当我们切换项目时,mise 会自动切换版本,为不同上下文管理环境变量,并提供强大的任务运行器用于构建和测试。
4.2 Mise 环境集成方法
- Mise 提供了三种主要方法和我们的开发环境进行集成,如下所示:
| 方法 | 使用案例 | 激活方式 |
|---|---|---|
| 自动激活 | 日常开发工作 | 在 shell 配置中使用 eval "$(mise activate zsh)" |
| 按需执行 | 在不激活的情况下运行命令 | mise exec -- node my-script.js |
| Shims | IDE 集成 | mise activate --shims 创建包装脚本 |
4.3 Mise 的核心特性
4.3.1 多版本工具管理
- 在项目开发中,可能不同的目录,使用不同的工具,如:Vue3.x 需要 Node.js 和 pnpm ,而 SpringBoot 3.5.x 需要 JDK17 和 Gradle ,如下所示:
bash
mall
├── mise.toml # [重要] 项目级工具锁定
├── frontend/ # 前端代码
├──── mise.toml # 前端项目工具锁定
├── backend/ # 后端代码
├──── mise.toml # 后端项目工具锁定1
2
3
4
5
6
2
3
4
5
6
- 示例:创建项目目录
bash
mkdir -pv mall/{frontend,backend}1

- 示例:在顶级目录 mall 中安装 node、jdk、gradle 以及 pnpm
bash
# 进入顶级目录 mall
cd mall
# 安装依赖
mise use node@lts java@25 gradle@9 pnpm@101
2
3
4
2
3
4

- 示例:在前端项目 mall/frontend 中安装 node(20)和 pnpm(9)
bash
# 进入前端项目 mall/frontend
cd frontend
# 在前端项目中安装工具
mise use --path mise.toml node@20 pnpm@9
# 使用 vite 脚手架生成对应的 Vue 项目模板
pnpm create vite . --template vue-ts1
2
3
4
5
6
2
3
4
5
6

- 示例:在后端项目 mall/backend 中安装 JDK(17) 和 Gradle(8)
bash
# 进入后端项目 mall/backend
cd ../backend
# 在后端项目中安装工具
mise use --path mise.toml java@17 gradle@8
# 使用 SpringBoot 脚手架生成对应的 SpringBoot 项目模板
mise use spring-boot@3.5.0
spring init \
--dependencies=web,lombok \
--type=gradle-project \
--language=java \
--boot-version=3.5.0 \
--name=demo \
--description="演示项目" \
--groupId=com.github \
--artifactId=demo \
--version=v1.0 \
--package-name=com.github.demo \
--java-version=17 \
--extract
# Gradle 加速
sed -i 's|services.gradle.org/distributions|mirrors.cloud.tencent.com/gradle|g' \
./gradle/wrapper/gradle-wrapper.properties
sed -i '/^rootProject.name/i\
pluginManagement {\
repositories {\
maven { url "https://mirrors.cloud.tencent.com/nexus/repository/maven-public/" }\
maven { url "https://maven.aliyun.com/repository/public/" }\
gradlePluginPortal()\
mavenCentral()\
}\
}\
\
dependencyResolutionManagement {\
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)\
repositories {\
maven { url "https://mirrors.cloud.tencent.com/nexus/repository/maven-public/" }\
maven { url "https://maven.aliyun.com/repository/public/" }\
mavenCentral()\
}\
}\
' settings.gradle
# Gradle 编译
./gradlew clean build -x test
# 启动
./gradlew bootRun1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

4.3.2 环境变量管理
- mise 可以用于设置项目的环境变量,类似于 dotenv 和我们的构建工具集成。

mise 可以通过
mise set KEY=VALUE命令行的方式来设置环境变量(本质上还是通过修改 mise.toml 文件的方式),也可以直接修改mise.toml文件来进行修改。示例:
bash
# 创建项目目录并进行项目目录
mkdir mall && cd mall
# 安装工具
mise use node@24
# 设置环境变量
mise set NODE_ENV='development'
# 查看环境变量
mise set
# 使用环境变量
echo $NODE_ENV
# 使用环境变量
mise exec -- node --eval 'console.log(process.env.NODE_ENV)'
# 取消环境变量
mise unset NODE_ENV
# 查看环境变量
mise set
# 使用环境变量
mise exec -- node --eval 'console.log(process.env.NODE_ENV)'1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

4.3.3 任务执行
- 一个项目,可能会经历
安装依赖、启动、打包、测试、部署等一系列过程,那么就可以通过 mise 的任务执行来统一管理和简化。
提醒
mise 任务将会自动安装 mise.toml 中的所有工具,再执行相关任务(巧妇难为无米之炊)。
- 示例:
bash
# 创建项目并进入目录
mkdir mall && cd mall
# 在前端项目中安装工具
mise use node@24 pnpm@9
# 使用 vite 脚手架生成对应的 Vue 项目模板
pnpm create vite . --template vue-ts
# 设置任务
mise tasks add install -- pnpm install
mise tasks add build --depends install -- pnpm run build
mise tasks add dev --depends install -- pnpm run dev
mise tasks add preview --depends install -- pnpm run preview
# 执行任务
mise run dev1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
