Next.js16.2とTypeScript 6移行でbaseUrl/es5撤去

Next.js 16.2へ上げたら、TypeScript 6の警告で急にCIが赤くなる。これ、最近かなり増えています。特にbaseUrltarget: "es5"を長く使っているプロジェクトほど、今は動いていても将来詰まりやすいです。この記事では、設定監査から安全撤去、CIでの再発防止までを実務寄りにまとめます。読んだあとに「まず何を触ればいいか」が明確になるように、コードと運用テンプレまで落とし込みます。

こんな方におすすめ

  • Next.js 16.2とTypeScript 6への移行で警告が増えて困っている方
  • tsconfigが継承だらけで、どこを直せばいいか迷っている方
  • 本番を止めずに段階的に移行したい方
  • CIで設定回帰を確実に検知したい方

この記事でわかること

  • baseUrl/target: "es5"/moduleResolution: "node"の移行優先順位
  • paths再定義と*フォールバックの使い分け
  • Next.js 16.2でのtsconfigPath分離テンプレ
  • lint・typecheck・build分離で回帰を止めるCI設計
僕は福祉事業のIT全般を担当しながら、AI×SaaSの開発を複業で続けています。現場では「非エンジニアのチームでも運用できるか」を最優先に、設定変更の事故を起こさない移行設計を日常的にやっています。

なぜ今やるべきか|Next.js 16.2 TypeScript 6移行の全体像

まず前提です。TypeScript 6.0は2026年3月23日に公開され、target: "es5"baseUrlmoduleResolution: "node"が非推奨になりました。さらにignoreDeprecations: "6.0"は一時しのぎで、TS7で非推奨オプションが削除予定と明記されています。今は警告でも、次はエラーになる可能性が高いということです。

Next.js側はかなり速く対応していて、PR #91847と#91855(どちらも2026年3月24日マージ)でTS6向けの回避が入り、2026年4月1日公開の16.2.2にバックポート済みです。ただし、ここで誤解しやすいのが「Next.jsを上げたから終わり」と思ってしまう点です。実際は各プロジェクトのtsconfig、とくにextendsで繋がった設定まで整理しないと再発します。

論点 TS6での扱い 推奨対応 放置時のリスク
baseUrl 非推奨 paths./src/...で明示 TS7で解決不能になる可能性
target: "es5" 非推奨 ES2015以上へ引き上げ ビルド/型チェックの将来互換が崩れる
moduleResolution: "node" 非推奨 bundlerまたはnodenextへ移行 解決ルール差で本番のみ不具合

一次情報はTypeScript 6.0リリースノートNext.js v16.2.2PR #91847を先に読むのがおすすめです。イメージとしては、建物全体の配線は直ったけど、各部屋の延長コードが古いまま残っている状態です。部屋側まで直して、初めて安全になります。

まず監査する項目|baseUrl・es5・moduleResolution・extends連鎖

移行で最初にやるべきことは「修正」ではなく「棚卸し」です。理由はシンプルで、tsconfigは単体より継承連鎖で事故るからです。僕の現場でも、親設定は直っているのに子設定でbaseUrlが残り、週明けのCIだけ落ちるパターンがありました。最初の15分で全件を見える化すると、後半がかなり楽になります。

最初の15分でやる監査チェック

  1. tsconfigを列挙して、対象ファイルを固定します。
  2. 非推奨キーを検索して、どこで使っているかを一覧化します。
  3. extendsの親子関係を図にすることで、見落としを防ぎます。
  4. CI実行経路を確認して、どの設定が本番ビルドに使われるか確定します。
# 1) tsconfig候補を把握
rg --files | rg 'tsconfig.*\.json$'

# 2) 非推奨候補を検索
rg -n '"baseUrl"|"target"\s*:\s*"es5"|"moduleResolution"\s*:\s*"node"' --glob '**/tsconfig*.json'

# 3) 継承連鎖を確認
rg -n '"extends"' --glob '**/tsconfig*.json'

監査でよくある見落とし

  • 継承元だけ修正して継承先の上書きが残る
  • アプリ用だけ修正してテスト用tsconfigが古いまま
  • ローカルは通るのにCIのNODE_ENVで別設定が選ばれる

監査テンプレは、実案件で使うチェックシートとして先に固定しておくと、チーム内の判断がかなり揃いやすくなります。

tsconfig baseUrl 廃止の安全撤去手順|paths再定義の実務

baseUrl撤去は、置換ミスが起きやすいポイントです。TypeScript 6の方針は明快で、baseUrlを消してpathsに明示プレフィックスを書く流れです。Next.jsのPR #91847/#91855でも同じ方向で、extends経由のケースまで面倒を見ています。なのでプロジェクト側でも同じ設計に寄せるとズレにくいです。

// Before
{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "@app/*": ["app/*"],
      "@lib/*": ["lib/*"]
    }
  }
}
// After (TS6推奨)
{
  "compilerOptions": {
    "paths": {
      "@app/*": ["./src/app/*"],
      "@lib/*": ["./src/lib/*"],
      "*": ["./src/*"]
    }
  }
}

ポイントは"*"フォールバックです。これは便利ですが、何でも解決できるぶん依存の境界が曖昧になります。僕は次の基準で使い分けています。

  • 短期移行フェーズでは"*"を一時採用して停止リスクを下げます。
  • 安定後@app/*などの明示エイリアス中心に寄せます。
  • 共通ライブラリはワイルドカードを外して依存方向を固定します。

「まず止めない、そのあと締める」が安全です。なお、2026年3月31日更新のNext.js InstallationにはbaseUrl例が残っているので、そのままコピーしないように注意してください。移行判断で迷う場合は、実際のtsconfigを見ながら影響範囲を先に詰めるのが早いです。

target es5 deprecated 対応|ES2015+移行とランタイム戦略

target: "es5"を外すと、古い環境対応が心配になりますよね。ここは「対応ブラウザ」と「実行環境」を先に分けるのがコツです。TypeScriptの役割は型と変換で、実ブラウザ差分はバンドラやポリフィル設計で吸収する、という分担にすると迷いません。つまり、変換設定を現代化して、必要な互換だけ後段で補うイメージです。

{
  "compilerOptions": {
    "target": "ES2019",
    "lib": ["ES2021", "DOM", "DOM.Iterable"]
  }
}

移行時の確認はこの3点を固定すると失敗しにくいです。

  • 実行環境の下限を明文化する(Node/Lambda/ブラウザ)。
  • ポリフィル対象を機能単位で決める(Promise.anyなど)。
  • E2Eで主要画面を1本ずつ通して体感差を確認する。

性能面は過度に心配しなくて大丈夫です。PR #91847のベンチでも「No significant changes detected」で、例としてCold First Requestは918ms→921ms、Fresh Buildは4.296s→4.386sでした。互換より保守性を優先するほうが、長期では得しやすいです。

Next.js 16.2 TypeScript 6移行テンプレ|tsconfigPath分離で事故を減らす

次に運用テンプレです。Next.jsはtypescript.tsconfigPathでビルド時の設定を切り替えできます。移行期は「開発体験」と「本番安定」を分けるのが実務向きです。僕のモノレポ運用でも、ここを分けてから「ローカルOKなのにデプロイ失敗」がかなり減りました。

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  typescript: {
    tsconfigPath:
      process.env.NODE_ENV === "production"
        ? "tsconfig.build.json"
        : "tsconfig.json",
  },
};

export default nextConfig;
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "noEmit": true,
    "skipLibCheck": true
  },
  "exclude": ["**/*.spec.ts", "**/*.test.ts"]
}
移行序盤は「理想の厳格設定」を一気に求めないほうが安全です。まずは本番ルートを安定させて、次に厳格化を戻す順番が、現場ではいちばん再現性が高いです。

段階移行の目的は“きれいにする”より“止めない”です。福祉領域のように利用者対応が止められないシステムほど、この順番が効きます。設計レビューを先に入れる場合は、条件整理から進めると手戻りが減ります。

CIで回帰を止める|lint/typecheck/build分離と再実行上限50対策

ここが最後の山です。Next.js 16ではnext buildがlintを自動実行しません。なのでCIでlintを明示ジョブにしないと、静的品質の回帰を取りこぼします。さらに2026年4月10日以降、GitHub Actionsは同一workflowの再実行が50回上限です。再実行前提の運用はもう持ちません。

name: ci
on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npm run lint

  typecheck:
    runs-on: ubuntu-latest
    needs: lint
    strategy:
      fail-fast: true
      matrix:
        package: [web, admin]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci
      - run: npm run -w ${{ matrix.package }} typecheck

  test:
    runs-on: ubuntu-latest
    needs: typecheck
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test -- --runInBand

  build:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build

加えて、DBサービスコンテナを使うならentrypoint/commandで初期化手順を固定して、環境差分による“再現しない赤”を潰します。fail-fastを有効にして早く落とす設計にすると、50回上限に近づく前に原因特定しやすいです。参考はWorkflow syntax再実行上限の変更告知です。

設定負債を放置したまま1年過ごすと

baseUrles5の警告を「今は動くから」で置いておくと、次のメジャー更新で一気に詰まる可能性があります。特に採用強化や新規開発が重なる時期に止まると、開発速度だけでなく採用候補への印象にも影響します。知らないままだと、トラブルが“ある日まとめて”来るのが設定負債の怖さです。小さく直せる今のうちに、監査とCIの土台だけ先に作っておくのがおすすめです。

この記事を書いている理由

僕自身、福祉事業のIT全般を担当しながら、Node.js + TypeScriptのモノレポを日常運用しています。現場は「理想的な設定」より「今日も止まらない運用」が最優先です。過去には短期リリースしたWebサービスで、90日以上のログイン継続率を維持するために、派手な機能追加より設定の安定化を優先してきました。ITを非IT領域へ持ち込む“異世界転生”を本気でやるなら、まず壊れない土台づくりが必要だと、実体験で強く感じたからこそこのテーマを書いています。

次のアクション

ここまで読んだら、今日はまず監査だけでも進めてみてください。小さく着手すると、移行は想像よりスムーズに進みます。

今日からできるアクション

  • 15分監査tsconfig全件を洗い出して非推奨キーを一覧化する
  • 分離実装tsconfigPathで開発用とビルド用を分ける
  • 相談して最短化 — 実案件で迷う場合は、設定差分とCIログを見ながら壁打ちする