前提条件
- Node.js がインストールされていること
今記事での使用バージョン: v22.16.0 - Webの基本的な仕組みや環境変数について大まかに理解していること
読んだ方がいい人
- EDMの環境でdotenvパッケージを利用したい人
- 以下のエラーにぶち当たった人
- const dotenv = require('dotenv')
^
ReferenceError: require is not defined in ES module scope, you can use import instead
- const dotenv = require('dotenv')
結論
dotenvパッケージを上手に使うこと。
答えをすぐ知りたい方は「dotenvをうまく使うとは?」の章へどうぞ。
何が問題だったのか?
ES Module 環境で開発を行う場合、次のようなコードは動作しません。
import { createClient } from '@supabase/supabase-js'
const dotenv = require('dotenv')
これで実行しようとすると以下の様なエラーが出ます
arunbababa@Arunbababa:~/Dev/supabase-quiqk-learn$ node supabase.js
(node:5594) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///home/arunbababa/Dev/supabase-quiqk-learn/supabase.js is not specified and it doesn't parse as CommonJS.
Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
To eliminate this warning, add "type": "module" to /home/arunbababa/Dev/supabase-quiqk-learn/package.json.
(Use `node --trace-warnings ...` to show where the warning was created)
file:///home/arunbababa/Dev/supabase-quiqk-learn/supabase.js:2
const dotenv = require('dotenv')
^
ReferenceError: require is not defined in ES module scope, you can use import instead
at file:///home/arunbababa/Dev/supabase-quiqk-learn/supabase.js:2:16
at ModuleJob.run (node:internal/modules/esm/module_job:274:25)
at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:644:26)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5)
Node.js v22.16.0
これは、dotenv
パッケージが CommonJS 仕様 で書かれているためです。
importはESmoduleの形式で共存させるにはどちらかに寄せないといけないです
実践:環境構築手順
1. 必要なファイルを作成
適当なディレクトリで以下のコマンドを実行します。
touch supabase.js .env
2. supabase.js
を編集
以下のコードを貼り付けてください。
import * as dotenv from 'dotenv'
dotenv.config()
const arunba = process.env.ARUNBA
console.log("this is arunba", arunba)
3. .env
を編集
次の内容を記述します。
ARUNBA=arunbababa
4. npm init
の実行
同じディレクトリで以下を実行します。
npm init
質問がいくつか出ますが、すべて Enter で構いません。
実行後、package.json
が生成されていることを確認してください。
5. dotenv のインストール
以下のコマンドを実行します。
npm i dotenv
これで環境構築は完了です。
ディレクトリ構成
以下のような構成になっていればOKです。
(赤線などの装飾は不要です)
dotenvをうまく使うとは?
補足:なぜこれでうまく動くのか?
以下の Node.js ドキュメントを参照してください:
https://nodejs.org/api/esm.html#import-statements
該当部分には次のように書かれています。
When importing CommonJS modules, the module.exports object is provided as the default export.
Named exports may be available, provided by static analysis as a convenience for better ecosystem compatibility.
ここですね
これを訳すと次の通りです。
CommonJS モジュールをインポートする場合、
module.exports
オブジェクトが デフォルトエクスポート(default export) として提供されます。
また、エコシステムとの互換性を高めるために、静的解析で検出されたプロパティが「名前付きエクスポート」として利用できる場合もあります。
(※この説明は ECMAScript 仕様に基づくものです)
つまりどういうことか?
Node.js が CommonJS モジュールをデフォルトエクスポートとして扱ってくれるため、
dotenv
が CommonJS 形式で書かれていても、以下のように import
できます。
import * as dotenv from 'dotenv'
もう少し深掘り
dotenv
モジュールは、以下のような形でエクスポートされています。
思いっきしCommonJS形式ですね
DotenvModule
の中身を見ると、次のようになっています。
これらが as dotenv
の dotenv
オブジェクト内に展開されるため、
以下のように呼び出せます。
dotenv.config()
動作確認
最後に、環境変数が正しく読み込まれているか確認します。
node supabase.js
次のような出力が得られれば成功です。
.env
に記述した環境変数がしっかり読み込まれていますね。
React や Next.js など、モダンなプロジェクトでもこの方法で dotenv
を利用できます。
ぜひ参考にしてください。
参考資料
他にもさまざまな設定方法が紹介されています。
https://zenn.dev/manase/scraps/f0e33417206522