Prisma ORMはこれまで、データベースクライアントをnode_modules
に生成してきました。この記事では、当初の決定の理由、それ以降に学んだこと、そして今後変更することについて説明します。
Prisma ORMがコード(Prisma Client)をnode_modules
に生成する理由
Prisma ORMは、最初のリリース以来、データベーススキーマに合わせたデータベースクライアント(「Prisma Client」と呼ばれる)を生成するために*コード生成*を使用しています。Prisma Clientライブラリは、Prismaスキーマに基づいて自動生成されるため、その構造を認識し、カスタムで型安全なクエリを提供できます。
コード生成はTypeScriptエコシステムにおいて最も一般的な方法ではなく、Prisma ORMはそれに依存した最初の人気ライブラリの1つでした。開発者にとっての親しみやすさを最大化するため、デフォルトでPrisma Clientをnode_modules
フォルダに生成することにしました。それは、開発者がアプリケーションにサードパーティライブラリを統合する際に慣れている方法だからです。
生成されたコードのカスタムロケーションは、当初からoutput
フィールドを介して選択可能でしたが、このデフォルト設定により、Prisma ORMのさまざまなフレームワークや使用状況で統一された動作が実現されました。
デフォルトでPrisma Clientをnode_modules
に生成することは、最終的にほとんどの人にとって魔法のような「it just works™️」開発者体験をもたらしました…しかし、動かなかった場合を除いては!
v7でPrisma Clientの場所を変更する理由と方法
それ以来、開発者はnode_modules
内の生成されたコードが原因で問題に遭遇しました。JS/TSエコシステムの多くのツールは、node_modules
ディレクトリが(npm
、pnpm
、yarn
などの)パッケージマネージャーによってのみ変更されるという前提で動作します。
しかし、Prisma ORMでは、生成されたコードがデータベースの最新の状態を反映するように、データベーススキーマを変更するたびにPrisma Clientを再生成する必要があります。この要件と、生成されたコードをnode_modules
に入れるというデフォルトの選択が、エコシステム内の多くのツールの前提に反していました。
生成されたコードをnode_modules
に入れる場合の必要な回避策
多くのツールがnode_modules
はパッケージマネージャーによってのみ変更されるという前提で動作するため、私たち(およびコミュニティの他の人々)はスムーズな開発者体験を確保するために*回避策*を講じてきました。
例えば、TS言語サーバーがnode_modules
の変更を監視しないため、prisma generate
を実行するたびにTS言語サーバーを再起動するようにPrisma VS Code拡張機能を調整しました。もう1つの例は、Prisma ORMがNext.jsを使用したモノレポで使用される際に、node_modules
からファイルが適切にコピーされることを唯一の目的とする@prisma/nextjs-monorepo-workaround-plugin
パッケージです。
node_modules
に生成されたコードが存在するという核心的な問題に対する回避策は、専用パッケージからハードコードされたコードパスまで、さまざまな形で存在します。
今後何が変わるのか?
当初、Prisma Clientをnode_modules
に生成するという決定は、多くの開発者がPrisma ORMを使い始めるのに役立ち、スムーズで統一された開発者体験を提供しましたが、このような「魔法のような」動作が、開発者がPrisma ORMを使用する際に予期せぬ問題を引き起こすこともわかりました。
現在、魔法のような動作や不要な抽象化レイヤーを排除することで、Prisma ORMの使用における開発者体験をよりシンプルで予測可能なものにする作業を進めています。
この取り組みの一環として、常にoutput
パスを必須とすることで、node_modules
にコードを生成するオプションを削除する予定です。
この変更に先立ち、v6.6.0で非推奨の警告を追加し、ドキュメントを変更しました。これにより、コミュニティに不要な混乱が生じました。これについては、次のセクションで詳しく説明します。
この変更は今年後半にPrisma ORM v7の一部として導入され、新しいprisma-client
ジェネレーターのみに影響します。このアプローチにはいくつかの利点があります
- 生成されたコードは「通常の」アプリケーションコードとして扱われます。開発者はそれを完全に制御し、アプリケーションバンドルの一部としてどのように含めるかを決定できます。
- 予測可能性が高まり、魔法のような動作による回避策が不要になります。
node_modules
はパッケージマネージャーによってのみ変更されるという前提との適合。
prisma-client
対prisma-client-js
ジェネレーター
私たちのリリースを追っている方ならご存知の通り、v6.6.0でprisma-client
という新しいジェネレーターをリリースしました。
この新しいジェネレーターはESMをサポートし、さまざまなJSランタイムと互換性があり、全体的により柔軟で、カスタムのoutput
パスを*必須*とします。
Prisma ORM v7では、これがPrisma ORMで使用されるデフォルトのジェネレーターとなり、現在のprisma-client-js
ジェネレーター(魔法のようなnode_modules
生成機能付き)はメンテナンスモードに移行されます。
v6.6.0以降のoutput
パス設定に関する混乱
v7で予定されている変更に先立ち、必須となるoutput
パスの破壊的変更に開発者が備えられるよう、node_modules
にPrisma Clientを生成することに頼らないように促したかったのです。
そこで、最近のv6.6.0リリースでは、prisma-client-js
ジェネレーターでカスタムoutput
パスを使用していない場合に、Prisma CLIの出力に以下の非推奨警告を導入しました
また、prisma init
実行時に生成されるデフォルトのPrismaスキーマもoutput
パスを含むように変更し、それに合わせてドキュメントを更新しました。
この働きかけが、予測不能で問題のある動作の排除と開発者へのより多くの制御提供により、良い効果しかもたらさないと期待していましたが、多くの人が実際に非推奨警告を見て、prisma-client-js
ジェネレーターでカスタムoutput
パスを使用するように切り替えた後、問題を報告しました。
ユーザーはsrc/generated/prisma
でのlintingエラーを報告し始めました。特に、lintingエラーが検出されると操作を停止するNext.js開発サーバーなどで問題となりました。コードは生成されたものであるため、lintingエラーは実際には重要ではありませんが、ユーザーはデフォルトでsrc/generated
をlinting設定から除外していませんでした。
他のユーザーは、バンドラー、相対パス解決、その他多くの意図しない副作用に関する問題を報告しました。全体として、Prisma Clientをどこに生成し、どのようにバンドルするかについて、多くの混乱が見られました。
これらはすべて、Prisma Clientがnode_modules
にあったときは問題なく動作していたプロジェクトで発生しました。v7までこれらの問題を避けるため、CLI出力からの非推奨警告を再度削除し、コミュニティから提起された問題を修正する予定です。
今日、Prisma ORMでカスタムoutput
パスを使用するべき時
これら全てが今日あなたにとって何を意味するかの要約(TLDR)です
- 既存のPrisma ORMプロジェクトがあり、
prisma-client-js
ジェネレーターを使用している場合- 最近カスタム
output
パスを追加し、その変更が原因でエラーが発生した場合は、以前と同様にPrisma Clientをnode_modules
に生成するように戻すことができます。 - Prisma ORMが今日、Prisma Clientを
node_modules
に生成して問題なく動作しているなら、何も変更する必要はありません。 Prisma ORM v7では、output
パスを指定してPrisma ORMを使用するデフォルトの方法として新しいprisma-client
ジェネレーターが導入されます。その時期が来たら、アップグレードパスに関する包括的なドキュメントが提供されます。
- 最近カスタム
- 今日から新しいプロジェクトを始める場合は、バンドルの問題を回避し、Prisma ORM v7での今後の破壊的変更に備えるため、カスタム
output
パスを設定することをお勧めします。生成されたアセットは(ほとんどが)ソースコードであり、アプリケーションのバンドルに処理され含まれることを意図しているため、アプリケーションのソースツリー内(例:src/generated/prisma
)のパスを使用することをお勧めします。 output
パスで問題が発生した場合(新しいprisma-client
ジェネレーターを使用しているか、現在のprisma-client-js
ジェネレーターを使用しているかにかかわらず)、新しいissueを開いていただければ、問題解決のお手伝いをいたします。
いつものように、ご意見やご質問がありましたら、Xでご連絡いただくか、Discordにご参加ください!
次回の投稿をお見逃しなく!
Prismaニュースレターに登録する