typescript - NextJsアプリケーションで単一のJSONファイルに対してresolveJsonModuleを無効にするにはどうすればよいですか?
私はNext.jsのアプリケーションを構築しており、Vercelでデプロイしています。これまではすべて順調に動作していましたが、最近、大きなJSONファイルにいくつかの変更を加えたところ、そのサイズが約20%増加しました。サイズの増加が何らかの制限を超えたようで、現在、TypeScriptの型解決に起因すると思われるWebpack 5のエラーが発生しています。
私は JSON ファイルを import で直接インポートしています。私が集められた情報によると、tsconfig.json の resolveJsonModule コンパイラオプションが、webpack に対して JSON ファイルの型をその場で解決しようと指示する役割を果たしているようです。そのため、おそらく JSON ファイルを正しく操作しているかを確認できるのでしょう。
実際のところ、このファイルはかなり簡単なものです。以下のような、比較的シンプルな FoodItem オブジェクトの配列に過ぎません(以下は例示です):
import allFoodOriginal from '../data/all-food-data.json'
interface FoodData {
Calories: string,
Kilojoules: string
}
interface FoodItem {
id: number,
name: string,
folders: string[],
slug: string,
image?: string,
data?: FoodData
}
const allFood = allFoodOriginal as FoodItem[]
JSONファイル自体は約140万行あり、アイテム数は約82021です。どうやらこれは大きすぎるようで、vercelでデプロイ中にコンパイルすると以下のログでエラーが発生します。
14:39:23.522 Installing dependencies...
14:39:28.885 npm WARN @babel/[email requires a peer of @babel/core@^7.0.0-0 but none is installed. You must install peer dependencies yourself.
14:39:28.896 npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @next/[email (node_modules/@next/swc-darwin-arm64):
14:39:28.896 npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @next/[email : wanted {"os":"darwin","arch":"arm64"} (current: {"os":"linux","arch":"x64"})
14:39:28.907 npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @next/[email (node_modules/@next/swc-win32-x64-msvc):
14:39:28.908 npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @next/[email : wanted {"os":"win32","arch":"x64"} (current: {"os":"linux","arch":"x64"})
14:39:28.922 npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email (node_modules/fsevents):
14:39:28.922 npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email : wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
14:39:28.933 npm WARN optional SKIPPING OPTIONAL DEPENDENCY: @next/[email (node_modules/@next/swc-darwin-x64):
14:39:28.933 npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for @next/[email : wanted {"os":"darwin","arch":"x64"} (current: {"os":"linux","arch":"x64"})
14:39:28.934
14:39:28.935 updated 1 package in 4.846s
14:39:29.060
14:39:29.060 50 packages are looking for funding
14:39:29.060 run `npm fund` for details
14:39:29.061
14:39:29.847 Detected Next.js version: 11.1.2
14:39:29.850 Running "npm run build"
14:39:30.131
14:39:30.131 > [email build /vercel/path0
14:39:30.131 > next build
14:39:30.132
14:39:30.868 info - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
14:39:31.072 info - Checking validity of types...
14:45:11.987
14:45:11.989 > Build error occurred
14:45:12.003 RangeError: Value undefined out of range for undefined options property undefined
14:45:12.004 at Map.set (<anonymous>)
14:45:12.004 at recursiveTypeRelatedTo (/vercel/path0/node_modules/typescript/lib/typescript.js:62613:30)
14:45:12.004 at isRelatedTo (/vercel/path0/node_modules/typescript/lib/typescript.js:62112:34)
14:45:12.004 at checkTypeRelatedTo (/vercel/path0/node_modules/typescript/lib/typescript.js:61742:26)
14:45:12.004 at isTypeRelatedTo (/vercel/path0/node_modules/typescript/lib/typescript.js:61694:24)
14:45:12.005 at removeSubtypes (/vercel/path0/node_modules/typescript/lib/typescript.js:58445:33)
14:45:12.005 at getUnionType (/vercel/path0/node_modules/typescript/lib/typescript.js:58547:31)
14:45:12.005 at checkArrayLiteral (/vercel/path0/node_modules/typescript/lib/typescript.js:70038:17)
14:45:12.005 at checkExpressionWorker (/vercel/path0/node_modules/typescript/lib/typescript.js:76283:28)
14:45:12.005 at checkExpression (/vercel/path0/node_modules/typescript/lib/typescript.js:76204:38)
14:45:12.146 npm ERR! code ELIFECYCLE
14:45:12.146 npm ERR! errno 1
14:45:12.150 npm ERR! [email build: `next build`
14:45:12.150 npm ERR! Exit status 1
14:45:12.151 npm ERR!
14:45:12.151 npm ERR! Failed at the [email build script.
14:45:12.151 npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
14:45:12.157
14:45:12.157 npm ERR! A complete log of this run can be found in:
14:45:12.158 npm ERR! /vercel/.npm/_logs/2021-10-26T13_45_12_151Z-debug.log
14:45:12.174 Error: Command "npm run build" exited with 1
ローカルで npm run build を実行すると、単純に Javascript のヒープメモリエラーが発生します。
JSONファイルの型チェックを気にせずに済むのは嬉しいですが、NextJsアプリケーション内から型チェックを無効にする方法がわかりません。
もし resolveJsonModule を false に設定すると、ビルドプロセスによって自動的に true に戻されます。そのビルドプロセスは自分のほうがよくわかっていると主張しています。
このJSONファイルだけの型チェックを無効にするオプションはありますか?
更新
この特定の型チェックエラーは、fsモジュールを使ってJSONファイルを読み込むことで、どうやら回避することが可能です:
import fs from 'fs'
import path from 'path'
const allFood = JSON.parse(fs.readFileSync(path.join(process.cwd(), '/data/all-food-data.json'), 'utf-8')) as FoodItem[]
しかし、これにより別のエラーが発生しました。ページがリクエスト時に動的に生成されなくなり、その代わりに404エラーが表示されました。fs.readFileSync() の呼び出しを getStaticProps 関数内に入れると、今度は500エラーが発生しました。これらのエラーは vercel のデプロイメント上でのみ発生し、ローカル版は問題なく動作しました。
これらの問題を解決する方法があるかもしれませんが、私は別の回避策を使うことになりました:
回避策
JSONファイルを単に2つの小さなファイルに分割し、実行時にそれらを結合することで問題が解決しました。
import allFood1 from '../data/all-food-data.json'
import allFood2 from '../data/all-food-data-2.json'
const allFood = [...(allFood1 as FoodItem[]), ...(allFood2 as FoodItem[])] as FoodItem[]
あまり満足のいく答えではないので、より良い方法を見つけることを期待して、その質問には答えずにおこうと思います。