Slide 1

Slide 1 text

© LayerX Inc. TypeScriptを活用したi18n対応 スプシの翻訳情報を用いた型付けと段階的i18n対応のためのカスタムESLint

Slide 2

Slide 2 text

目次 Agenda ● 自己紹介・会社紹介(1min) ● i18nパッケージのt関数に型を付けた話(4mins) ● 翻訳漏れを防ぐカスタムESLintを作った話(4mins) ● 終わりに(1min)

Slide 3

Slide 3 text

自己紹介・会社紹介

Slide 4

Slide 4 text

© LayerX Inc. 4 ● 2023年8月 株式会社LayerX 入社 ○ バクラク申請・経費精算 ソフトウェアエンジニア ● 型しか勝たん 山本美奈子(minako-ph) 自己紹介 ● ex - ○ 株式会社メディカルフォース ■ リードエンジニア ○ DMM.comグループ 株式会社終活ねっと ■ フロントエンドエンジニア

Slide 5

Slide 5 text

5 © LayerX Inc. すべての経済活動を、デジタル化する。 会社概要 会社名 株式会社LayerX(レイヤーエックス) 代表取締役 代表取締役CEO 福島 良典 代表取締役CTO 松本 勇気 創業 2018年 8月1日 資本金 約132.6億円 拠点 東京本社 〒103-0012 東京都中央区日本橋堀留町1丁目9−8 人形町PREX 関西支社 〒530-0003 大阪府大阪市北区堂島1-1-5 関電不動産梅田新道ビル 中部支社 〒453-6111 愛知県名古屋市中村区平池町4-60-12 グローバルゲート 九州支社 〒810-0801 福岡県福岡市博多区中洲3-7-24 従業員数 250名 (2023年12月末日時点)

Slide 6

Slide 6 text

6 © LayerX Inc. 「すべての経済活動を、デジタル化する。」をミッションに掲げ、 法人支出管理サービス「バクラク」や企業内業務のデジタル化を支援するサービスを提供しています。 事業紹介 バクラク事業 企業活動のインフラとなる法人支出 管理(BSM)SaaSを開発・提供 Fintech事業 ソフトウェアを駆使したアセットマネジメ ント・証券事業を合弁会社にて展開 AI・LLM事業 文書処理を中心とした、LLMの活用による プロセスのリデザイン

Slide 7

Slide 7 text

7 © LayerX Inc. バクラク事業紹介 稟議・支払申請・経費精算 仕訳・支払処理効率化 法人カードの発行・管理 帳票保存・ストレージ 帳票発行 ・AIが領収書を5秒でデータ化 ・スマホアプリとSlack連携あり ・領収書の重複申請などミス防止機能 ・AIが請求書を5秒でデータ化 ・仕訳・振込データを自動作成 ・稟議から会計までスムーズに連携 ・年会費無料で何枚でも発行可 ・インボイス制度・電帳法対応 ・すべての決済で1%以上の還元 ・AIが書類を5秒でデータ化 ・あらゆる書類の電子保管に対応 ・電子取引・スキャナ保存に完全対応 ・帳票の一括作成も個別作成も自由自在 ・帳票の作成・稟議・送付・保存を一本化 ・レイアウトや項目のカスタマイズも可能 バックオフィス系のSaaSを提供している事業

Slide 8

Slide 8 text

i18nパッケージのt関数に型を付けた話 @nuxt/i18nのt関数にパッチを当ててスプシから生成された翻訳情報で型を付ける

Slide 9

Slide 9 text

© LayerX Inc. 9 ● @nuxt/i18nではt関数に翻訳情報のkeyを渡すことで国際化ができます ● しかし... 存在しないキーを渡せてしまい、予測補完も効かないのでタイポを起こしやすい💦 ● 変数の渡し忘れや変数名の間違いなど、変数の過不足に気付けない😭 @nuxt/i18nに型を当てる前の状態 @nuxt/i18nの`t()`関数にパッチを当ててスプシから生成された翻訳情報で型を付ける

Slide 10

Slide 10 text

© LayerX Inc. 10 ● 私たちは翻訳作業をスプレッドシート上で非同期で進めていて、それをスクリプトでロードしながらプロ ダクトに適用しています 1. スプレッドシートで定義されているkeyが、t関数のキーの型として当たること 2. スプレッドシートで定義されている翻訳情報に含まれる変数が、t関数の変数の型として当たること 3. 型が当たることにより予測補完が効き開発体験が保証されること 要件 @nuxt/i18nの`t()`関数にパッチを当ててスプシから生成された翻訳情報で型を付ける

Slide 11

Slide 11 text

© LayerX Inc. 11 1. スプレッドシートから翻訳情報jsonを生成 2. 翻訳情報jsonからt関数に当てる型ファイルを生成 3. patchファイルで元のt関数の定義を削除 4. 生成された型ファイルでt関数のキーと変数に型を当てる 全体のアーキテクチャ @nuxt/i18nの`t()`関数にパッチを当ててスプシから生成された翻訳情報で型を付ける

Slide 12

Slide 12 text

© LayerX Inc. 12 ● i18nはFEだけでなくBEやNativeAppでも実装されるので、 jsonの生成スクリプトは別途リポジトリを立ててそちらに用意 スプレッドシートから翻訳情報jsonを生成 @nuxt/i18nの`t()`関数にパッチを当ててスプシから生成された翻訳情報で型を付ける

Slide 13

Slide 13 text

© LayerX Inc. 13 ● ts-nodeで実行可能なmtsファイルにスクリプトを用意し以下の ようなMessagesインターフェースの型を作成 ○ 翻訳情報にアクセスするキーをMessagesのキーに ○ 翻訳情報の中で変数プレースホルダが使用されていれば paramsに変数として抽出 翻訳情報jsonからt関数に当てる型ファイルを生成 @nuxt/i18nの`t()`関数にパッチを当ててスプシから生成された翻訳情報で型を付ける

Slide 14

Slide 14 text

© LayerX Inc. 14 ● TypeScriptでは、ライブラリの型定義に何かを追加はできても削除はできず、t関数を真に型安全に することが難しかったです ● そのためpnpmに搭載されているpatchコマンドを使用してパッチを当てることで対応しました ○ t関数に関する型定義のコメントアウトを行いました ○ pnpm patchはパッケージのコードに対するローカルな変更を容易に行える機能です(便利!) patchファイルで元のt関数の定義を削除 @nuxt/i18nの`t()`関数にパッチを当ててスプシから生成された翻訳情報で型を付ける

Slide 15

Slide 15 text

© LayerX Inc. 15 ● 生成されたMessagesをt関数に当てる ○ t関数のキーにMessagesのキーを型として当てた ○ t関数の変数を受け取る引数にMessagesのparamsに格納しておいた変数を型として当てた 生成された型ファイルでt関数のキーと変数に型を当てる @nuxt/i18nの`t()`関数にパッチを当ててスプシから生成された翻訳情報で型を付ける

Slide 16

Slide 16 text

© LayerX Inc. 16 ● キーや変数の予測補完が効くようになった ● 存在しないキーへのアクセスに対してエラーが出るようになった ● 変数の渡し忘れや変数名の間違いなど変数の過不足に対してエラーが出るようになった 型が当たるようになった結果✨ @nuxt/i18nの`t()`関数にパッチを当ててスプシから生成された翻訳情報で型を付ける

Slide 17

Slide 17 text

翻訳漏れを防ぐカスタムESLintを作った話 段階的なi18n対応のために特定ファイルから参照されるコードのみに翻訳漏れを検証するカスタムESLint

Slide 18

Slide 18 text

© LayerX Inc. 18 ● コンポーネントのネストが深くて対応漏れがないか不安... ● 一律で日本語が実装されていたらNGにしたいけど、今回は一部ページしか対応しないので、世の中に 存在するi18n対応漏れ検証Lintを適用させることができない😭 ● i18n対応するページから参照される処理だけにLintを適応させたい💦 ということで、特定ページから参照されるコードにのみ 翻訳漏れを検証するカスタムESLintを用意することにしました💡 i18n対応してみたけど... 段階的なi18n対応のために特定ファイルから参照されるコードのみに翻訳漏れを検証するカスタムESLint

Slide 19

Slide 19 text

© LayerX Inc. 19 ● 指定されたページから参照されるコードに限定して翻訳漏れがないことを検出するカスタムESLint ルールを実装する ○ 翻訳漏れはt関数で囲われているかで検証 ○ 参照されるコードはコンポーネント・関数・変数に限定して、再帰して末端まで検証 ● i18n対応は指定されたページに限定したいので、翻訳すべきコードをページ起点で検索する 要件 段階的なi18n対応のために特定ファイルから参照されるコードのみに翻訳漏れを検証するカスタムESLint

Slide 20

Slide 20 text

© LayerX Inc. 20 1. jsonファイルに翻訳対象となるページを定義 2. mtsで用意したスクリプトからESLintを実行 3. 指定されたページから参照されるコードを再帰的に検索 し、翻訳漏れを検知 全体のアーキテクチャ 段階的なi18n対応のために特定ファイルから参照されるコードのみに翻訳漏れを検証するカスタムESLint

Slide 21

Slide 21 text

© LayerX Inc. 21 ● 翻訳対象となるページの.vueファイルパスをtargetPagesとしてjsonに定義 jsonファイルに翻訳対象となるページを定義 段階的なi18n対応のために特定ファイルから参照されるコードのみに翻訳漏れを検証するカスタムESLint

Slide 22

Slide 22 text

© LayerX Inc. 22 ● ts-nodeで実行可能なmtsファイルにスクリプトを用意し、カスタムESLintを実行する ○ 再帰により別ファイルへのアクセスが発生するが、デフォルトの出力だと元のファイルに対しての エラーとして出力されてしまうので、どのファイルに対するエラーなのかが分かるように出力結 果をカスタマイズする為に、スクリプトを用意しました ○ コマンドラインの出力結果は「chalk」で色をつけてます mtsで用意したスクリプトからESLintを実行 段階的なi18n対応のために特定ファイルから参照されるコードのみに翻訳漏れを検証するカスタムESLint

Slide 23

Slide 23 text

© LayerX Inc. 23 【1】 vueファイルをASTに変換 a. template内のNodeを末端まで再帰して翻 訳漏れがないか検証 b. script内のNodeを末端まで再帰して翻訳 漏れがないか検証 指定されたページから参照されるコードを再帰的に検索し、翻訳漏れを検知 段階的なi18n対応のために特定ファイルから参照されるコードのみに翻訳漏れを検証するカスタムESLint

Slide 24

Slide 24 text

© LayerX Inc. 24 【2】 importがある場合の処理 a. vueファイルのimportがあれば、vueファイ ルの検証に再帰させる b. tsファイルのimportがあれば、そのtsファイ ルをASTに変換し、importされている処理 を抽出してscriptの検証に再帰させる 指定されたページから参照されるコードを再帰的に検索し、翻訳漏れを検知 段階的なi18n対応のために特定ファイルから参照されるコードのみに翻訳漏れを検証するカスタムESLint

Slide 25

Slide 25 text

© LayerX Inc. 25 【3】 翻訳漏れのレポート a. t関数で囲われていない日本語が見つかればレ ポートする このレポートのお陰でi18n対応すべき箇所がCIで検知で きるようになり、対応漏れも防げるようになりました🤩 指定されたページから参照されるコードを再帰的に検索し、翻訳漏れを検知 段階的なi18n対応のために特定ファイルから参照されるコードのみに翻訳漏れを検証するカスタムESLint

Slide 26

Slide 26 text

終わりに

Slide 27

Slide 27 text

© LayerX Inc. 27 We are hiring! LayerXのプロダクトメンバーと美味しいお酒やご飯を囲み ながら、プロダクトやチーム、技術の話をゆる〜く行うイベン トを定期的に行っています。 直近の予定は以下のとおりです。 LayerX Casual Night ※原則招待制です。気になるかたはDM(@minako___ph)等でコンタ クトください。 LayerX Casual Night LayerX Open Door アカウント登録が一切不要なカジュアル面談を公開しています。 ・私と雑談してみたい ・質問したいことがある ・選考に進むか悩んでいる などなど、お気軽にお申し込みください。 日程 テーマ 7/23(火) 19時ごろ〜 🍻 Beer Night