🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付

大家在開發環境的工具管理上是怎麼做的呢?

我在進入這個行業的三年半期間一直在使用 Homebrew,不過最近因為經常看到「Nix 的文章」和「大家的 Dotfiles 文章」,我感到想要更新自己的開發環境。

不過……我老實說並沒有時間和精力去學習像 Nix 這樣的「完全重現性」的獨特語言。

因此,我選擇了可以結合「Homebrew 的便利性」和「如 Nix 一樣的宣告式管理」的工具「Mise」。

這次我想記錄下這段經過和遇到的困難。

※ 本文不會介紹 mise 的功能

Mise 是什麼

What is it?
它像 asdf(或 nvm 或 pyenv,但適用於任何語言)一樣,管理像 node、python、cmake、terraform 等數百種開發工具。
像 direnv 一樣為不同的項目目錄管理環境變數。
像 make 一樣管理用於構建和測試項目的任務。

https://github.com/jdx/mise

以上是從 Mise 的 GitHub 引用來的。

簡而言之,就是具備「開發工具管理」、「環境變數管理」、「任務執行器」的功能。

發音

Pronounced "MEEZ ahn plahs"

中文發音為「米茲」。

轉換的經過 ~ 在 Homebrew 中遇到的問題 ~

1. 版本管理困難

使用 brew updatebrew upgrade 進行工具的批量更新非常方便,但無法指定要安裝的版本,例如想保持在「xx 系列」的版本。

2. 無法判斷是否是自己安裝的工具或依賴的包

brew list 輸出的工具列表中,無法分辨出這些工具是自己安裝的還是依賴的工具。

這無法像 package.jsonpackage-lock.json 那樣進行區分。

當然,可以利用 brew depsbrew use 指令來確定是否有依賴,但這樣做非常麻煩。

3. dotfiles 管理的困惑

這是個「困惑」,所以寫這些感受的文章我感到有些不好意思。
因為在 brew list 中列出了自己選擇的以外的包,讓我感到用代碼來管理這些包有些不自然。

此外,在創建文件並列出後,實施用於在其他環境中重現的腳本的管理成本也很高。
※ 如果 homebrew 發生更改,維護腳本會變得非常麻煩。

4. 目錄級別的環境隔離

如果在主機上開發多個項目而不使用容器,像是 node 或 go 等語言的版本切換會非常麻煩。

現今不少情況下會進行遠端開發或容器開發,但在我的情況下,有時「我希望能在主機 OS 上迅速執行靜態分析或格式化」這種需求,所以「每個項目目錄的工具版本指定」是必要的。

市面上當然也有這樣的工具,在 Node 系列中,voltanvm 給人的印象很強。

但是,「Homebrew 中同時安裝 nodevolta,然後在項目目錄中使用指定的 volta 版本的 node」會讓人感到不適。

為什麼選擇 Mise

1. 可以指定版本

可以像下面這樣指定工具的版本:

[tools]
go = "latest"
golangci-lint = "v2.7.2" # 固定版本
node = "latest"
jq = "latest"

在 Homebrew 中經常會發生「不知不覺就升級到新版本而不能使用」的情況,但在 Mise 中可以用代碼明確指定所使用的工具和版本。

只需在 dotfiles 中管理此文件,當更換電腦或建立開發用的遠端虛擬機時,僅需執行 mise install 即可安裝所需的開發工具。

# 安裝工具
mise install
# 更新工具版本
mise upgrade

2. 能夠在目錄級別進行包管理而不僅限於 OS 設定

「想在每個項目中使用不同版本的開發工具」的需求只需放置設定文件即可解決。

例如,當在項目 A(Node.js v18)和項目 B(Node.js v20)之間切換時,只需更改目錄,Mise 就會自動切換。

項目 A

[tools]
node = "18.00.0"

項目 B

[tools]
node = "20.10.0"

即使不單獨安裝 direnvvolta,僅用 Mise 就能輕鬆完成語言版本和工具版本的切換,這樣的體驗非常好。

3. 定義任務執行器

Mise 也具有任務執行器的功能(與 make 類似)。
可以通過 mise run 列出並執行定義的任務。

我也在日常操作系統的維護任務中使用它。
下面分享一個範例。

[tasks.cleanup]
description = "系統整體的快取清理"
run = """
  echo "Cleaning Go cache..." && go clean -modcache -cache -testcache
  echo "Cleaning Docker..." && docker system df && docker volume ls -qf dangling=true | xargs -r docker volume rm && docker images -f 'dangling=true' -q | xargs -r docker rmi && docker container prune --force --filter 'until=168h' && docker ps --filter 'status=exited' | grep 'weeks ago' | awk '{print $1}' | xargs -r docker rm && docker builder prune && docker system df
  echo "Cleaning npm cache..." && npm cache clean --force
"""

[tasks.doctor]
run = "mise doctor && mise reshim"

4. 定義 Shell 别名

對於用 mise 安裝的開發工具,當然希望可以使用 mise 進行別名註冊。
當然,mise 也有別名註冊的功能。

我設置了如下的別名。

mr = "mise run"
d = "docker"
dc = "docker compose"
dps = "docker ps"
dpsa = "docker ps -a"
dst = "docker stats"
dil = "docker images"
dclog = "docker compose logs -f"
dex = "docker exec -it"
dcex = "docker compose exec -it"
drm = "docker rm"
dri = "docker rmi"

5. 可以做 dotfiles 管理

我認為,Mise 的可移植性價值非常高。

只需設置一個符號鏈接,讓 OS 能讀取以 Dotfiles 管理的 Mise 的 config.toml,就可以完成 Mise 的設置。

在我自己的情況下,會在 Dotfiles 的初始化腳本中編寫設置內容。以下是範例。

# 為 mise 創建符號鏈接
ln -sfvn "$DOTFILES_DIR/mise" ~/.config/mise

mise install

遷移中遇到的問題與解決方案

遷移過程中我並沒有花費太多時間,很順利。
但其中有幾個小困難的點,還有閱讀者可能會關心的點,我這裡總結一下。

1. Docker

在和 AI 一起進行遷移計畫時,我把 docker 相關工具視為一大難關。
具體來說,候選開發工具如下。

  • lima
  • colima
  • docker cli
  • docker compose
  • docker buildx

的確,如果「上述五個中有一個未被 Mise 支持」,我會覺得非常麻煩,但實際上可問題不大,Mise 可以正常管理。

docker compose 的 PATH 問題

關於 docker composedocker buildx,在 mise 中的安裝路徑如下所示。

% which docker compose
~/.local/share/mise/installs/docker-cli/29.2.1/docker/docker

因此,由於每次版本升級時路徑會改變,每次都需要設置符號鏈接,讓 docker cli 具識別為子命令。

ln -s $(which docker-cli-plugin-docker-compose) ~/.docker/cli-plugins/docker-compose
ln -s $(which docker-cli-plugin-docker-buildx) ~/.docker/cli-plugins/docker-buildx

或者。

可以利用 mise 的 tools 定義的安裝時的 postinstall 功能。
這樣在更新後會自動設置路徑。目前為止我並未遇到任何問題。

[tools]
lima = "latest"
colima = "latest"
docker-cli = "latest"
docker-compose = { version = "latest", postinstall = "ln -s $(which docker-cli-plugin-docker-compose) ~/.docker/cli-plugins/docker-compose" }
"aqua:docker/buildx" = { version = "latest", postinstall = "ln -s $(which docker-cli-plugin-docker-buildx) ~/.docker/cli-plugins/docker-buildx" }

2. GUI 應用的管理該怎麼辦

Mise 無法管理 GUI 應用,因此在選擇時我也有些猶豫。

仔細想一下,或許我對於 GUI 應用的管理實際上並不是那麼需要。

以下是我總結的理由。

理由

  • 使用的電腦上並沒有安裝太多的第三方 GUI 應用
    (盡量不這樣做)
  • 使用的 GUI 應用中的大部分會在應用內提醒我進行版本更新
  • OS 初始化和 OS 遷移的機會數年才會發生一次

因此,我決定從這次開始不進行 GUI 應用的管理。

總結

引進 Mise 使我能將「Homebrew 的便利性」和「Nix 的宣告式管理」的優點結合在一起。
到目前為止,選擇這個工具是值得的。

特別是對於那些「想挑戰開發環境代碼化但還未實現的人......,但是看起來難度好高」的人,我特別推薦 Mise。
我非常喜歡 Mise 的「開發工具管理」和「項目單位開發工具管理」無縫的體驗。

這次的文章像是「Mise 遷移體驗記」,但希望這篇文章能成為閱讀者開發環境更加豐富的契機。


原文出處:https://qiita.com/umekikazuya/items/388a7aaad767b9e11fa3


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝21   💬3  
560
🥈
我愛JS
📝1   💬5   ❤️2
66
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
🔧 阿川の電商水電行
Shopify 顧問、維護與客製化
💡
小任務 / 單次支援方案
單次處理 Shopify 修正/微調
⭐️
維護方案
每月 Shopify 技術支援 + 小修改 + 諮詢
🚀
專案建置
Shopify 功能導入、培訓 + 分階段交付