タグ

ブックマーク / www.mizdra.net (25)

  • fetch の中断と Back/Forward Cache からの復元で発生する奇妙な現象について - mizdra's blog

    TL;DR あるリソースの fetch 中にページ遷移すると、一部ブラウザでは fetch が中断される 中断されると、TypeError が throw される ページ遷移時は、ブラウザによって遷移前のページの実行が"停止"され、"捨てられる"ので、通常 throw された後のことは考えなくて良い しかし、そのページが Back/Forward Cache から復元されうるなら、話は別 ブラウザバックすると、エラーが throw された後からページが再開される!!! そして発生する、奇妙な現象の数々... はじまりは、あるサービスの不具合報告 ある日、「Webサービスから外部サービスにページ遷移した後、ブラウザバックで戻ると、エラー画面が表示される」という不具合が報告された。どうも WebサービスErrorBoundary で何かしらのエラーが catch され、それによってエラー画

    fetch の中断と Back/Forward Cache からの復元で発生する奇妙な現象について - mizdra's blog
  • ESLint の Suggestions から学ぶ、コードの自動修正の奥深さ - mizdra's blog

    これは、はてなエンジニアアドベントカレンダー2023 4日目の記事です。 3日目は id:mechairoi さんの「SQLiteでLinderaを使った日語全文検索」でした。 blog.chairoi.me 今日のテーマは、JavaScript 向けの Linter 「ESLint」についてです。ESLint を使うと、JavaScript で書かれたコードを静的解析して、よくある間違いを検出したり、コーディングスタイルを統一できます。 通常、ESLint のルールによって報告された問題 (error や warn) は人が手で修正します。ただし、ルールが報告する問題の中には「fixable」な性質を持ったものがあります。こうした fixable な問題は、eslint --fix で自動修正できます。例えば、object-shorthand ルールによって報告された問題は、以下のよう

    ESLint の Suggestions から学ぶ、コードの自動修正の奥深さ - mizdra's blog
  • Next.js で言語ごとに異なるアセット画像を埋め込む - mizdra's blog

    多言語対応している Web アプリで、あらかじめファイルに書き出しておいた画像 (アセット) が言語別にあって、それをページに埋め込むにはどうするか、という話題です。基は言語ごとに別々の画像を出すことないと思いますが、たまーにあるんですよね。例えばGoogle Play のバッジが言語ごとに違うので、これを言語ごとに出し分けたいとか。 Google Play バッジ – Google 色々方法があるので、それをいくつか紹介します。 方法1. import 文を言語の数だけ書く シンプルにやるなら、言語の数だけ import 文を書いて、next/image の <Image> コンポーネントで読み込むコードを書くかと思います。 // pages/index.ts import Image from 'next/image'; import GooglePlayJaJP from '../

    Next.js で言語ごとに異なるアセット画像を埋め込む - mizdra's blog
  • アセットの import を簡単にする TypeScript Language Service Plugin を作った - mizdra's blog

    Web ページを作るときに、あらかじめファイルに書き出しておいた画像 (アセット) をページに埋め込みたいことがよくあると思います。例えばヘッダーにサービスのロゴ画像を埋め込む場合、以下のようなコードを書くと思います。 // src/components/Header.tsx export function Header() { return ( <header> <img src="/assets/logo.png" alt="Logo image" /> {/* ... */} </header> ); } 一方で、最近のWeb フロントエンドフレームワーク (例: Next.js, Remix) を使う場合は、import 文を用いて以下のように書くことが多いと思います。 // src/components/Header.tsx import I_LOGO from '../asse

    アセットの import を簡単にする TypeScript Language Service Plugin を作った - mizdra's blog
  • npm package を実装するための自分専用テンプレートリポジトリを作った - mizdra's blog

    npm package を作る度にイチから開発環境の構築をしていて大変だったので、自分専用のテンプレートリポジトリを作りました *1。 github.com せっかくなので、テンプレートの特徴とか、どういうこと考えながら作ったとか紹介してみます。 はじめに: 基的な技術スタック npm TypeScript Node.js Native ESM Prettier ESLint Vitest Renovate GitHub Actions vscode 向けの各種設定ファイル (extensions.json, launch.json, settings.json) GitHub の「テンプレートリポジトリ」機能を使う GitHub にそれっぽい機能があったので使ってみました。 docs.github.com 「Use this template」というボタンが出て便利です。 「Use t

    npm package を実装するための自分専用テンプレートリポジトリを作った - mizdra's blog
  • Next.js の getServerSideProps を共通化する - mizdra's blog

    Next.js で開発していると、複数のページの getServerSidePropsで同じようなコードを度々書くことになると思う。例えば 「GraphQL クライアントでクエリを fetch して、そのレスポンスをpagePropsに焼き込むロジック」であったり、「(マルチテナントアプリケーションにおいて) リクエストヘッダーからテナントを特定するロジック」であったり。こうした大部分のページで使われるロジックのコードは、何度も書かずに済むよう、何らかの共通化をしたくなる。 すでに色々な人が似たような動機でgetServerSidePropsを共通化する方法を紹介していると思う。それを参考にしながら id:mizdra も自分流の共通化方法を実践している。何度か Next.js アプリケーションを作っているうちに、自分の型のようなものが身についてきたので、それを紹介してみる。 はじめに結論

    Next.js の getServerSideProps を共通化する - mizdra's blog
  • CPU シミュレータを用いて継続的ベンチマークを安定化させる - mizdra's blog

    id:mizdra は eslint-interactive というツールをメンテナンスしています。このツールを使うと、多数の ESLint エラーを効率的に修正できます (詳しくは以前書いた記事を見てください)。 www.mizdra.net eslint-interactive では「中規模〜大規模なコードベースであってもキビキビ動く」を大事にしてます。その一環として、eslint-interactive には CI (GitHub Actions) でベンチマークを取り、以前から大きく劣化していたら CI を fail させる仕組みがあります。 https://github.com/mizdra/eslint-interactive/actions/workflows/benchmark.yml?query=is%3Afailure しかし CI で実行するためにノイズが大きく、よく

    CPU シミュレータを用いて継続的ベンチマークを安定化させる - mizdra's blog
  • 試行錯誤を邪魔しない開発環境 - mizdra's blog

    ある機能を実装する際、完成形のコードになるまでには、プログラムとして不正確な状態や、プロダクト品質ではない状態を経る 静的型検査や lint rule に違反したコードが途中に挟まる 型エラーや lint エラーは望ましくないので、できるだけ早くこうした情報を開発者に伝え、気付けるようにすると良い CI でこうしたエラーを検知して、Pull Request をマージする前に気づけるようにするとか エディタ上にエラーの情報を表示して、コーディング中に気づけるようにするとか エラーを積極的に通知してくれるのはありがたいけど、やりすぎには注意するべき なんとなくでも動いてくれたほうが嬉しい 例えば lint エラーがあった際に、watch モードで起動しているビルドやテストの実行を止めて、lint エラー見つけたよーと教えてくれる開発環境がたまにあるけど... 別にビルドやテストの実行は止める必

    試行錯誤を邪魔しない開発環境 - mizdra's blog
  • Web フロントエンドにおけるコロケーション (co-location) という考え方について - mizdra's blog

    Webフロントエンド界隈の文献などにあたっていると、「コロケーション (co-location)」という考え方が時々登場します。 コロケーションを簡単に説明すると、関連するリソース同士を近くに置いておく、という考え方です。 FooComponent.tsx と同じディレクトリに FooComponent.test.tsx を置く GraphQL fragment は、クエリを発行するコンポーネントファイル (pages/user.tsx) ではなく、fragment を利用するコンポーネントファイル (components/UserInfo.tsx) の中で定義する pages/user.tsx からはサブコンポーネントのファイルで定義されている fragment を import してきて、クエリを組み立てて発行する API ドキュメントは API.md に書くのではなく、コードの中にド

    Web フロントエンドにおけるコロケーション (co-location) という考え方について - mizdra's blog
  • React コンポーネントの定義の仕方によって VSCode の定義元ジャンプの挙動が変わる - mizdra's blog

    この記事は「はてなエンジニア Advent Calendar 2022」の3日目の記事です。2日目は id:pokutuna さんの「Slack チャンネルのロボット帝国化を防ぐ feed-pruning-proxy」でした。 blog.pokutuna.com さて、TypeScriptReact コンポーネントを定義する時、皆さんはどういう書き方をしてますか? 関数宣言/アロー関数どちらを使って書くか、React.FC を使うかどうか、など微妙に人によって書き方が異なると思います。 その中でも、よく使われるのは以下の 3 つのスタイルでしょうか。 import React from "react"; type ButtonProps = { children: React.ReactNode; }; // 関数宣言。 function Button1({ children }:

    React コンポーネントの定義の仕方によって VSCode の定義元ジャンプの挙動が変わる - mizdra's blog
  • Prisma で本物のDBMSを使って自動テストを書く - mizdra's blog

    DBMS に依存するロジックのテストを書く時、主に2つの手法があると思います。 Repository 層などを mock する Service 層のテストをする時は、その下位の Repository 層を mock して、DBMS に依存しない形にしてからテストする レイヤードなアプリケーションで適用できる手法 テスト実行時も DBMS を裏で動かして、それを使う 番と同じスキーマを持つ DBMS に対して、実際に insert したり select してテストする DBMS は docker-compose upとかで事前に立ち上げておく 双方にそれぞれ良さがあって、プロダクトによってどっちでやるか変わってくると思います。 この記事では 2 の手法を Prisma でどうやるかについて紹介します。 前提 実際のテストコードの例 テストヘルパーを作る 別解: ヘルパーを自動生成する je

    Prisma で本物のDBMSを使って自動テストを書く - mizdra's blog
  • コードジャンプ可能な CSS Modules を実現する happy-css-modules の紹介 - mizdra's blog

    弊社では ReactCSS を書くための手法として CSS Modules を全面的に採用しています。そこで CSS Modules を使った開発をより快適にするために、「happy-css-modules」というツールを作りました。 happy-css-modules のデモ。 この記事ではこのツールが必要になった背景、導入方法、そしてツールの技術的な仕組みについて紹介します。 CSS Modules の問題点と、typed-css-modules による解決 CSS Modules では、デフォルトでは存在しないクラス名を使用しても、(プロジェクトの設定次第ですが) TypeScript のコンパイルエラーが出ることはありません。 import styles from './Button.module.css'; function Button() { return ( <but

    コードジャンプ可能な CSS Modules を実現する happy-css-modules の紹介 - mizdra's blog
  • qwik の発明、及びマイクロフロントエンドへの活用について - mizdra's blog

    最近調べた qwik というライブラリが結構面白かったので、実際どういうものなのかとか紹介してみます。 qwik とは qwik は Web 向けの View ライブラリです (ReactVue.js の仲間)。パフォーマンスオタクがパフォーマンスの最適化 (Web Vitals の改善) にこだわって作ったライブラリです *1。 すでにいくつも良い紹介資料があるので、まずはこれらをいくつか読んでみると良いと思います。 Resumable な JavaScript フレームワーク Qwik を学ぶ Qwikの基概念である Resumable を理解する Qwikというフレームワークについて - console.lealog(); Qwik調べてみたら結構面白かった qwik の詳しい使い方などは先人の記事に譲ることにして、以降は id:mizdra が個人的に面白いと思ったことを書

    qwik の発明、及びマイクロフロントエンドへの活用について - mizdra's blog
  • 遠い未来の話をする理由、それは自信を持って前に進むため - mizdra's blog

    id:mizdra は時々仕事で「今の時点で結論を出す必要はない、遠い未来の話」をすることがあります。1年後に考えれば良いことを、今考える、とかです。それをするのは何故か、という話を今日はします。 長期プロジェクトを段階的に進めていくには、不安が付き物 現在 id:mizdra はレガシーな Web アプリケーションへの Next.js の導入を仕事でやっています。新規実装部分から少しずつ Next.js を導入していて、段階的に Next.js 化を進めています。全部一気に Next.js 化するとなると、「レガシーな技術スタックでやってたアレは Next.js/React でどうやるの?」という問いが絶え間なく発生して全く前に進めなくなります。しかしスコープを小さくすれば、少しずつ問いに答えていって、進行できます。途中で方針転換もしやすいし、最初の機能をリリースするまでの時間も短くなり

    遠い未来の話をする理由、それは自信を持って前に進むため - mizdra's blog
  • 見つけた GitHub の Issue を片っ端から subscribe している - mizdra's blog

    あるライブラリを使っていてバグっぽい挙動に遭遇した時、ほぼ必ず当該ライブラリの Issue を検索するようにしている。加えて、見つけた Issue の subscribe ボタンを押して、https://github.com/notifications に通知がいくようにしている。バグ遭遇時以外にも、何らかの理由で Issue に到達した時にその Issue を subscribe してる。 ハマったバグの Issue を見つけた時 欲しい機能の feature reuqest の Issue を見つけた時 例: Docker for Mac の VirtioFS 対応の Issue その他面白や動向をチェックしたい Issue を見つけた時 例: TS 4.7 のリリース計画について議論している Issue 例: Jest の ESM 対応の Meta Issue 例: ESLint

    見つけた GitHub の Issue を片っ端から subscribe している - mizdra's blog
  • npm-scripts を書く時の手癖 - mizdra's blog

    かれこれ 5 年くらい趣味開発で npm-scripts を書き続けている。長年書き続けているとノウハウが蓄積されてきて、「こう書くとスッキリする」「迷いがなくなる」「後から拡張したくなった時に、簡単に拡張できる」みたいな書き方が身についてきた。自分の型、あるいは手癖のようなものだと思う。 せっかくなので、id:mizdra の今の npm-scripts を書く時の手癖を書き連ねてみる。 基形 { "scripts": { "build": "webpack --mode production", "dev": "webpack-dev-server --mode development", "lint": "eslint .", "test": "jest" } } 一番シンプルな npm-scripts を書く時のパターン。以下の 4 つの script を登録している。 buil

    npm-scripts を書く時の手癖 - mizdra's blog
  • chezmoi を使って VSCode devcontainer 対応 dotfiles を作る - mizdra's blog

    趣味開発で使っている dotfiles をリニューアルした。 github.com 以前までの dotfiles では適切なパスへの設定ファイルの配置や、onetime script の実行タイミングの管理に ansible を使っていた。冪等性を確保するために色々な機能が用意されていて、便利ではあったのだけど、ファイルの配置をするだけで色々なおまじないが必要だったりと、若干冗長だなと感じていた。 シンボリックリンクを貼るタスク シンボリックリンク貼られる側のファイル郡 あと ansible 自体のインストールにそこそこ時間が掛かるという問題がある。GitHub Actions 上でインストールに掛かる時間を測ったところ、2分くらい掛かっていた。 GitHub Actions のログ (Install Ansible が ansible のインストールをしてい部分) dotfiles そん

    chezmoi を使って VSCode devcontainer 対応 dotfiles を作る - mizdra's blog
  • 個人的 Web フロントエンドスキルの獲得方法 - mizdra's blog

    ここ2年くらいの話なのですが、仕事で「フロントエンド会」というチーム内委員会のようなものを立ち上げて運営しています。元々1人の Web フロントエンド職人がプロダクトの Web フロントエンドの面倒を見ていたのですが、その方が異動されることになったので、残った人で面倒を見ていける体制を作りましょう、というモチベーションで発足した会でした。この話については以前イベントで発表したので、詳しくはこのスライドをご覧下さい。 speakerdeck.com Web フロントエンド職人の異動とともに入社した id:mizdra が Web フロントエンドが得意だったので、ペアプロやペアオペ、定例会などを通じてどんどんスキルや知見を配っていく、という戦略で運営していました。実際に 2 年経過してみてメンバーも徐々にキャッチアップしていって、ちょっとしたパフォーマンス改善をやってみたり、最近 Gulp

    個人的 Web フロントエンドスキルの獲得方法 - mizdra's blog
  • vscode-jest を導入してテストの開発体験を向上させる - mizdra's blog

    この記事は JavaScript Advent Calendar 2021 の 12日目です。11日目は なかがわはじめ さんの 「Array.prototype.reduce()とかのprototypeってなに?」 でした。 Jest は JavaScript のテスティングフレームワークです。Node.js で動くアプリケーションのテストや、React を使った Web アプリケーションのテストなど、様々なプロジェクトのテストをサポートしています。また、エディタ向けに拡張機能やプラグインも公開されています。 VSCode vscode-jest IntelliJ IDEA https://pleiades.io/help/idea/running-unit-tests-on-jest.html Vim test.vim (各拡張機能のサポート状況によりますが) これらの拡張機能を使うと

    vscode-jest を導入してテストの開発体験を向上させる - mizdra's blog
  • nodebrew と homebrew の Node.js が重複しないようにする - mizdra's blog

    普段 yarn を homebrew で管理していているのだけど、yarn が node への依存を持っているせいで、インストールしたり、更新したりする時に Node.js が homebrew で追加でインストールされることがある。けど Node.js は nodebrew で管理しているので、2重でバイナリが存在してむず痒い。何とかしたい、という話。*1 *2 作戦 homebrew でインストールした Node.js バイナリをアンインストールする nodebrew でインストールした Node.js バイナリを homebrew の管理化に置く homebrew 側で node fomula のバージョンを固定して、brew upgrade でアップグレードされないようにする 1. homebrew でインストールした Node.js バイナリをアンインストールする brew un

    nodebrew と homebrew の Node.js が重複しないようにする - mizdra's blog