Upgrade to Pro — share decks privately, control downloads, hide ads and more …

100以上のプロジェクトを持つNxモノレポのTypeScript 7移行の実践

karukan029
November 01, 2026
58

100以上のプロジェクトを持つNxモノレポのTypeScript 7移行の実践

karukan029

November 01, 2026

Transcript

40 slides
  1. ⾃⼰紹介 甲斐 和基(かるカン) ファインディ株式会社 / Web エンジニア ファインディ株式会社にて、Findy Freelance という

    フリーランスエンジニア向けのサービスを開発しています。 プロダクトとコーヒーをエンジニアリングすることが好き。 𝕏 @karukan013L23 © Findy Inc. 2
  2. Nx とは? • モノレポやアプリケーションのビルド、テストの実⾏、 コード⽣成など の機能を備えた統合的なツール • ファインディのフロントエンドでは、 多くのプロダクトで Nx

    を⽤いた モノレポを構築している タスク実⾏の並列化、変更検知とキャッシュ活⽤により、 CI の実⾏を効率化する © Findy Inc. 6
  3. Findy Freelance のフロントエンドは Nx のモノレポ 01 02 03 Next.js アプリ

    ライブラリ next build の中で React + Vite アプリ 型チェックする @nx/vite:build が 機能単位のものと、 Vite の前に 機能間で共通のもの アプリごとの 型チェックする アプリ + ライブラリ群 = 100 以上の Nx プロジェクト © Findy Inc. 7
  4. TS7 への移⾏を、対応ごとに 3 段階に分けた TS6 の⾮推奨は TS7 で削除 TS7.0 には従来の

    API がない TS6 に上げた段階で削除する API を使う周辺ツールへの 影響範囲を調べる TS6 移⾏前 TS6 移⾏ TS7 移⾏ TS5.9 のまま、 TS6 への更新と、 TS7 の追加と、 既定値と型定義の ⾮推奨になった 型チェックの切り替え 変更に対応 オプションの削除 © Findy Inc. 10
  5. TS6 で試し、抑⽌しても残るエラーを洗い出した tsconfig.json { "compilerOptions": { "ignoreDeprecations": "6.0" } }

    • まず ignoreDeprecations なしで実⾏し、⾮推奨のオプションを把握した • 次に ignoreDeprecations: "6.0" を付けて再実⾏し、 抑⽌しても残るエラー を洗い出した © Findy Inc. 12
  6. 抑⽌しても残るエラーは、TS6 移⾏前に直した • 既定値の変更: CSS の副作⽤ import → 型宣⾔を追加 •

    既定値の変更: rootDir → rootDir の明⽰と outDir の削除 • DOM 型の変更: FileList → 新しい型定義に合わせて修正 どれも TypeScript 5.9 のままで直せる © Findy Inc. 13
  7. CSS の副作⽤ import に型宣⾔を追加した noUncheckedSideEffectImports の既定値が true になり、 副作⽤ import

    でも参照先を解決できないとエラーになる 副作⽤ import import '@my-org/ui/styles.css'; env.d.ts declare module '@my-org/ui/styles.css' {} © Findy Inc. 14
  8. FileList を新しい型定義に合わせて修正した dom.iterable の内容が dom に統合され、 lib が dom だけでも

    FileList にイテレーターが加わった lib.dom.d.ts interface FileList { [Symbol.iterator](): ArrayIterator<File>; } © Findy Inc. 15
  9. TS6 では、rootDir の既定値が変わる 例: libs/feature-a の tsconfig.json で型チェックし、 libs/core/src/index.ts を

    import している TS5.9 TS6 rootDir 未指定なら、 tsconfig の配置ディレクトリが ⼊⼒ソース全体の 既定値になる 共通ディレクトリを推論 rootDir = libs/feature-a rootDir = libs File '.../core/src/index.ts' libs/core/src/index.ts も範囲内 is not under 'rootDir' © Findy Inc. 16
  10. rootDir への対応は、⽤途で 2 つに分けた 01 02 宣⾔ファイル⽣成の tsconfig 型チェック専⽤の tsconfig

    リポジトリのルートを --noEmit で出⼒しないので、 rootDir に明⽰し、 不要な outDir を削除する 参照先のソースを範囲内に含める - "outDir": "rootDir": "../.." "../../dist/typecheck" outDir があると、noEmit でも rootDir の範囲検査が⾛る © Findy Inc. 17
  11. next build が失敗する baseUrl の⾮推奨エラーは抑⽌できたが、ビルドで別の問題が発⽣した tsc での型チェック ⾮推奨のエラーは、ignoreDeprecations で抑⽌できる Next.js

    16.2.x のビルド バンドルは通るが、next build の型チェックで失敗する エラー Type error: Cannot find module '@my-org/feature-a' © Findy Inc. 18
  12. Next.js 16.2.x が paths を ../../ 付きに書き換える tsconfig.base.json(リポジトリのルート) "@my-org/feature-a": ["libs/feature-a/src/index.ts"]

    ↓ apps/my-app/tsconfig.json からの相対パスに書き換える 書き換え後の paths "@my-org/feature-a": ["../../libs/feature-a/src/index.ts"] © Findy Inc. 19
  13. 書き換え後のパスは、リポジトリの外を指す Next.js の想定 apps/my-app/tsconfig.json から ../../ → ルート TypeScript のパス解決

    tsconfig.base.json から ../../ → リポジトリの外 Cannot find module '@my-org/feature-a' © Findy Inc. 20
  14. baseUrl を消し、paths を ./ 始まりにした tsconfig.base.json - "baseUrl": ".", "paths":

    { - "@my-org/feature-a": ["libs/feature-a/src/index.ts"] + "@my-org/feature-a": ["./libs/feature-a/src/index.ts"] } • baseUrl がないと、paths は定義した tsconfig からの 相対パスで解決される • baseUrl を前提にしていた Storybook の設定も調整した © Findy Inc. 21
  15. TS6 で⾮推奨になったオプションは、TS7 で削除される ① TS6 移⾏ ② オプション削除 ③ TS7

    移⾏ ⾮推奨になった ⾮推奨になった 削除を終えてから オプションは残す オプションを消す 切り替える © Findy Inc. 23
  16. Compiler API は、型チェック以外でも使われる ツール Compiler API の⽤途 Next.js next build

    の中で型チェックする @nx/vite:build Vite を呼ぶ前に型チェックする typescript-eslint 構⽂⽊を ESLint ⽤に変換する vite-plugin-dts 宣⾔ファイルを⽣成する © Findy Inc. 24
  17. TS6 はブリッジで⼊れ、typecheck を tsc6 に変えた package.json "devDependencies": { "typescript": "npm:@typescript/[email protected]"

    } • Next.js や typescript-eslint は従来どおり typescript パッケージから TS6 の Compiler API を読む • CLI は tsc6 になり、typecheck は tsc6 --noEmit に変更 • ブリッジにしたのは、あとで TS7 と共存させるため © Findy Inc. 25
  18. TS6 に上げてから、⾮推奨のオプションを順に削除した 01 esModuleInterop: false を残したまま、TS6 で動作を確認 02 esModuleInterop: false

    を削除 03 ⾮推奨のオプションを消し終えたら、ignoreDeprecations も削除 TS6 への更新と esModuleInterop の変更の影響を、分けて確認するため © Findy Inc. 26
  19. ブリッジを固定しても、実体のコンパイラのバージョンは固定されない 固定済みのブリッジ 未固定の実体のコンパイラ package.json で 6.0.2 に固定 ブリッジの依存 @typescript/old は

    API や CLI の処理を npm:typescript@^6 で解決される コンパイラ実体へ渡すパッケージ ほかの依存を更新したときに、 意図しないバージョンになりうる package.json "overrides": { "@typescript/old": "npm:[email protected]" } © Findy Inc. 27
  20. TS7.0 には、従来の Compiler API がない • Compiler API を使うツールは、このままでは TS7

    に移せない 例: typescript-eslint、vite-plugin-dts • 型チェックの CLI は TS7、API を使う周辺ツールは TS6 にして、 TS6 と TS7 を共存させた © Findy Inc. 29
  21. TS7 は別名で追加し、tsc を TS7 にした package.json "devDependencies": { "typescript": "npm:@typescript/[email protected]",

    "@typescript/native": "npm:[email protected]" } • typescript という名前は、TS6 のブリッジのまま • typecheck を tsc6 --noEmit から tsc --noEmit へ切り替えると、 TS7 で型 チェックできる © Findy Inc. 30
  22. tsc は TS7 に、require は TS6 に解決される CLI として呼ぶ tsc

    --noEmit .bin/tsc = TS7 TS7 Compiler API として読み込む require('typescript') typescript = TS6 ブリッジ TS6 © Findy Inc. 31
  23. next build が失敗した Next.js 16.3.0 で experimental.useTypeScriptCli が既定で有効になり、 型チェックが tsc

    を起動する CLI ⽅式に変わった バンドラー 症状 Turbopack TypeScript パッケージの不⾜を⽰すエラー webpack tsconfig の paths が無視され、 パスエイリアスを解決できないエラー Next.js 16.3.0 が、typescript として⼊れた TS6 ブリッジの tsc6 を検出できなかった © Findy Inc. 32
  24. useTypeScriptCli を無効にして回避した next.config.js const nextConfig = { experimental: { useTypeScriptCli:

    false, }, }; module.exports = nextConfig; • Compiler API ⽅式に戻る • Nx の typecheck は TS7、next build 内の型チェックは TS6 で実⾏ • tsc6 を検出できない問題は、Next.js 16.3.4 で修正された © Findy Inc. 33
  25. ローカルの型チェックは、TS7 で約 3 倍速くなった 48 秒 15.8 秒 TS6: tsc6

    TS7: tsc 全プロジェクトの typecheck を、--skip-nx-cache で キャッシュを使わず同じ条件で実⾏ © Findy Inc. 35
  26. CI のステップは、TS7 で約 35% 短縮した TS5.9 366.0 秒 TS6 367.0

    秒 TS7 239.4 秒 lint‧stylelint‧typecheck を合わせたステップの平均で、 typecheck 単体の時間ではない © Findy Inc. 36
  27. まとめ 段階に分けた TS6 と TS7 を併⽤ 速くなった TS6 移⾏前 →

    TS6 移⾏ CLI は TS7、 ローカルの型チェック → TS7 移⾏。 Compiler API を使う 約 3 倍、 段階ごとに検証 周辺ツールは TS6 CI のステップ 約 35% 短縮 CLI は TS7、Compiler API は TS6 と使い分けたことで、 周辺ツールを動かしながら、 型チェックを TS7 へ切り替えられた © Findy Inc. 37
  28. 今後の展望 useTypeScriptCli を有効に戻せるか確認する tsc6 を検出できない問題は Next.js 16.3.4 で修正された。 既定の CLI

    ⽅式に戻せる⾒込み next build などの型チェックを、typecheck タスクに任せる next build と @nx/vite:build は、今も TS6 で型チェックしている。 ビルド側の型チェックを⽌めれば、ビルドの時間も短くなる⾒込み 周辺ツールの TS7 対応の動向を追い、 より快適に開発できる環境を整えていく © Findy Inc. 38
  29. 参考資料 • TypeScript — Announcing TypeScript Native Previews / 7.0

    Beta / 7.0 RC / 7.0 / 7.1 Beta、6.0 リリースノート(devblogs.microsoft.com/typescript、 typescriptlang.org) • Nx — Knowledge Base: TypeScript 7(nx.dev/docs/kb/typescript-7) • Next.js — useTypeScriptCli(nextjs.org/docs)/ Issue #93336‧#96589‧#97015、 PR #93377(github.com/vercel/next.js) © Findy Inc. 39