ロゴテキスト ロゴ

    Next.jsとRecoilを組み合わせた時の Duplicate atom key を表示させなくする

    Next.jsとRecoilを組み合わせた時の Duplicate atom key を表示させなくする

    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のプロセスなので、アトムはすでに宣言されています。

    —中略—

    基本的に、このチェック/警告を無効にするコンフィギュレーション設定を提供する以外に、この問題を解決する方法は思いつきません。


    [SSR][NextJS] Duplicate atom key during development and during production build in nextjs · Issue #733 · facebookexperimental/Recoil より引用


    要約すると

    • 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 で書き出す際の値をラップします

    next.config.js
    // 変更前
     
    module.exports = {
      env: {
        HOGE: process.env.HOGE,
      },
    }
    next.config.js
    // 変更後
    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開発を支援するパッケージを用いた際でも今回の方法で無事出来ました。

    Nx: Smart, Fast and Extensible Build System

    プロフィールの背景画像 プロフィール画像
    Yuki Takara
    都内でフリーランスのエンジニアをやってます。フロントとアプリ開発メインに幅広くやってます。