できない.dev

環境変数を読むには

各言語で環境変数を読み取る基本形を示す。
未設定のときに既定値を与える書き方と、値が常に文字列で返る点への注意までを扱う。

公開:

各言語見出しの横のバッジは検証状態を表す。実行確認済みはコードを実際に実行して確認したもの、静的確認は構文と公式 API ドキュメントで確認したものである。

Python 実行確認済み

import os
 
print(os.environ["PATH"])            # 未設定だと KeyError
print(os.environ.get("PORT", "3000"))  # 無ければ既定値
port = os.getenv("PORT", "3000")       # getenv も同じ意味

os.environ["KEY"] は未設定だと KeyError を投げる。
落としたくないときは get や os.getenv に既定値を渡す。
値は常に文字列で返るため、数値として使うなら int() で変換する。

JavaScript 実行確認済み

const port = process.env.PORT ?? "3000"; // 未設定なら既定値
console.log(process.env.PATH);            // 値は文字列 or undefined

Node.js では環境変数は process.env にまとまっており、未設定のキーは undefined になる。
?? や || で既定値を補う。
ブラウザには process が無く、Vite なら import.meta.env のようにバンドラが置き換える仕組みを使う。

うまくいかない時: Vite で環境変数(import.meta.env)が読み込めないVite で「process is not defined」が解決できないnpm scripts で環境変数が設定できない(Windows で動かない)

TypeScript 静的確認

const port: string = process.env.PORT ?? "3000";
// process.env.KEY の型は string | undefined

process.env のプロパティは string | undefined 型なので、未設定を考慮せず string として使うと型エラーになる。
?? で既定値を与えるか、事前に存在を確認して絞り込む。
型定義には @types/node が要る。

Go 静的確認

package main
 
import (
	"fmt"
	"os"
)
 
func main() {
	port := os.Getenv("PORT") // 未設定なら空文字
	if port == "" {
		port = "3000"
	}
	if v, ok := os.LookupEnv("PATH"); ok {
		fmt.Println(v) // ok で存在を判別
	}
}

os.Getenv は未設定でも空文字を返すだけでエラーにならない。
空文字と「未設定」を区別したいときは os.LookupEnv を使い、第 2 戻り値の ok で存在を判定する。

Rust 静的確認

use std::env;
 
fn main() {
    // 未設定なら Err を返すので既定値でフォールバック
    let port = env::var("PORT").unwrap_or_else(|_| "3000".to_string());
    println!("{port}");
}

std::env::var は環境変数が無い場合や不正な UTF-8 の場合に Err を返す Result 型である。
未設定でも落とさないよう unwrap_or_else などで既定値を用意する。

Java 静的確認

public class Main {
    public static void main(String[] args) {
        String port = System.getenv("PORT");
        if (port == null) port = "3000"; // 未設定は null
        System.out.println(port);
    }
}

System.getenv は未設定の環境変数に対して null を返すため、そのまま使うと NullPointerException の原因になる。
null チェックで既定値を補うか、Optional でラップして扱う。

C# 静的確認

using System;
 
class Program {
    static void Main() {
        // 未設定なら null
        string port = Environment.GetEnvironmentVariable("PORT") ?? "3000";
        Console.WriteLine(port);
    }
}

Environment.GetEnvironmentVariable は未設定のとき null を返す。
?? 演算子で既定値を与えると未設定でも安全に扱える。
ユーザー単位やマシン単位を指定するなら第 2 引数に EnvironmentVariableTarget を渡す。

つまずき

環境変数が読めない原因の多くは、コードの書き方ではなく「そのプロセスに変数が渡っていない」ことにある。
シェルで export したのに別ターミナルで実行した、.env ファイルを読み込むライブラリを通していない、といったケースが典型である。
まずは一時的に値を出力して、そもそも渡っているかを確認する。

未設定のときの既定値

どの言語でも未設定の扱いは分かれる。
Python の os.environ[] や Java の getenv は「未設定」を KeyError や null で表し、Go の os.Getenv は空文字を返す。
想定外の落ち方を避けるため、get の既定値引数や ?? 演算子、LookupEnv の存在フラグで必ずフォールバックを用意する。