Share
Embed
Transcript
40 slides
-
2026.11.01 TSKaigi Sendai 2026 100以上のプロジェクトを持つ NxモノレポのTypeScript 7移⾏の実践 ファインディ株式会社 Webエンジニア 甲斐
和基 @karukan029 © Findy Inc. 1 -
⾃⼰紹介 甲斐 和基(かるカン) ファインディ株式会社 / Web エンジニア ファインディ株式会社にて、Findy Freelance という
フリーランスエンジニア向けのサービスを開発しています。 プロダクトとコーヒーをエンジニアリングすることが好き。 𝕏 @karukan013L23 © Findy Inc. 2 -
今⽇話すこと 01 背景: Nx のモノレポと型チェック 02 TS7 への移⾏: 3 段階で進めた対応
03 移⾏の結果とまとめ © Findy Inc. 5 -
Nx とは? • モノレポやアプリケーションのビルド、テストの実⾏、 コード⽣成など の機能を備えた統合的なツール • ファインディのフロントエンドでは、 多くのプロダクトで Nx
を⽤いた モノレポを構築している タスク実⾏の並列化、変更検知とキャッシュ活⽤により、 CI の実⾏を効率化する © Findy Inc. 6 -
Findy Freelance のフロントエンドは Nx のモノレポ 01 02 03 Next.js アプリ
ライブラリ next build の中で React + Vite アプリ 型チェックする @nx/vite:build が 機能単位のものと、 Vite の前に 機能間で共通のもの アプリごとの 型チェックする アプリ + ライブラリ群 = 100 以上の Nx プロジェクト © Findy Inc. 7 -
変更検知とキャッシュ活⽤ 01 02 変更検知 タスク結果のキャッシュ 変更されたプロジェクトと、 実⾏済みタスクの結果を それに依存するプロジェクト キャッシュし、 だけを対象に実⾏できる
型チェックなど低速なタスクも 同じタスクの再実⾏を省ける スキップできる © Findy Inc. 8 -
TS7 への移⾏を、対応ごとに 3 段階に分けた TS6 の⾮推奨は TS7 で削除 TS7.0 には従来の
API がない TS6 に上げた段階で削除する API を使う周辺ツールへの 影響範囲を調べる TS6 移⾏前 TS6 移⾏ TS7 移⾏ TS5.9 のまま、 TS6 への更新と、 TS7 の追加と、 既定値と型定義の ⾮推奨になった 型チェックの切り替え 変更に対応 オプションの削除 © Findy Inc. 10 -
TS6 で試し、抑⽌しても残るエラーを洗い出した tsconfig.json { "compilerOptions": { "ignoreDeprecations": "6.0" } }
• まず ignoreDeprecations なしで実⾏し、⾮推奨のオプションを把握した • 次に ignoreDeprecations: "6.0" を付けて再実⾏し、 抑⽌しても残るエラー を洗い出した © Findy Inc. 12 -
抑⽌しても残るエラーは、TS6 移⾏前に直した • 既定値の変更: CSS の副作⽤ import → 型宣⾔を追加 •
既定値の変更: rootDir → rootDir の明⽰と outDir の削除 • DOM 型の変更: FileList → 新しい型定義に合わせて修正 どれも TypeScript 5.9 のままで直せる © Findy Inc. 13 -
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 -
FileList を新しい型定義に合わせて修正した dom.iterable の内容が dom に統合され、 lib が dom だけでも
FileList にイテレーターが加わった lib.dom.d.ts interface FileList { [Symbol.iterator](): ArrayIterator<File>; } © Findy Inc. 15 -
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 -
rootDir への対応は、⽤途で 2 つに分けた 01 02 宣⾔ファイル⽣成の tsconfig 型チェック専⽤の tsconfig
リポジトリのルートを --noEmit で出⼒しないので、 rootDir に明⽰し、 不要な outDir を削除する 参照先のソースを範囲内に含める - "outDir": "rootDir": "../.." "../../dist/typecheck" outDir があると、noEmit でも rootDir の範囲検査が⾛る © Findy Inc. 17 -
next build が失敗する baseUrl の⾮推奨エラーは抑⽌できたが、ビルドで別の問題が発⽣した tsc での型チェック ⾮推奨のエラーは、ignoreDeprecations で抑⽌できる Next.js
16.2.x のビルド バンドルは通るが、next build の型チェックで失敗する エラー Type error: Cannot find module '@my-org/feature-a' © Findy Inc. 18 -
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 -
書き換え後のパスは、リポジトリの外を指す Next.js の想定 apps/my-app/tsconfig.json から ../../ → ルート TypeScript のパス解決
tsconfig.base.json から ../../ → リポジトリの外 Cannot find module '@my-org/feature-a' © Findy Inc. 20 -
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 -
TS6 で⾮推奨になったオプションは、TS7 で削除される ① TS6 移⾏ ② オプション削除 ③ TS7
移⾏ ⾮推奨になった ⾮推奨になった 削除を終えてから オプションは残す オプションを消す 切り替える © Findy Inc. 23 -
Compiler API は、型チェック以外でも使われる ツール Compiler API の⽤途 Next.js next build
の中で型チェックする @nx/vite:build Vite を呼ぶ前に型チェックする typescript-eslint 構⽂⽊を ESLint ⽤に変換する vite-plugin-dts 宣⾔ファイルを⽣成する © Findy Inc. 24 -
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 -
TS6 に上げてから、⾮推奨のオプションを順に削除した 01 esModuleInterop: false を残したまま、TS6 で動作を確認 02 esModuleInterop: false
を削除 03 ⾮推奨のオプションを消し終えたら、ignoreDeprecations も削除 TS6 への更新と esModuleInterop の変更の影響を、分けて確認するため © Findy Inc. 26 -
ブリッジを固定しても、実体のコンパイラのバージョンは固定されない 固定済みのブリッジ 未固定の実体のコンパイラ package.json で 6.0.2 に固定 ブリッジの依存 @typescript/old は
API や CLI の処理を npm:typescript@^6 で解決される コンパイラ実体へ渡すパッケージ ほかの依存を更新したときに、 意図しないバージョンになりうる package.json "overrides": { "@typescript/old": "npm:[email protected]" } © Findy Inc. 27 -
TS7.0 には、従来の Compiler API がない • Compiler API を使うツールは、このままでは TS7
に移せない 例: typescript-eslint、vite-plugin-dts • 型チェックの CLI は TS7、API を使う周辺ツールは TS6 にして、 TS6 と TS7 を共存させた © Findy Inc. 29 -
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 -
tsc は TS7 に、require は TS6 に解決される CLI として呼ぶ tsc
--noEmit .bin/tsc = TS7 TS7 Compiler API として読み込む require('typescript') typescript = TS6 ブリッジ TS6 © Findy Inc. 31 -
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 -
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 -
ローカルの型チェックは、TS7 で約 3 倍速くなった 48 秒 15.8 秒 TS6: tsc6
TS7: tsc 全プロジェクトの typecheck を、--skip-nx-cache で キャッシュを使わず同じ条件で実⾏ © Findy Inc. 35 -
CI のステップは、TS7 で約 35% 短縮した TS5.9 366.0 秒 TS6 367.0
秒 TS7 239.4 秒 lint‧stylelint‧typecheck を合わせたステップの平均で、 typecheck 単体の時間ではない © Findy Inc. 36 -
まとめ 段階に分けた TS6 と TS7 を併⽤ 速くなった TS6 移⾏前 →
TS6 移⾏ CLI は TS7、 ローカルの型チェック → TS7 移⾏。 Compiler API を使う 約 3 倍、 段階ごとに検証 周辺ツールは TS6 CI のステップ 約 35% 短縮 CLI は TS7、Compiler API は TS6 と使い分けたことで、 周辺ツールを動かしながら、 型チェックを TS7 へ切り替えられた © Findy Inc. 37 -
今後の展望 useTypeScriptCli を有効に戻せるか確認する tsc6 を検出できない問題は Next.js 16.3.4 で修正された。 既定の CLI
⽅式に戻せる⾒込み next build などの型チェックを、typecheck タスクに任せる next build と @nx/vite:build は、今も TS6 で型チェックしている。 ビルド側の型チェックを⽌めれば、ビルドの時間も短くなる⾒込み 周辺ツールの TS7 対応の動向を追い、 より快適に開発できる環境を整えていく © Findy Inc. 38 -
参考資料 • 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