ウェブサイト検索

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[]

あまり満足のいく答えではないので、より良い方法を見つけることを期待して、その質問には答えずにおこうと思います。