Next.jsでRecoilを使って開発をしていると
Expectation Violation: Duplicate atom key "xxx". This is a FATAL ERROR in
production. But it is safe to ignore this warning if it occurred because of
hot module replacement.
のような Duplicate atom key "xxx"
というメッセージが表示される事があります。
Next.jsのアプリケーションとして特に問題が起きる・影響があるわけではないですが、
なんとなく気になりますよね。
このメッセージが表示される原因はRecoilの公式GitHubのIssueに載っていて、
Next.js has a concept of Pages. Imagine an SPA with multiple entry points, like an Admin and a Client App, both importing a module that declares a Recoil atom.
—中略—
In development, when a file is changed, Next.js re-builds the relevant page entry file.
Because it’s the same Node.js process, the atom has already been declared.
—中略—
Basically, I can’t think of a solution to this problem besides providing a configuration setting to disable this check/warning.
[DeepL翻訳]
Next.jsには、Pagesという概念があります。AdminとClient Appのように、複数のエントリーポイントを持つSPAがあり、どちらもRecoilアトムを宣言したモジュールをインポートしていると想像してください。
—中略—
開発では、ファイルが変更されると、Next.jsは該当するページエントリーファイルを再ビルドします。
同じNode.jsのプロセスなので、アトムはすでに宣言されています。
—中略—
基本的に、このチェック/警告を無効にするコンフィギュレーション設定を提供する以外に、この問題を解決する方法は思いつきません。
要約すると
- Next.jsで開発している以上、Next.jsの仕様的に警告のメッセージが出てしまう
- なので、このメッセージを無効にする設定をNext.jsに追加すれば解決するよ
となります。
無効にする設定を記載したところ無事出来たため備忘録兼ねて記載します
検証した環境
1 | next | 12.2.6-canary.8 |
2 | recoil | 0.7.5 |
3 | next-intercept-stdout | 1.0.1 |
next-intercept-stdoutを設定する
結論としては next-intercept-stdout
を用いてnext.config.jsの設定を変更します
next-intercept-stdout を追加
$ yarn add -D next-intercept-stdout
next.config.jsの設定を変更
やることは module.exports で書き出す際の値をラップします
// 変更前
module.exports = {
env: {
HOGE: process.env.HOGE,
},
}
// 変更後
const withInterceptStdout = require('next-intercept-stdout')
module.exports = withInterceptStdout(
{
env: {
HOGE: process.env.HOGE,
},
},
(text) => (text.includes('Duplicate atom key') ? '' : text)
)
withInterceptStdout
でラップ- 第2引数に
(text) => (text.includes('Duplicate atom key') ? '' : text)
を追加
この設定でDuplicate atom key "xxx"
というメッセージが表示されなくなりました!
Nx
というmonorepo開発を支援するパッケージを用いた際でも今回の方法で無事出来ました。