有名テック企業の技術ブログを、ひとつのフィードで。
フィード
35件
.images-row {width: 100% !important;} Developer Engagementブロックの@ikkouです。2026年5月22・23日の2日間にわたりベルサール羽田空港で「TSKaigi 2026」が開催されました。 ZOZOはGold Sponsorとして協賛し、スポンサーブースを出展しました。ZOZOがTSKaigiに協賛するのは今回が初めてです。 technote.zozo.com 本記事では、前半はZOZOのWebフロントエンドエンジニアが気になったセッションを紹介します。後半では、ZOZOのスポンサーブースの様子と各社のブースにおけるコーディネートを写真中心に報告します。 ZOZOのWebフロントエンドエンジニアが気になったセッション 開発体験を左右するライブラリの API 設計 ― GraphQL スキーマ構築ライブラリから考える 「関数型プログラミング」を分解する.ts 純粋性について 型でエフェクトを表す いつテストを書くか?―ソフトウェア開発における安心と不安について考える LLM時代のリファクタリング戦略:AIエージェントによる段階的・安全なTS移行方法 TypeScript の型で副作用の実行順序を制御する ZOZOのスポンサーブースの紹介 協賛企業ブースのコーディネートまとめ おわりに ZOZOのWebフロントエンドエンジニアが気になったセッション 開発体験を左右するライブラリの API 設計 ― GraphQL スキーマ構築ライブラリから考える ssssotaです。izumin5210さんの「開発体験を左右するライブラリの API 設計 ― GraphQL スキーマ構築ライブラリから考える」を紹介します。 speakerdeck.com このセッションでは、スキーマや型情報をいかにTypeScriptの実装に接続するかという観点で、既存ライブラリのアプローチやその長短を深ぼる内容でした。弊社ではOpenAPIを使っているケースが非常に多く、いかにOpenAPIスキーマを実装に接続するかは往々にして発生する問題の1つです。 セッションではGraphQLに焦点が当てられていましたが、スキーマから実装を生成するスキーマファースト、コードからスキーマを生成するコードファースト、コードファーストのうちDecoratorsを使うパターン、DSL的な独自のbuilderパターン、計3パターンについて評価していました。比較・評価軸として、1.スキーマと実装の分離、2.型整合性、3.DBモデルとの接続、の3軸を用いています。 スキーマと実装の分離については、スキーマファーストが優れているのは言うまでもありませんが分離する強いモチベーションがなければ優先度は低くなります。型整合性は採用するライブラリのtype ergonomicに依りますが、コードファーストなDSL builderパターンが強い傾向にあります。DBモデルとの接続においてはGraphQL特有と見ることができますが、コードファーストなDSL builderパターンで型整合問題と合わせて解決できることを示唆しています。 セッションの最後には、自作のライブラリでこのギャップを埋める取り組みとAIを用いた評価結果を紹介していました。気になる方はスライドも合わせて確認してみてはいかがでしょうか。 私自身、OpenAPIスキーマと実装の接続に関して関心があり、ライブラリ(openapi-ts-hono)を作った経験から非常に共感できるところがありました。もちろんGraphQLとはギャップがありますが、スキーマと実装の分離、型整合性などは感覚としてもっていながらも、改めて言語化されることで気付きのあるセッションでした。 「関数型プログラミング」を分解する.ts www_REM_zzzです。おーみーさんの『「関数型プログラミング」を分解する.ts』を紹介します。 tsk-2026-aumy.vercel.app 自分の話ですが、TypeScriptに入門する前はScalaを書いていた経験があります。当時はコップ本と呼ばれる本とHaskellの公式ドキュメントが日本語で関数型プログラミングに入門する入口でした。Object指向プログラミングとは全く別の世界からやってきたような考え方で、面白くもあり、苦労もした過去があります。 このセッションでは、そもそも関数型プログラミングとは何なのかの考え方に触れながら、TypeScriptで真の関数型はできないのかに触れられています。僕もTypeScriptで真の関数型が書けたらいいのにと思った一人です(OCaml書けよというのは一旦置いといて)。スライドの中で語られた関数型プログラミングは「いい感じのソフトウェアを作るため」というのは本質的だなと思いました。ついつい手段に引っ張られてしまうところがあるのですが、心に留めておきたいです。 純粋性について 特に純粋性についてのところはReactでも他のライブラリでも語られる部分であり、意味の純粋性の部分は悩ましいと感じたことがあるので共感しました。 // 「副作用を表す値」を返すだけ(純粋関数) function pureAlert(msg: string) { return ["alert", msg] as const; } // 副作用の実行は別の関数に委ねる function executeAction(action: readonly ["alert" | "confirm", string]) { switch (action[0]) { case "alert": alert(action[1]); break; case "confirm": confirm(action[1]); break; } } const actions = [pureAlert("hey"), pureAlert("bye")]; actions.forEach((a) => executeAction(a)); 引用:https://tsk-2026-aumy.vercel.app/29 このような「何をするかの宣言」と「実行」が分離されている書き方は普段からできるし、メンテナンスを考えると普段から実践していきたいと思いました。 returnは「この関数の呼び出し元(= 継続)に値を渡して戻る」という考え方はTSを書いていてなんとなく感じていたものがはっきりと言語化されてスッキリした気持ちになりました。 型でエフェクトを表す () => T // 特に何も起きない純粋な処理 () => Option<T> // 失敗しうる処理 () => Promise<T> // 非同期処理 これを徹底すると 関数の型を見るだけで「何が起きるか・何が起きないか」がわかる 純粋な部分と副作用のある部分が型レベルで分離される 「支払い処理を起こしうる部分」だけを特定して二重実行を防げる これはTypeScriptを堅牢に書くうえで実践したいと思います。ちょうど業務でも似たシチュエーションがあることを思い出して、まず「この関数は副作用を持つか?」を命名(execute, get, !記法)で示すのが現実的な入口かなと思いました。 いつテストを書くか?―ソフトウェア開発における安心と不安について考える ジン(@Jin_pro_01)です。自分の気になったセッションとして、lacolacoさんの「いつテストを書くか?―ソフトウェア開発における安心と不安について考える」を紹介します。 docs.google.com このセッションでは、テストをどのような時に書くべきなのかを「開発者の安心と不安」を起点に問い直したlacolacoさんの気づきの共有、問いの提示、視点の提案をするというセッションでした。 セッションの中ではソフトウェアの保守性の本質は「変更容易性」であり、それは予期的変更容易性(変更する前に感じる不安)と経験的変更容易性(変更をする中で実際に感じる手応え)の二層モデルとして見ることができるとしていました。その上でテストはその両方にフィードバックを返すセンサーであるとし、変更前に感じる不安があるならそれを取り除く安心のために書き、変更のしやすさを試したり構造に問題が見つかったりするなら設計を見直すために書くという体系的な整理がされており、とても興味深いセッションでした。 自分が従事しているZOZOTOWNでは、新規機能の実装や既存機能の改修と並行で、フロントエンドリプレイスも各チームで進行しています。ZOZOTOWNの発展を止めずに開発を進める体制である一方、考慮すべきことが多く、自分にとっては比較的「予期的変更容易性」が低い状態だと表現できることに気づきました。そして、まさにこの「予期的変更容易性」を高めるためのテストへの投資価値が高いと感じました。 さらにAIを使ってコーディングをしていく時代に入り、開発の生産量が増える一方で、自分が直接書いていないコードや構造との距離は広がっていきます。その距離は新たな不安、つまり予期的変更容易性の低下にもつながると感じています。だからこそ変更の前後で「振る舞いが変わっていないこと」を担保し、その不安を取り除くセンサーとしてのテストの価値は、AI時代にこそますます高まっていくのだと考えました。 <p
ZOZO開発組織の2026年3月分の活動を振り返り、ZOZO TECH BLOGで公開した記事や登壇・掲載情報などをまとめたMonthly Tech Reportをお届けします。 ZOZO TECH BLOG 2026年3月は、前月のMonthly Tech Reportを含む計19本の記事を公開しました。特に次の3記事は反響も大きく、とても多くの方に読まれています。ぜひご一読ください。 techblog.zozo.com techblog.zozo.com techblog.zozo.com 登壇 【Flutter推し活】Flutter好きが集うLT会 Studyplus x Linc'well 3月13日に開催された「【Flutter推し活】Flutter好きが集うLT会 Studyplus x Linc'well」に、新規事業部の大野(@junjun_1345)が登壇しました。 ZOZO フロントエンドMeetup 3月18日にZOZOで主催した「ZOZO フロントエンドMeetup」に、ZOZOTOWN開発3部の揚原、WEAR開発部の岩崎、ZOZOTOWN開発1部の佐藤、そしてZOZOTOWN企画開発部の片岡が登壇しました。 掲載 Apps in ChatGPT対応 OpenAIの対話型AI「ChatGPT」の新機能「Apps in ChatGPT」にファッション領域でいち早く対応し、アプリ連携を開始しました。このことが複数のメディアで取り上げられました。まだ試したことがない方はぜひ一度お試しください。 corp.zozo.com www.fashionsnap.com netkeizai.com ZOZOEDUCATION つくっちゃお! ZOZO初となる、子どもが“つくって売る”に挑戦できる教育プロジェクト「ZOZOEDUCATION つくっちゃお!」を始動しました。本プロジェクトの一環として、Tシャツのデザインから販売までを、親子が自宅で気軽に体験できるTシャツづくりキットを3月25日より販売開始しています。このことが複数のメディアで取り上げられました。親子で体験できる楽しいキットですので、ぜひお試しください。 corp.zozo.com www.nikkei.com kosodate.mynavi.jp 以上、2026年3月のZOZOの活動報告でした! ZOZOでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。 corp.zozo.com
はじめに こんにちは、ZOZOTOWN企画開発部 企画フロントエンド2ブロックのパクサンイです。普段はZOZOTOWNにあるCMSベースのLPページのメンテナンスや機能追加、企画LPページ環境のメンテナンスを担当しています。 ZOZOTOWNの複数のWebアプリケーション間で、プロモーション用ランディングページコンポーネントを共有するために、LitベースのWeb Componentsを導入しました。本記事ではその事例を紹介します。 ZOZOTOWNでは多数のLPページが開設・更新されており、従来はiframeを使った埋め込み方式でUIを共有していました。しかし、この方式にはさまざまな課題が存在し、レガシー環境からNext.jsベースの新環境へのリプレイスを進める中で、フレームワークに依存しないUI共有アーキテクチャが必要となりました。 本記事では、iframeベースの共有方式が抱える具体的な課題と、LitベースのWeb Componentsを採用した理由と選定プロセスを解説します。さらに、フレームワーク非依存なコンポーネント共有基盤を設計・実装する中で得た経験を共有します。 対象読者 マルチWebアプリケーション環境でUI共有に課題を感じているフロントエンドエンジニア iframeを使ったUI共有方式の代替手段を探している方 Web Componentsの導入を検討している方 目次 はじめに 対象読者 目次 背景・課題 ZOZOTOWNフロントエンドのマルチWebアプリケーション構成 LPコンポーネントの共有仕様 従来のiframeベース共有方式とその課題 1. レイアウト制御の煩雑さ 2. UI制御の複雑化 3. SEOの制約 アプローチ:Web Componentsの導入 要件整理 技術選定:Lit基盤Web Components Litを選択した理由 npmパッケージ方式を除外した理由 設計・実装 全体アーキテクチャ 1. 利用側アプリケーションによるデータ取得・加工 2. Lit ContextによるProps Drilling防止 3. Scriptローディングによる独立したUI更新 4. Shadow DOMからLight DOMへの切り替え ビルド・配信 全体フロー LPコンポーネント開発側(コンテンツ共有専用リポジトリ) 利用側Webアプリケーション 効果 学んだこと 今後の課題 今後の展望 まとめ 最後に 参考資料 背景・課題 ZOZOTOWNフロントエンドのマルチWebアプリケーション構成 現在、ZOZOTOWNのフロントエンドは3つのマルチWebアプリケーションで運用されています。 リポジトリ 説明 主な役割 リポジトリA(レガシー環境) 統合リポジトリ 既存の全ページを管理 リポジトリB(リプレイス環境) コアメインページ ホーム、カート、検索結果、商品詳細ページなど リポジトリC(リプレイス環境) 企画ページ フルスクラッチLP、CMS活用LP レガシー環境では複数のサービスが単一リポジトリで管理されていたため、共通UI共有に関する課題はありませんでした。しかし、リプレイス後にマルチWebアプリケーションが増えたことで、従来の方式ではUIを再利用できなくなりました。 LPコンポーネントの共有仕様 ZOZOTOWNでは特定のLPコンポーネントを複数のページで表示しています。一部のページでは以下の2つの形態で表示されます。 単独ランディングページ — header/footerを含むフルページ モーダル表示 — 特定ページのバナークリック時に、header/footerなしでコンテンツセクションのみをモーダルで表示 つまり、ほぼ同一のUIでありながら、header/footerの有無、SEOメタタグ、計測用トラッキングスクリプトの有無などで差異がある仕様でした。 従来のiframeベース共有方式とその課題 リプレイス後は以下の方式でUIを共有していました。 環境 運用方式 リポジトリA(レガシー) LPページ配信 + iframe用LPページ(header/footerなし)配信 リポジトリB・C(リプレイス) 特定ページにバナー表示 → クリック時にモーダル内でiframeとしてリポジトリAのLPを埋め込み このiframe方式には以下の課題が存在していました。 1. レイアウト制御の煩雑さ iframeは独立したドキュメントを読み込むため、フレームサイズの調整や使用箇所ごとの非表示領域の処理は対応していたものの、煩雑な部分がありました。 2. UI制御の複雑化 各バリエーションに応じて非表示にすべき子コンポーネントもあり、クエリパラメータやpostMessageで解決できるものの、ケースが増えるほど複雑化しました。 3. SEOの制約 検索エンジンはiframe内のコンテンツをsrc側の所有として認識するため、SEO上の制約がありました。 アプローチ:Web Componentsの導入 要件整理 上記の課題を解決するために、以下の4つの要件を整理しました。 要件 説明 各アプリのデプロイなしにUI更新 iframe方式の利点であった各マルチWebアプリケーションのデプロイなしにUI変更が反映されることを維持 iframe脱却 各アプリケーションでネイティブにUIをレンダリング フレームワーク非依存 React、Vueなど、どのフレームワークでも使用可能であること 軽量バンドルサイズ 利用側に負担のない最小限のサイズを維持 技術選定:Lit基盤Web Components Web Componentsはブラウザのネイティブコンポーネントモデルであり、特定のフレームワーク(React、Vueなど)に依存せず、ブラウザが直接理解する標準技術です。主に以下の3つの中核技術で構成されています。 Custom Elements:開発者が独自のHTMLタグを定義できる。タグ名にはハイフン(-)を含む規約がある。 Shadow DOM:コンポーネントのスタイルとマークアップを外部ページから隔離(Encapsulation)する。 HTML Templates:<template>と<slot>要素により、再利用可能なマークアップ構造を定義する。 このWeb Componentsをより効率的に開発するため、Litライブラリを採用しました。 Litを選択した理由 選定基準 Litの特徴 バンドルサイズ 約5KB(minified + compressed)で非常に軽量 リアクティブプロパティ Reactive Propertiesにより状態変更時に自動再レンダリング テンプレート Tagged Template Literalsベースで別途コンパイル不要 パフォーマンス Virtual DOM diffingなしに動的部分のみを直接更新 相互運用性 すべてのLitコンポーネントはネイティブWeb Componentであり、HTMLを使うあらゆる場所で動作 npmパッケージ方式を除外した理由 LPページはテキスト更新の頻度が高く、UIも不定期に変更されます。npmパッケージで運用すると、変更のたびに各環境でパッケージ更新+デプロイが必要となり、運用負荷が大きいため除外しました。 設計・実装 全体アーキテクチャ コンテンツ共有専用リポジトリを新たに構築し、以下の設計原則を適用しました。 1. 利用側アプリケーションによるデータ取得・加工 ZOZOTOWNにはページアクセス時に初期設定すべき値やAPIフェッチのためのロジックが各アプリケーションに存在します。これらのロジックをコンテンツ共有専用リポジトリにも含めると管理が二重になりメンテナンス負荷も大きくなるため、このリポジトリではUIレンダリングのみを責任範囲としました。 利用側の親アプリケーションでデータを取得・加工してpropsで渡す形式を採用しています。 2. Lit ContextによるProps Drilling防止 UI内部で必須的に共有すべき情報(デバイス種別、性別など)は、Lit Contextを活用したカスタム要素を設けて処理しました。 Lit ContextはReactのContext APIと同様の概念で、Props Drillingなしに上位から下位コンポーネントへデータを渡すことができます。 3. Scriptローディングによる独立したUI更新 各Webアプリケーションで別途デプロイなしにUI変更が可能なよう、Scriptローディングを採用しました。各アプリケーションでは<script>タグで必要なコンポーネントのJSファイルを読み込み、クライアントでWeb Componentがレンダリングされます。 4. Shadow DOMからLight DOMへの切り替え Web Componentsの代表的な特徴であるShadow DOMは、スタイルを完全に隔離し、コンポーネント内部のCSSが外部に影響せず、外部CSSも内部に影響しません。 しかし、今回のケースでは、Shadow DOMで隔離して管理するUIではなく、利用側から自由にスタイルだけでなく要素にもアクセスできることが重要でした。そのため、Shadow DOMの代わりにLight DOMを採用しました。 ビルド・配信 Viteを使用してLit基盤Web Componentをビルドし、S3にデプロイしてCDN経由で配信します。 全体フロー LPコンポーネント開発側(コンテンツ共有専用リポジトリ) Lit + Vite dev serverでローカル開発 各テスト環境にてHTML + JSで動作確認 問題なければ各環境(S3)にデプロイして確認 利用側Webアプリケーション SSR時にCMS APIでデータ取得(スケジュールに応じて変更されるテキストなどはCMSで管理) クライアントで<script>タグによるJSファイルローディング、Web Componentのレンダリング カスタムタグへCMS API仕様に合わせたデータをpropsで渡す 効果 この仕組みの導入により、以下の効果が得られました。 マルチWebアプリケーション間でiframeを使わずにUIコンポーネントを共有できるようになった 各アプリケーション側のリリース(デプロイ)なしでコンテンツ更新が可能になった 利用側からスタイルだけでなく要素へのアクセスも自由に可能になった(Light DOM採用) CMS連携により、エンジニア以外でも直接スケジュールベースのデータ管理が可能に 学んだこと Litを通じて開発する中で、Web Componentsのベースとなるウェブ標準技術をより深く理解し、関心を持つようになりました。また、CSS変数などを活用してJavaScriptなしにCSSだけでスタイルを制御する方法も知ることができました。 今後の課題 Web Components公式のSSR対応はまだ限定的ですが、Lit SSRなど複数の解決策がライブラリやコミュニティで共有されています。現在、このプロジェクトで管理しているLPページの仕様ではWeb ComponentのSSRは不要ですが、将来に備えた準備は必要だと考えています。 また、現在の運用方式では、Scriptローディング+CMSデータ連携という構造上、テストが非常に重要であり補強が必要です。<