Remix ✕ Clouflare D1 ✕ Prisma マイグレーション用のnpm run コマンドを作ってみたが、、、
Prismaのマイグレーションをlaravelのマイグレーションよろしく使いたかったのでpackage.jsonのscriptsにコマンドを定義していた。 構築当時はnpxを使っていたものの、npxは指定したパッケージの最新版を使ってコマンドを実行するはずである。すべてのローカル開発環境でなるべく各種バージョンを明示的に指定して共通化したい意図があった。そのためローカルにwranglerのパッケージをインストールしたのでコマンドを変更した。 変更後のコマンドで今まで開発に使っていたPCでは問題なく動作した。しかしテストで別のPCに環境構築して同様のコマンドを実行したところ
Unknown command: "wrangler"
のエラーが発生した。 先輩のアドバイスでなんとか解決できたので内容をまとめる。
npxを使っていた頃のコマンド
ローカル開発環境の仕組みづくり段階では下記の様なコードだった。
"scripts": {
"local-migrate": "npx wrangler d1 migrations apply DB名 --local",
"local-migrate-fresh": "npx wrangler d1 execute DB名 --local --file ./seeds/drop_tables.sql"
},
"scripts": {
"local-migrate": "npx wrangler d1 migrations apply DB名 --local",
"local-migrate-fresh": "npx wrangler d1 execute DB名 --local --file ./seeds/drop_tables.sql"
},
ただ、npxコマンドには実行優先順位があるらしい。(ローカル探索 → グローバル探索 → リモート探索)
https://qiita.com/miriwo/items/7e3a65c59c75898d562c
稀にパッケージのバージョン差異でエラーが出たり出なかったりする事がある。環境構築前に「グローバルにwranglerのパッケージが入っており、古いバージョンだった」場合等はnpxを使ってもグローバルパッケージが優先されるので人によってエラーが出たり出なかったりする。 突き詰めたらきりが無いかもしれないが「〇〇さんはエラーが出て、△△さんはエラーが出ない」見たいな状況は結構しんどい。
これはpackage.jsonを使ってwranglerをバージョン指定してローカルにインストールすることで全員が同じwranglerパッケージのバージョンを使う事ができる。この件だけに限れば人によってエラーが出たり出なかったりの状況は避けられる。
ローカルのwranglerを見に行くようにコマンドを変更(修正ミス)
※この方法は完全に修正ミスです。自身の戒めとして残します。
「$ npm install wrangler
も実行したし、今の"npx"になっている部分を"npm"に変えればええやろ」と思っていた。 なので下記のように修正をして動作確認をしてプルリクを出した。
"scripts": {
"local-migrate": "npm wrangler d1 migrations apply DB名 --local",
"local-migrate-fresh": "npm wrangler d1 execute DB名 --local --file ./seeds/drop_tables.sql"
},
"scripts": {
"local-migrate": "npm wrangler d1 migrations apply DB名 --local",
"local-migrate-fresh": "npm wrangler d1 execute DB名 --local --file ./seeds/drop_tables.sql"
},
先輩に「package.jsonの他のscriptを呼び出したい場合にはnpmをつけるけど、外部パッケージのコマンドは不要だと思う」と指摘をいただく。 自分でも調べてみたところ確かに外部コマンドはnpmつけなくていいらしい。あれ・・?ではなぜ自分の環境は動くのだろうか・・?
・・・・実は前に$ npm install -g wrangler
を実行しており、自身のPCのグローバルにはwranglerパッケージがすでに入っていたのだ。
裏を取るためにグローバルにwranglerが入っていないPCで"local-migrate": "npm wrangler d1 migrations apply DB名 --local",
を実行してみると「Unknown command: "wrangler"」のエラーが出る。
ローカルのwranglerを見に行くようにコマンドを変更(正しい修正)
下記のように「npx」も「npm」もつけない記載が正しい。
"scripts": {
"local-migrate": "wrangler d1 migrations apply DB名 --local",
"local-migrate-fresh": "wrangler d1 execute DB名 --local --file ./seeds/drop_tables.sql"
},
"scripts": {
"local-migrate": "wrangler d1 migrations apply DB名 --local",
"local-migrate-fresh": "wrangler d1 execute DB名 --local --file ./seeds/drop_tables.sql"
},
確かにこの記載で$ npm run local-migrate
を実行すると正常に動作する。 ただ疑問なのが前述のコマンドと同様のディレクトリで$ npm wrangler d1 migrations apply DB名 --local
を実行すると「wrangler command not found」が発生する。これはどういうことなのか。
どうやらpakage.jsonのscriptsのコマンドは実行時にプロジェクトディレクトリのnode_modulesディレクトリ配下のパッケージを確認してコマンドを実行しているらしい。(node_modulesディレクトリ配下にパッケージがある = ローカルにパッケージがインストールされている) なので
$ npm run local-migrateを実行すると正常に動作する。 同様のディレクトリで$ npm wrangler d1 migrations apply DB名 --localを実行すると「wrangler command not found」が発生
こういう事が起きる。
ターミナルにて手動でwranglerコマンドを実行したいときは「npx」を使うで良いと思う。 前述したが、「npx」は実行優先順位がある。プロジェクトディレクトリでnpxを実行するならローカル探索時にヒットしたwranglerを使うはずなのでpakage.jsonのscriptsのコマンドとwranglerのバージョンも一致する。
よく見たら。。。
記事を記載しているときにpackage.jsonをよくよく見たら、、、下記のように最初から用意されているscriptsの記載で直接wranglerコマンドを実行している部分があった。。。
"scripts": {
"deploy": "npm run build && wrangler pages deploy",
"preview": "npm run build && wrangler pages deploy --branch preview"
},
"scripts": {
"deploy": "npm run build && wrangler pages deploy",
"preview": "npm run build && wrangler pages deploy --branch preview"
},