typescript - Hur inaktiverar jag resolveJsonModule för en enda JSON-fil i en NextJs-applikation?


Jag bygger en Next.js-applikation och distribuerar med Vercel. Allt har fungerat bra, tills jag nyligen gjorde några ändringar i en stor JSON-fil som ytterligare ökade dess storlek med cirka 20%. Ökningen i storlek verkar ha brutit någon sorts gräns, och jag får nu webpack 5-fel, vilket verkar bero på TypeScript-typlösning.

Jag importerar JSON-filen direkt med en import. Från vad jag har kunnat samla in verkar det som att resolveJsonModule-kompilatoralternativet i tsconfig.json är ansvarigt för att tala om för webpack att försöka lösa typerna för JSON-filerna direkt, så att det förmodligen kan kontrollera att jag gör vettiga saker med JSON-filen.

Det är faktiskt en ganska enkel fil - det är bara en array av ganska enkla FoodItem-objekt enligt följande (illustrativt exempel nedan):

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-filen själv är omkring 1,4 miljoner rader lång, vilket är ungefär 82021 objekt. Det verkar som om detta är för stort, eftersom det ger felet i loggarna nedan när den kompileras i Vercel-distributionen.

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

När jag kör npm run build lokalt får jag helt enkelt ett Javascript heap out of memory-fel.

Jag är glad över att slippa bry mig om typkontroll av JSON-filen, men jag vet inte hur man inaktiverar typkontrollen från min NextJs-applikation.

Om jag sätter resolveJsonModule till false, sätts det automatiskt tillbaka till true av byggprocessen som påstår sig veta bättre.

Finns det några alternativ för att inaktivera typkontrollen endast för denna JSON-fil?

Uppdatering

Det är tydligen möjligt att övervinna detta specifika typkontrollfel genom att ladda JSON-filen med fs-modulen:

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

Men detta introducerade ett annat fel, där sidor inte längre skulle genereras dynamiskt vid förfrågan, och istället fick jag ett 404-fel. Om jag placerade fs.readFileSync()-anropet inuti getStaticProps-funktionen, då fick jag ett 500-fel. Dessa fel uppstod endast vid vercel-distributionen, och den lokala versionen fungerade fortfarande bra.

Det kan finnas ett sätt att lösa dessa problem, men jag slutade med en annan lösning:

Arbetsrunda

Att helt enkelt dela JSON-filen i två mindre filer och slå ihop dem vid körning löste problemet.

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

Inte riktigt ett särskilt tillfredsställande svar ändå, så jag kommer att låta frågan vara obesvarad i hopp om att hitta ett bättre sätt att övervinna den.