◢ この記事は以下の言語でも利用できます: English
mise の [env] は、そのディレクトリの中にいるあいだだけ有効な環境変数を定義する仕組みです。
mise 入門ガイドでは、ツールのバージョンについて「設定が打った人ではなくディレクトリに結びつく」と書きました。環境変数も同じです。export はそれを打ったシェルにしか効かず、打ち忘れた人には届かず、打ったまま忘れた人にはついて回ります。
[env] の書き方mise.toml に書きます。
[env]
NODE_ENV = "development"
APP_NAME = "envdemo"いま何が設定されているかは mise env で確認できます。
❯ mise env
export APP_NAME=envdemo
export NODE_ENV=developmentこのコマンドは、シェルを有効化していなくても使えます。「設定したつもりが効いていない」を切り分けるときの入り口です。
export との違いはここです。
❯ cd envdemo
❯ mise env | grep APP_NAME
export APP_NAME=envdemo
❯ cd ..
❯ mise env | grep APP_NAME外に出ると、同じコマンドが何も返しません。
別のプロジェクトに移った瞬間に、前のプロジェクトの値は消えます。持ち出さないことが保証される、というのが export に対する一番の利点です。
.env を読み込むすでに .env を使っているなら、_.file で読み込めます。
[env]
_.file = ".env".env の中身がそのまま環境変数になります。
❯ mise env
export API_KEY=from-dotenv
export DATABASE_URL='postgres://localhost:5432/dev'.env は .gitignore に入れたまま、mise.toml だけをコミットする、という使い分けができます。値そのものではなく「どこから読むか」を共有する形です。
[env] の直接指定と _.file の両方に同じキーがあると、書いた順で決まります。これは実測しないと分からない挙動なので、両方の順序で確かめました。
[env]
SHARED = "from-mise-toml"
_.file = ".env"❯ mise env
export SHARED=from-dotenv順序を入れ替えると、結果も入れ替わります。
[env]
_.file = ".env"
SHARED = "from-mise-toml"❯ mise env
export SHARED=from-mise-tomlつまり「.env が常に優先」でも「mise.toml が常に優先」でもありません。上から順に適用され、後から書いたものが前を上書きします。既定値を mise.toml に置き、.env で個人ごとに上書きさせたいなら、_.file を後ろに書きます。
初めて設定を置いたディレクトリでは、こう言われます。
❯ mise env
mise ERROR error parsing config file: .../envdemo/mise.toml
mise ERROR Config files in .../envdemo/mise.toml are not trusted.
Trust them with `mise trust`. See https://mise.jdx.dev/cli/trust.html for more information.
❯ mise trust
mise trusted .../envdemo
❯ mise env | grep APP_NAME
export APP_NAME=envdemo一手間に見えますが、理にかなっています。[env] は任意の値をシェルに注入できる機能です。mise.toml を含むリポジトリを clone して中に入っただけで、PATH を書き換えられたり、認証情報らしき変数を仕込まれたりしては困ります。ツールのバージョンと違い、環境変数は中身を見ないと危険性が分かりません。だから明示的な承認を求めます。
.env が本物の認証情報を覆い隠すこのブログのリポジトリで実際に起きたことです。
AWS の認証を、長期のアクセスキーから IAM Identity Center(SSO)に移しました。ところが aws コマンドがこう言い続けます。
Profile 'default' is already configured with Access Key credentials.原因は .env に残っていた古い行でした。
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...環境変数は、設定ファイルより優先されます。AWS CLI も SDK も、環境変数にキーがあればそちらを使います。aws configure sso でどれだけ正しく設定しても、このディレクトリで動かすかぎり古いキーが勝ち続けます。しかも、そのキーはもう無効なので、エラーは「認証に失敗した」ではなく「既に設定済み」という、原因から遠い形で出ます。
厄介なのは、消したはずのものが効いているという構図です。AWS 側の設定を何度見直しても見つかりません。
対処として、このリポジトリでは .env そのものをやめました。生成していた .env に本来書くつもりだったのは、ローカルの DynamoDB コンテナ用のリージョン・エンドポイント・テーブル名の 3 つで、どれも開発用の既定値であって秘密ではありません。AWS のキーは、役目を終えたあともそこに残っていた行でした。この 3 つは、いまは mise.toml の [env] に直接書いてあります。
[env]
AWS_REGION = "ap-northeast-1"
DYNAMODB_ENDPOINT = "{{ env.DYNAMODB_ENDPOINT | default(value='http://127.0.0.1:8000') }}"
DYNAMODB_TABLE_NAME = "blog-page-views"生成するファイルが無いので、clone した直後から値が揃い、古い行が残る場所もありません。マシンごとに変えたい値は、コミットしない mise.local.toml で上書きします。AWS の認証情報は環境変数にもファイルにも置かず、ローカルでは SSO、Lambda では実行ロールから取ります。
_.path で PATH に足す環境変数と同じ場所で、PATH にディレクトリを足せます。
[env]
_.path = ["./bin"]そのディレクトリの bin/ が PATH の先頭に入ります。プロジェクト固有のスクリプトを、フルパスを書かずに名前で呼べるようになります。
これも、ディレクトリを出れば消えます。他のプロジェクトの bin/ が紛れ込むことはありません。
ここまでは .env でもできることです。ディレクトリに入ったときだけ有効、という点は違いますが、値そのものの管理としては大きく変わりません。
もう 1 つ、タスクランナーとしての機能があります。タスクごとに違う環境変数を渡せます。make のターゲットや just のレシピにも同じ仕組みがあるので、タスクランナーを使ったことがあれば見慣れたものだと思います。
[env]
NODE_ENV = "development"
DATABASE_URL = "postgres://localhost:5432/dev"
[tasks.dev]
run = "bun dev"
[tasks.test]
env = { NODE_ENV = "test", DATABASE_URL = "postgres://localhost:5432/test" }
run = "bun test"mise run dev は [env] の値をそのまま受け取ります。
NODE_ENV=development DATABASE_URL=postgres://localhost:5432/devmise run test だけが、テスト用の値で走ります。
NODE_ENV=test DATABASE_URL=postgres://localhost:5432/test.env は 1 つのファイルに 1 組の値なので、これを .env だけでやろうとすると、.env.test を用意して起動コマンドで読み分けることになります。タスクの env は、その置き換えをタスクの定義の隣に書く場所です。
.env との使い分けは、こう考えると整理しやすいと思います。
.env — 個人ごとに違い、コミットしない値(API キー、ローカルの接続先)[env] — プロジェクト共通で、コミットしてよい既定値env — その 1 コマンドの間だけ差し替えたい値[env] はディレクトリの中でだけ有効。持ち出されないことが export との違い_.file で既存の .env を読める。同じキーは後に書いた方が勝つmise env で、いま何が設定されているかを確認できる.env に使わなくなった認証情報を残さない。環境変数は設定ファイルより優先されるので、消したはずの値が静かに勝ち続けるenv を書ける。他のタスクランナーにもある機能で、その 1 コマンドの間だけ値を差し替える環境変数は、動かなくなって初めて存在に気付く種類の設定です。ディレクトリに結びつけておくと、少なくとも「どこで効いているのか」がファイルを見れば分かります。
Meta 製の Git 互換 VCS「Sapling (sl)」を、インストールからスタック、sl pr submit での PR 作成、ReviewStack、GUI の sl web まで
Git 互換のバージョン管理システム Jujutsu (jj) を、インストールから Git との違い、毎日打つコマンドまで
パッケージ・dotfiles・ツール・仕上げのタスクを 1 つの設定ファイルに宣言し、mise bootstrap 1 回で新しいマシンを揃える方法