問題
自作したReact Componentを含むnpmライブラリを、NextJsプロジェクトでinstall
、next build
したところ、Cannot find module 'project\node_modules\react\jsx-runtime' imported from project\node_modules\my-library\my-component Did you mean to import react/jsx-runtime.js?
というエラーが発生しました。
Stack Overflowなどでも取り上げられており、ライブラリとプロジェクト間のVersion差異で、簡単に解決できるかなぁと思ったところで見事沼にはまりました。
まず、試したのは以下です。
React
を最新Ver18に上げるという手段はプロジェクトへの影響上除外しています。
-
@types/react
を最新Verにあげるライブラリ側も、Nextjsプロジェクト側も全てVersionを揃えてみましたが、改善しませんでした。プロジェクト側で問題なく
@types/react
によるModue resolutionは行えていたので望み薄だったので気にしません。 -
node_modules
と.lock
ファイルを削除し、install
lockファイルを削除するという荒業ですが、やるしかありません。
package.json
の各ライブラリVersionを色々と調整しつつ、やっとの思いで試してみましたが、改善しません。
単純な問題ではないことが分かり、色々と覚悟すると共に、「調子にのってライブラリなんて作るんじゃなかった」などの後悔も当然発生します。手がかりはエラーメッセージのみです。
環境
以下で完全に再現というわけではなく、関連するパッケージのみ上げています。
※ちなみにreact:17.0.2
は、こちら記載のjsx-runtime
によるJSX解析を行います。
-
npmライブラリ
react:17.0.2
typescript:4.4.4 -
NextJs Project(上記Packageをインストールする)
react:17.0.2
typescript:4.4.4
原因
エラー発生元は、npmライブラリの実ファイル、つまりバンドル後のJavaScript
から発生しており、この時点で@types
系の問題ではないことが分かりました。
つまり、本来はreact/jsx-runtime
という名称そのままでインポートされるべきということです。
ここで、npmライブラリを作成したときの知恵が役立ちます。
parent/child
のような形式で、モジュールインポートを行えるようにするには、reactライブラリ
のpackage.json
に以下のような記載が必要です。パスを明示的に設定する必要があります。
{
"name":"react",
,
,
"exports": {
"./jsx-runtime":{
"import": "xxxx",
"require": "xxx"
}
}
}
プロジェクト側のnode_modules/react
のpackage.json
を確認してみると、exports
の記載がありません!
この問題をベースに検索してみると、同じことを問題にしているIssueが見つかりました。
一安心です。
対策
react
のv18
から修正されているようなので、シンプルな解決方法はnpmライブラリもNextJsプロジェクトのどちらも最新Versionに上げるということでしたが、それは色々な兼ね合いでできません。
したがって、npmライブラリ側のバンドルでjsx-runtime
を含まないよう以下のように変更しました。これにより、React
がJSX解釈に必要になるので、Component
ファイルにimport React from 'react'
も行いました。
{
"compilerOptions": {
,
"jsx": "react",
最後に
NextJsプロジェクトのtsconfig.json
を見てみると、"jsx":"preserve"
固定になっていたので、この辺がちゃんと考慮されているようでした。
補足
NextJsプロジェクト側でreact/jsx-runtime
とreact/jsx-runtime.js
を紐づけるように解決するという方法もありますが、npmライブラリ導入により、本体プロジェクト側に設定関連の修正を与えたくなかったので、採用しませんでした。