はじめに
先日、個人で開発している Lerna でモノレポ構成の子パッケージをデプロイすると次のように怒られました。
1Error: Cannot find module '@hoge/graphql-schema'
エラー内容から、@hoge/graphql-schema
はありませんと言われました。
TL; DR
Lerna
のモノレポ構成を採用していた場合、別パッケージの参照にはシンボリックリンクが貼られているため、パッケージ単体でデプロイした場合、シンボリックリンク故に実体のディレクトリ・ファイルが参照できなくなり、module がないよと怒られてしまいます。
なので、実体のファイルやディレクトリを用意してあげる必要があります。
内容
個人開発では、GraphQL
でスキーマファースト、Lerna
でモノレポ構成にしているため、graphql-schema
というパッケージに GraphQL のスキーマを記述しています。そして、バックエンドを記述するパッケージgraphql
ではそのgraphql-schema
を npm モジュールとして参照するようにしています。
1$ tree packages -L 1
2packages
3├── graphql # バックエンドが記述されているパッケージ
4└── graphql-schema # Graphqlスキーマを記述しているパッケージ
5
62 directories, 0 files
そして、バックエンド API が固められたgraphql
パッケージを Lambda Container にデプロイしようとすると、上述のエラーが発生したのです。
最初は Lambda もしくはコンテナ内のファイル権限の問題かなと思いました。
ところが、module(package)がないよと言われているので、まさかデプロイ image にgraphql-schema
ディレクトリがないのかと思いls
してみると、Symbolic Link
ではないですか!
1$ ls -la
2total 0
3drwxr-xr-x 3 smiler staff 96 5 31 02:05 .
4drwxr-xr-x 273 smiler staff 8736 5 31 02:05 ..
5lrwxr-xr-x 1 smiler staff 23 5 31 02:05 graphql-schema -> ../../../graphql-schema
Lerna の README を眺めているとBootstrap
時にPacakges
配下はそれぞれSymlink
されると明示的に書かれていました。
Symlink together all Lerna packages that are dependencies of each other.
よって、graphql-schema
を npm パッケージとしてインストールしていても Symbolic Link として参照されるため、graphql
パッケージのみをデプロイすると、実体としてgraphql-schema
がいないためCannot find module
と怒られていました。
では、どう解消したかと言うと、全くナンセンスかと思いますが、デプロイ時にgraphql-schema
を明示的に node_modules 配下にコピーしてあげることで、実体として存在させ参照できるようにしました。
おわりに
bootstrap 時に実体としてファイル・ディレクトリをそもそも置けないのか?
バンドルすれば良いとも聞くのですが、どうするのだろうか...