TypeScript 6.0へ上げたいけど、Next.js 16.2でmoduleResolutionやbaseUrlまわりが崩れそうで不安、という人に向けて書きました。この記事を読むと、tsconfigをどこから直すか、CIでどう再発を止めるかまで一気に整理できます。僕は福祉事業のIT全般を担当しながら、複業でAI×SaaS開発も回しているので、複数案件を止めない移行手順として実務ベースでまとめます。
こんな方におすすめ
- TypeScript 6.0 Stable 移行を進めたいが、設定差分の洗い出しに時間がかかっている方
- Next.js 16.2 moduleResolution baseUrl の警告やエラーで手が止まった方
- tsconfig CI 回帰テストを導入して、再発防止まで仕組み化したい方
- 非エンジニアメンバーにも説明できる移行手順を作りたい方
この記事でわかること
- 2026年3月時点のTypeScript/Next.jsの最新状況(RC/Stable差分)
moduleResolutionとbaseUrlでつまずく根本原因- 壊さず進めるtsconfig修正手順と、実運用向けの分割戦略
- GitHub Actionsで回すCI回帰テストのテンプレート
公開前確認(2026年5月時点):TypeScript移行では公式ドキュメントのProject ConfigurationとModules Referenceを基準に、baseUrlや古いmoduleResolutionをCIで検出し、Next.js側のサポート範囲も同時に確認してください。
TypeScript 6.0移行で最初に押さえる事実(2026年3月時点)
まず日付をそろえておきます。TypeScript公式ブログでは、2026年3月6日に「TypeScript 6.0 RC」が公開されています。つまり2026年3月27日時点では、確認できる公式アナウンスはRCが最新です。一方でNext.jsは、2026年3月18日に16.2、3月20日に16.2.1が出ています。
- 2026-03-06 — TypeScript 6.0 RC公開(移行用の非互換整理が本格化)
- 2026-03-18 — Next.js 16.2公開(開発体験と性能改善が中心)
- 2026-03-20 — Next.js 16.2.1公開(バグ修正のバックポート)
- 2026-03-24以降 — 16.2.1 canaryでTS6関連の修正が継続投入
ここで大事なのは、「TS側の非推奨化」と「Next側の追随タイミング」はズレるという点です。イメージとしては、道路工事(TypeScript)が先に始まって、信号制御(Next.js)が順次アップデートされる感じです。だからこそ、単純なバージョンアップではなく、設定ファイルとCIをセットで更新するのが現実的です。
Next.js 16.2でmoduleResolution/baseUrlが問題化する理由
問題の芯は2つです。1つ目は、TypeScript 6.0 RCでmoduleResolution: node(実質node10)が非推奨寄りになったことです。2つ目は、baseUrlの扱いが見直され、以前の“なんとなく解決”が通らなくなったことです。公式のmoduleResolutionドキュメントでも、node10は現代用途では通常不要と明記されています。
さらに、Next.js側でも以前から課題化していて、Issue #82017ではmoduleResolutionをnodeに寄せる挙動が議論されています。16.2.1 stableのリリースノートには「canaryの全変更は含まれない」と明記があり、canary側には「deprecated TS node10 defaults回避」「TS6 baseUrl deprecation修正(extended tsconfig)」が入っています。つまり、stable運用中のプロジェクトほど自前で守りを作る必要があります。
| 項目 | 旧来のよくある設定 | TS 6.0移行時のリスク | 推奨方針 |
|---|---|---|---|
| moduleResolution | node |
非推奨警告・将来破綻 | Nextアプリはbundler、Node実行はnodenext |
| baseUrl | "./src"で曖昧解決 |
意図しない解決先が混入 | pathsに明示プレフィックス移行 |
| extends構成 | 親で共通化しすぎ | 子設定で警告が再発 | runtime別にtsconfigを分離 |
| CIチェック | next buildのみ |
設定回帰を検知しにくい | tsc --noEmit+設定検証スクリプト |
つまり、エラーは「Next.jsが悪い」ではなく、tsconfigの世代差分が露出した結果です。 ここを理解すると、対処が一気にシンプルになります。
tsconfigを壊さず直す手順(baseUrl撤去とpaths再定義)
ここは手順でいきます。まずは現状把握、次に置換、最後に用途別分割です。難しそうに見えますが、やることは3ステップです。
- 解決後設定を可視化 —
npx tsc --showConfig > .tmp/tsconfig.resolved.jsonで、extends後の実態を確認します。 - baseUrl依存を除去 —
baseUrlを消し、paths側へ明示プレフィックスを寄せます。 - runtimeで分離 — Web側は
moduleResolution: "bundler"、Nodeスクリプト側は"nodenext"に分けます。
// before (よくある形)
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@app/*": ["app/*"],
"@lib/*": ["lib/*"]
},
"moduleResolution": "node"
}
}
// after (TS6移行向け)
{
"compilerOptions": {
"paths": {
"@app/*": ["./src/app/*"],
"@lib/*": ["./src/lib/*"]
},
"moduleResolution": "bundler"
}
}
モノレポなら、さらに分けると安全です。tsconfig.app.jsonはbundler、tsconfig.scripts.jsonはnodenextという形です。baseUrlの公式説明にも、設計意図と現在の推奨が整理されています。
つまずきやすいポイント
- 親tsconfigだけ直して安心 — 子で上書きされて再発しやすいです
- pathsの先頭
./を省略 — 環境差で解決結果がぶれやすいです - rootDir未指定のまま — TS6系では意図外の出力構造になることがあります
「baseUrlを消すだけ」では不十分で、pathsを“実パス前提”に作り直すのがコツです。
tsconfig CI 回帰テストを作る(GitHub Actions実装例)
次は再発防止です。Next.js公式ドキュメントでも、CIでtsc --noEmitを別途回す運用が推奨されています。つまり、next buildだけでは守り切れません。ここは「型チェック」と「設定チェック」を分離すると安定します。
name: tsconfig-regression
on:
pull_request:
workflow_dispatch:
jobs:
verify:
runs-on: ubuntu-latest
strategy:
matrix:
node: [20, 22]
next_channel: ["16.2.1", "canary"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm i -D next@${{ matrix.next_channel }} typescript@rc
- run: npx tsc -p tsconfig.json --noEmit
- run: node scripts/check-tsconfig.mjs
- run: npx next build
// scripts/check-tsconfig.mjs
import { execSync } from "node:child_process";
const raw = execSync("npx tsc --showConfig", { encoding: "utf8" });
const cfg = JSON.parse(raw);
const c = cfg.compilerOptions ?? {};
const errors = [];
if (c.moduleResolution "node" || c.moduleResolution "node10") {
errors.push("moduleResolution=node/node10 はNG");
}
if ("baseUrl" in c) {
errors.push("baseUrl が残っています");
}
if (errors.length) {
console.error(errors.join("\\n"));
process.exit(1);
}
この形にしておくと、「誰かが古いテンプレをコピペして戻す」事故をPR段階で止められます。CIは“正しさを証明する場所”より、“戻り事故を止めるゲート”として設計すると運用が軽くなります。
運用メモとして、外部導線ではなく、実測ログ・設定差分・再現手順を同じ場所に残してチーム内で確認できる形にしてください。
stableとcanaryをどう使い分けるか(実務の判断基準)
最後に運用設計です。Next.js 16.2.1 stableはバグ修正中心で、canaryの全変更は入りません。なので「本番はstable固定、検証だけcanary追従」が現実的です。ここを曖昧にすると、毎回の障害対応で方針論争になりがちです。
| レーン | 依存バージョン | 目的 | 昇格条件 |
|---|---|---|---|
| production | Next.js 16.2.1固定 | 安定運用 | 週次CIが連続通過 |
| migration | Next.js canary + TS6系 | 先行検証 | deprecationゼロ・build成功 |
| release-prep | TS 6.0 stable確定版 | 本番反映前最終確認 | 2環境以上で再現確認 |
「とりあえずlatest」は短期では速いですが、複業や小規模チームほど後で重くなります。 逆にこの3レーンを作ると、非エンジニアにも「どこまでが実験か」を説明しやすくなります。
運用メモとして、外部導線ではなく、実測ログ・設定差分・再現手順を同じ場所に残してチーム内で確認できる形にしてください。
この移行を先送りしたチームで起きやすい3つの損失
設定移行を後回しにすると、機能開発よりも“調査の時間”が増える可能性があります。 具体的には、①PRごとに断続的な型警告が出てレビュー速度が落ちる、②環境ごとに解決結果がズレて再現確認に時間がかかる、③担当者しか直せない属人運用になる、の3つです。知らないままだと、半年後に「小さな不整合の総量」がチームの生産性を削る形になりやすいです。
この記事を書いている理由
僕自身、SESから人材教育、そして福祉領域のIT担当へキャリアを移してきました。550名以上のキャリア面談をやってきた経験もあって、技術の正しさだけじゃなく「伝わる運用設計」が本当に大事だと感じています。実務でも、業務効率化ツールで月80時間の工数削減を出したときは、派手な新機能より設定の再現性を整えた効果が大きかったです。だからこそ、今回も“知っている人だけ得する設定差分”を、実装まで落として共有したいと思っています。
次のアクション
運用メモとして、外部導線ではなく、実測ログ・設定差分・再現手順を同じ場所に残してチーム内で確認できる形にしてください。
今日からできるアクション
- 30分で棚卸し —
npx tsc --showConfigでmoduleResolutionとbaseUrlを確認 - 1日で実装 —
pathsを実パスへ書き換え、runtime別tsconfigへ分割 - 翌日から再発防止 — CIに
tsc --noEmitと設定検証スクリプトを追加 - 回遊強化 — 関連記事の Type Strippingガイド も確認して開発基盤をそろえる