O hirunewani blog

Frontend Weekly 2024-04-19

Created at

Chrome 124のJavaScriptからShadow DOMを使用するAPIの追加、WebSocket Stream API、Pageswap eventなど。pnpm v9、Biome 1.7、Farm v1などについて紹介する。

Chrome 124

2024年4月16日にChrome 124がリリースされました。

Chrome 124  |  Release notes  |  Chrome for Developers

Chrome 124  |  Release notes  |  Chrome for Developers

JavaScriptからShadow DOMを使用するAPIの追加

今まで、Element.innerHTMLなどにShadow DOMを含むHTMLを記述しても正しく解析されず表示されない問題がありました。

次のAPIを利用することでShadow DOMの解析も可能になります。

  • Element.setHTMLUnsafe()
    • Element.innerHTMLと同様に、要素の内部HTMLを指定された文字列に設定する。
  • Document.parseHTMLUnsafe()
    • DOMParser.parseFromString()と同様に、文字列を解析してDocumentを返す。

ただし、これらはUnsafeと付いている通り危険であり、scriptやイベントハンドラのcontent属性など危険な要素や属性の削除を行うサニタイズを行わないため、利用には注意が必要です。

今後、入力のサニタイズを行うバージョンの提供予定とのことです。また、これらのAPIはSafariなどでも利用可能です。

WebSocket Stream API

WebSocket APIとStream APIを統合したWebSocket Stream APIが追加されました。ブラウザのWebSocket APIでは、受信メッセージのBack-pressureがサポートされていないため、処理能力を超える量のメッセージを受信した場合、メッセージのバッファでメモリが占拠されたり、CPU使用率が100%になってしまう問題があります。

Back-pressureとは、WebSocketの文脈で簡単に言えば、処理が間に合わなければ受信を遅延させることであり、これをユーザーランドで適切に行うことは出来ませんでした。

https://www.reactivemanifesto.org/ja/glossary#Back-Pressure

WebSocket Stream APIでは、追加コストなくBack-pressureを適用できます。

WebSocket Stream APIは次のように記述します。

const wss = new WebSocketStream(WSS_URL);
const { readable, writable } = await wss.opened;
const reader = readable.getReader();
const writer = writable.getWriter();

while (true) {
  const { value, done } = await reader.read();
  if (done) {
    break;
  }
  const result = await process(value);
  await writer.write(result);
}

Pageswap event

View Transitionなど、ナビゲーションによって古いドキュメントが新しいドキュメントに置き換えられる直前に発火するイベントです。一方、Chrome 123で追加されたPagerevealはView Transitionの文脈では紹介されていませんでしたが、これは新しいドキュメントで最初のレンダリングが行われる直前に発火します。

それぞれ、次のように古い/新しいURLを取得できます。

window.addEventListener("pageswap", async event => {
  if (event.viewTransition) {
    const current = new URL(navigation.currentEntry.url);
    const destination = new URL(event.activation.entry.url);
  }
});

window.addEventListener("pagereveal", async event => {
  if (event.viewTransition) {
    const from = new URL(navigation.activation.from.url);
    const current = new URL(navigation.activation.entry.url);
  }
});

URLやviewTransitionであることを確認することで、ナビゲーション時に適切な事前準備が出来るようになります。

その他

  • PictureInPictureの元のタブに戻るボタンを非表示にするオプションdisallowReturnToOpenerの追加
  • tabindexの指定されていないスクロールコンテナにもフォーカスが可能に。今まで、tabindexが指定されておらず、内部にフォーカス可能な要素がなければ、キーボードユーザーは一度キーボードから手を放す必要があった。フォーカスさせたくない場合は、明示的にtabindexに負の数を指定する必要がある。
  • ユニバーサルインストールによって、PWAの条件を満たさなくても、任意のページをインストールできるようになった。
  • writingsuggestions属性。ブラウザによる入力要素への書き込みの提案をコントロールできる。いくつかのブラウザで提供がはじまっているAIによる入力支援機能を無効化した場合は、これをfalseにしておく必要がある。autoComplete属性など、このようなブラウザの機能は開発者が入力要素にHTML外でバリデーションをかけている場合、疑似的なselect要素などで問題になる。
    • 継承されるため、個別に付ける必要はない。
  • ドキュメントのレンダリングブロック。<link rel="expect" href="#id"> のように指定すると、指定されたIDの要素が完全に解析されるまで、レンダリングをブロックできる。これにより、重要なコンテンツの解析が終了するまでレンダリングが遅延でいるため、最初の描画に一貫性を持たせられる。
  • WebGPUがServiceWorkerおよびSharedWorkerをサポート。これにより例えば、タブ間でリソースを共有できるようになる。

Biome 1.7

2024年4月15日にBiome 1.7がリリースされました。

Biome v1.7

次の変更がありました。

  • biome migrate eslintbiome migrate prettierの追加
    • ESLintとPrettierの設定からBiomeにマイグレーションできるコマンド
  • biome check —-stagedの追加
    • Gitでstagingされているファイルのみを対象に実行できるコマンド

pnpm v9

pnpm v9が2024年4月18日にリリースされました。

https://github.com/pnpm/pnpm/releases/tag/v9.0.0

次の変更がありました。

  • Node.js v16のサポート終了
  • dedupe-injected-depsがデフォルトで有効化
    • Injectされた依存関係が、可能な限りワークスペースからシンボリックリンクされるようになりました。例えば、他のworkspaceを依存関係に指定した場合、そのworkspaceでビルドを実行した度に、インストールを実行してnode_modulesにコピーさせる必要がありましたが、これがシンボリックリンクで解消されます。
  • enable-pre-post-scriptsがデフォルトで有効化
    • package.jsonのscriptsに記載するnpm scriptsでは、pre/postプレフィックスを付けたコマンドは、付いていないコマンドの前後で実行されます。
  • package.jsonのpackageManagerフィールドの確認
    • 指定と異なるパッケージマネージャーやpnpmのバージョンを利用している場合、処理が行われなくなります。
    • packageManagerフィールドは、corepackなどが利用しています。
  • Gitリポジトリからサブディレクトリのみをインストール可能に。
    • pnpm add github:user/repo#path:packages/foo

Farm v1

Most powerful, fastest, and most stableをうたうRust製ビルドツールのFarm v1がリリースされました。公開している1000個のReactコンポーネントを利用したベンチマークテストでは、Viteの10倍高速であるとのこと。

https://github.com/farm-fe/farm/releases/tag/v1.0

Farmは、Viteのプラグインエコシステムと互換性があります。元々Rollup形式のプラグインシステムを採用していたこともあり、早く本番稼働できるようにVite互換性を持つことを選択したようです。

Make Farm compatible with most Vite plugins #622

またキャッシュを利用したIncremental build、Lazy compilationがデフォルトで利用している他、開発と本番のビルドで全く同じ戦略を利用するためViteの欠点も解消されます。

ViteではESBuildとRollupを使い分けているため、開発環境と本番環境で差が生まれる可能性があることや、複数のツールを使うことによるパフォーマンスの低下や複雑度が増加する問題があります。

Viteは、この問題を解決するためにRust製のRollup互換のRolldownを現在開発中であり、Farmと多くの部分で被っているため、どのような差が生まれるのかは気になります。

Panda CSS the origin story

Panda CSSがなぜ、どのように作られたのか。

Panda CSS - The Origin Story

Chakura UIがナルトから来ているように、作者は基本的にアニメや漫画から名前を付けているらしく、Panda CSSはカンフー・パンダ由来とのこと。

Others

Vitest UIが便利。モジュール同士の依存関係を視覚的に確認できる機能があったりする。

Vitest UIを使ってみよう!

NOT A HOTELのCloludflare Workers導入事例。AIチャットボットに利用している。

Cloludflare Workers導入でデプロイ時間を大幅改善。リリース頻度も二週に一度→毎日へ。

リファクタリングに対してポジティブなイメージをチームに持ってもらうために、この辺りの考えは必要。

“リファクタリングはチームのためにするものなので、チームがどういうリファクタリングを求めているのかの認識を揃えておく必要があります” -https://zenn.dev/mike/articles/4542d9f51503e3#周囲とコミュニケーションをとる

“リファクタリングしたくなったら、影響範囲や今後の開発にメリットがあるかを、実装する前に考えてください。実装中にリファクタリングできるポイントに気付いた場合は、その作業が終わってから…” - https://zenn.dev/mike/articles/4542d9f51503e3#よく計画を立てる

リファクタリングのアンチパターン

ついにApp RouterをサポートしていないのCSS-in-JSライブラリはEmotionだけに…

Styling: CSS-in-JS

JSRの仕組みと、サイトの構成について。かなり詳細に書かれている。DBはPostgresでAPIはRust、アプリケーションはfreshで作られている。

How we built JSR

Playwright公式サイトにかかれているBest Practicesの翻訳

Playwrightのベストプラクティスを翻訳してみた

Best Practiceの他、Playwrightのテストの考え方や、知っておいた方が良い機能なども紹介されているので、Playwrightを触りたくなったら読み込んでおくと良い。

Best Practices | Playwright

上の記事で紹介されていないが、UI Modeも存在を知っておくと捗る。

UI Mode | Playwright

文章の折り返しは日英混ざっていると困難になる。CSSの進化によって細かなコントロールが出来るようになった。

文章の折り返し指定のCSS最新版 - ICS MEDIA

記事では、次の記述をおすすめしている。

body {
  overflow-wrap: anywhere; /* 収まらない場合に折り返す */
  word-break: normal; /* 単語の分割はデフォルトに依存 */
  line-break: strict; /* 禁則処理を厳格に適用 */
}

Figma公式によるCodegen特集

Codegen Plugins (And Other Tips) for Automating Design to Code | Figma Blog

4秒以上の待機はSpinnersよりもProgress Barを使った方がいいという話

Progress Bars vs. Spinners: When to Use Which

Moonbitはネタが全くないとかでなければ調べない

MoonBit

MoonBit が WebAssembly 時代の理想(の原型)だった