TypeORMの設定ファイル(ormconfig.json)を読み込めない!!
みたいな困りごとがあったので、解決策をメモしておきます
結論
TypeORMは「.env」「ormconfig.env」「ormconfig.xxx」の優先度で設定値を読み込む。今回はdotenv使っていたのでormconfig.jsonが読み込まれていなかった
抜粋
From the environment variables. Typeorm will attempt to load the .env file using dotEnv if it exists. If the environment variables TYPEORM_CONNECTION or TYPEORM_URL are set, Typeorm will use this method.
From the ormconfig.env.
From the other ormconfig.[format] files, in this order: [js, ts, json, yml, yaml, xml].
状況を再現してみる
実験用ディレクトリを作ります
npm init
npx typeorm init
こんなプロジェクトができるはず
.
├── README.md
├── node_modules
├── ormconfig.json
├── package-lock.json
├── package.json
├── src
└── tsconfig.json
ormconfig.jsonを開いてみます
{
"type": "mysql",
"host": "localhost",
"port": 3306, <-- ここに注目
"username": "test",
"password": "test",
"database": "test",
"synchronize": true,
"logging": false,
"entities": [
"src/entity/**/*.ts"
],
"migrations": [
"src/migration/**/*.ts"
],
"subscribers": [
"src/subscriber/**/*.ts"
],
"cli": {
"entitiesDir": "src/entity",
"migrationsDir": "src/migration",
"subscribersDir": "src/subscriber"
}
}
ポート3306を指定したので、この状態で npm start
すれば...
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3306, <-- ここに注目
fatal: true
ちゃんと3306を目指します。
dotenvを使っている場合
が、仮にあなたのプロジェクトがdotenvを使って環境変数を管理していて、こんな.envファイルがルートに置いてあるとしましょう
TYPEORM_PORT=4000
TYPEORM_CONNECTION=mysql
この状態で npm start
してみます
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 4000, <-- ここに注目
fatal: true
ormconfig.jsonは無視されて.envが優先されました
この仕様を見落としていたため、今回僕はormconfig.jsonが無視されて困っていたワケです
ちなみに
.envの中身に左右されます
TYPEORM_CONNECTION、もしくはTYPEORM_URLのいずれかが.envに指定されている場合のみ、.envが優先されます。
なので試しにTYPEORM_CONNECTIONを外してみましょう
TYPEORM_PORT=4000
TYPEORM_CONNECTION=mysql <-- コイツを削除してみる
TYPEORM_PORT=4000
この状態で起動すると
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 3306, <-- ここに注目
.envではなく、ormconfig.jsonが優先されて3306に向かっていますね。
dotenvの有無は関係ねぇ!
dotenvをプロジェクト自身が使っていなくても、.envファイルが転がっていると、そちらormconfig.jsonより優先されます。
node_modules/typeorm/package.json
を覗いてみると
"dependencies": {
"app-root-path": "^3.0.0",
"buffer": "^5.1.0",
"chalk": "^2.4.2",
"cli-highlight": "^2.0.0",
"debug": "^4.1.1",
"dotenv": "^6.2.0", <-- いた!
"glob": "^7.1.2",
"js-yaml": "^3.13.1",
はい、dotenvが居りますね。
なので自分自身がdotenvを入れていなくても注意しましょう。
教訓
今後はドキュメントをちゃんと読むようにします...
関係ありそうなエラーメッセージ
Cannot find connection xxx because its not defined in any orm configuration files.
- ormconfig.jsonの中でconnectionの名前とか指定していた場合、.envが優先されてormconfig.jsonは無視されるので、名前付きconnectionが見つからず、こんなエラーが出る事があります
No migrations pending
- マイグレーション対象のDBをormconfig.jsonで定義していた場合、.envが優先されてormconfig.jsonは無視されるので、マイグレーション済みの別DBを参照して、こんなエラーが出る事があります