🎉

つまずきニュースレター(2024-02-09号)

2024/02/09に公開

はじめに

こんにちは。ファンタラクティブyoshinoです。

ファンタラクティブのエンジニアチームはMob.*(モブアスタリスク)という取り組みを毎週行っており、それぞれのメンバーがどのような開発に取り組んでいるか・業務でつまずいたことを社内で共有しています。

このニュースレターでは、その中でも実際の業務で起きたつまずきをピックアップし、まとめています。

【vitest + urql】urqlを使っているコンポーネントの単体テストが落ちてつまずいた!

背景:
urqlを使っているコンポーネントの単体テストが落ちる

原因:
クライアントをモックするために、urql client の Provider を設定しないといけませんでした。

対応:
Provider を用いて、モックした client を設定することで解消しました。
vitest の mock 関数などもありますが、今回のケースでは render する際に、 Provider を一緒に設定する方針で対応しました。

import { Provider } from "urql";

const clients = {
  executeQuery: () => {},
};

// ...
test("render items", () => {
    render(
      <Provider value={clients}>
        <Component />
      </Provider>,
    );
// ...

参考
https://formidable.com/open-source/urql/docs/advanced/testing/


border-radius してもはみ出てしまいつまずいた!

背景:
背景のある要素に対して border-radius を設定したけど、うまくスタイルが当たらず border-radius を貫通して要素が表示されてしまう。

原因:
border-radius を設定している要素(以下 container)からはみ出る要素を隠すスタイリングをしていなかったために、貫通してしまっていました。

対応:
border-radius を設定している要素に対して、overflow: hidden を設定しました。こうすることで、角丸のエレメントを作成することができました。

参考:
https://zenn.dev/html_css/articles/e2675497da68b5


【Nextjs】API を叩くと431 (Request Header Fields Too Large)が返ってきてつまずいた!

背景:
クライアントからAPIにリクエストを送信すると、431 Request Header Fields Too Largeエラーが返され、APIへのアクセスが不能になりました。リクエストヘッダーなどにも不備はなさそうで、リクエストも届いていそうなのですが何故かエラーコードが返されていました。

原因:
next.config.jsrewrites内で使用されている環境変数が誤って設定されており、正しいエンドポイントにリクエストを送れていませんでした。

対応:
next.config.js内のrewritesで使用されている環境変数を正しく設定することで解消しました。エラーメッセージにある Request Header からは想定しづらい修正箇所だったため、解決に時間を要しました。

参考:
https://nextjs.org/docs/pages/api-reference/next-config-js/rewrites


【Nextjs + CloudFront】特定のページでリロードすると、別ページに飛ばされてつまずいた!

背景:
特定のページをリロードすると、意図しない別ページに移動される現象が発生しました。

原因:
CloudFront Function で動的ルーティングの設定が行われていなかったため、ページ内の動的パスが適切に処理されていませんでした。

対応:
CloudFront Function 上で動的ルーティングの設定を行うことで解消。

今のところ、動的なパスが現れるたびに設定を行う必要がありそうなので、プロジェクト内のルーティングを見て関数を自動生成するなど改善策を模索中。。。

const dynamicPatterns = {
  page: /\/hoge\/([^\/]+)\/?[^\/]*\.html$/,
};
const pageMatch = uri.match(dynamicPatterns.page);
if (pageMatch) {
  uri = uri.replace(pageMatch[1], "[id]");
}

Falsyな値のチェックでつまずいた!

背景
JavaScriptでgetElementsByClassNameメソッドを使用する際、返り値としてHTMLCollectionが返されます。しかし、このHTMLCollectionをそのままif文の条件に使用すると、意図しない挙動が発生する可能性があります。
原因
getElementsByClassNameの返り値がHTMLCollectionであるとき、このオブジェクトが空であっても、if文の条件として評価されるとtrueとなってしまいます。これはJavaScriptの真偽値の評価において、空のオブジェクトはtrueとみなされるためです。

HTMLCollectionが空(つまり、指定されたクラス名を持つ要素が一つもない)の場合、HTMLCollectionは実際には空の配列のような形([])を取りますが、これは依然として真偽値としてはtrueと評価されます。

対応
この問題を解決するためには、HTMLCollectionlengthプロパティを使用して、実際に要素が存在するかどうかをチェックする必要がありました。

const elements = document.getElementsByClassName('foo');

// NG
if (elements) {}

// OK
if (elements.length > 0) {}

SpeakerDeckの埋め込みでつまずいた!

背景
nuxtjsで構築されているページにSpeakerDeckを埋め込む作業を行った。この際の、埋め込み方としてscriptタグを使用する方法を試してみました。

原因
nuxt devではscriptタグを使った埋め込みが正常に機能したが、nuxt build && nuxt exportを実行した際にはうまく動作しなかった。なぜbuild時は機能しないのか正直理解できていません。ご存じの方がいたらコメント頂けると幸いです。

対応
最終的に、埋め込み方法をiframeに変更して対応しました。

補足情報
詳細な埋め込み方法についてはこちらで確認できます
https://help.speakerdeck.com/help/how-to-embed-your-presentation-inside-a-wix-website


Google拡張機能のタブ切り替え時のUIでつまずいた!

背景
chrome拡張機能の開発で、content script UIをpopupUI風に見せる実装をしていました

課題
拡張機能のUIを表示した後、ブラウザタブを切り替えても表示状態を維持する方法でつまずきました

対応
まず拡張機能アイコンをクリックしたとき、そのタブのIDをストレージに保存します。

content script UIは、Service Workerを通じてタブのIDを取得し、このIDがストレージに保存されているタブIDと一致する場合にのみUIを表示状態に切り替えるようにすることで対応しました。

もっと良い方法をご存知の方、コメントお待ちしています!


【Next.js】環境変数を使用したフォントのURL指定でつまずいた!

背景
プロジェクトで使用しているフォントのURLをS3に配置し、その向き先を環境変数で管理したいかった。当初、フォントの読み込みはSCSSファイルで行っていたが、SCSSファイルでは環境変数を参照できないという問題がありました。

対応
この問題を解決するために、Styled JSXを使用してフォントの読み込みをコンポーネントで行うようにしました。これにより、Next.jsの環境変数を利用して動的にフォントのURLを設定できるようになりました。

const fontDomain = process.env.NEXT_PUBLIC_FONT_BASE_URL
return (
    <style jsx>
      {`
        @font-face {
          font-family: 'foo';
          src: url(${fontDomain}/fonts/hoge.woff)
            format('woff');
          unicode-range: fuga
        }
      `}
    </style>
);

余談
以下の記事を見つけました。この記事内にある通りnextConfigのsassOptionsを調整することで同様のことができるかもしれません。
https://zenn.dev/chot/articles/b99b77eeeff912

おまけ🍪

今回から、エンジニアチームで「つまずきニュースレター」をはじめることにしました!

このニュースレターを通じて、私たちファンタラクティブのエンジニアチームが日々どんな風に仕事をしているのか、また、ちょっとしたつまずきやアレコレをどう乗り越えているのかを、のぞいてみてもらえたら嬉しいなと思っています。

もしあなたが仕事で「うーん」と思うことがあったとき、ここからちょっとしたヒントを見つけてもらえたら、それ以上の喜びはありません。気楽に読んで、何か一つでも「なるほどなぁ」と思ってもらえるところが見つかれば最高です!

最後に

ファンタラクティブではフロントエンド・バックエンド問わず絶賛エンジニア募集中です!

気になる方は下のリンクをクリック!

https://hrmos.co/pages/funteractive/jobs?category=1936009538684784640

ファンタラクティブテックブログ

Discussion