pnpmでインストールしたRemixでdotenvを使う
追記(2022/03/02)
v1.2.3 で.env ファイルを Remix に組み込まれた dotenv が読み込むようになりました。
結論
dotenv ではなく dotenv-cli を使うと動作します。
{
"scripts": {
"dev": "dotenv -- remix dev"
}
}
以下、結論以外の話を書きます。
現状
Remix 自体には.env をサポートする機能がないため、.env ファイルで環境変数を設定したい場合は dotenv を使うよう公式ドキュメントには書かれています。
しかし、pnpm ではドキュメント通りにやっても動作せず、以下のようなエラーが出ます。
$ pnpm dev
> remix-app-template@ dev /path/to/my-remix-app
> node -r dotenv/config node_modules/.bin/remix dev
/path/to/my-remix-app/node_modules/.bin/remix:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
^^^^^^^
SyntaxError: missing ) after argument list
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
at Module._compile (node:internal/modules/cjs/loader:1065:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
ERROR Command failed with exit code 1.
これについて Issue が作成されています。
コメントではdev
コマンドでnode_modules/.bin/remix
ではなくnode_modules/@remix-run/dev/cli.js
を指定するという書き込みもあります。
実行はできますが、ブラウザでアクセスすると別のエラーが出ました。
Error: Cannot find module '@remix-run/server-runtime'
エラーの原因
確認したところ、npm/yarn と pnpm でnode_modules/.bin
以下に作成されるファイルが異なるようです。
npm/yarn では#!/usr/bin/env node
から始まる JavaScript ファイルが置かれていますが、pnpm だと#!/bin/sh
から始まるシェルスクリプトになっています。
Binstub (node_modules/.bin に配置されるファイル) は常にシェルスクリプトです。JavaScript ファイルへのシンボリックリンクではありません。
https://pnpm.io/ja/limitations
つまり、ドキュメントに書かれたコマンドnode -r dotenv/config node_modules/.bin/remix dev
では pnpm で作成されたシェルスクリプトが node に渡されてしまっており、エラーになっていると分かります。
解決策
なんとなく「dotenv cli」とかで調べてみたら dotenv-cli が出てきて、これを使ったら動きました。
実装を読んでみると、dotenv のパース結果をprocess.env
にObject.assign
して、--
以降に渡されたコマンドをspawn
しているようです。
おわります。
Discussion