背景#
以前、このプラットフォームで微妙なバグを見つけました:
Chrome の組み込み翻訳ツールを使用してグローバル翻訳を行うと、ページにエラーが表示されます。具体的なエラーメッセージは次のとおりです。
アプリケーションエラー:クライアントの例外が発生しました(詳細についてはブラウザのコンソールを参照してください)。
ただし、プラットフォーム自体が優れた i18n を持っているため、複雑なコンテンツもほとんど関連ページでグローバル翻訳を使用することはありませんので、あまり注意を払っていませんでした。最近、他の仲間がこの問題について言及しているのを見て、興味を持ち、具体的な原因を簡単に調べてみました。
探究#
コンソールを参照すると言っていたので、具体的に何が言われているのか見てみましょう:
react-dom.production.min.js:189 DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
at e (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:89708)
at e (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:89781)
at e (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:89781)
at uK (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:89833)
at uq (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:86503)
at uQ (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:86382)
at uq (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:86495)
at uQ (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:86382)
at uq (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:86692)
at uQ (https://xlog.xlog.app/_next/static/chunks/framework-9e494f4410668bc3.js:9:86382)
ざっと見ても、わかりません。もう一度見てみましょう。おそらく React 内部で発生したエラーだと推測します。それでは、Google を使って直接検索してみましょう。簡単に原因と解決策を見つけることができました:https://github.com/facebook/react/issues/11538#issuecomment-390386520
問題は、Google 翻訳がテキストノードを含む
<font>
タグでテキストノードを置き換えることですが、React は DOM ツリーに存在しないテキストノードへの参照を保持しています。
そして、解決策も非常に簡単です:
最も簡単な解決策は、これらのテキストノードを
<span>
タグで囲むことです。これにより、React によって参照されるノードは、その内容が<font>
タグに置き換えられても、DOM ツリーに保持されます。
解決#
原因と解決策がわかったので、修正する必要があるエラーの場所を見つけるだけです。
xLog のコードはそれほど少なくないので、直接探すのは大変です。したがって、位置を特定するために、非常に荒っぽい方法を使用し、コンソールで要素をバイナリサーチして削除しました。
運が良かったですが、すぐに問題の原因を見つけました:src/components/site/SiteFooter.tsx
<div className="max-w-screen-md mx-auto px-5 py-10 text-xs flex justify-between">
<div className="font-medium text-base">
©{" "}
<UniLink href="/" className="hover:text-accent">
{site?.name}
</UniLink>{" "}
·{" "}
<Trans
i18nKey="powered by"
defaults={"Powered by <name/>"}
components={{
name: <LogoWithLink />,
}}
ns="site"
/>
</div>
大まかに 2 つのステップで修正します:
- 純粋なテキストを
<span>
タグで囲む Trans
コンポーネントの出力構造を修正する:https://react.i18next.com/latest/trans-component に従って、対応する言語ファイルの文字列テンプレートを修正し、components
フィールドに対応するspan
の宣言を追加します。
ざっと見ましたが、問題はありません。もちろん、完全に修正されていない可能性もありますが、それは発生した場合に対処します。
总结#
特に言うことはありません、Google をたくさん使ってください :_)