typescript - Hvordan deaktiverer jeg resolveJsonModule for en enkelt JSON-fil i en NextJs-applikasjon?


Jeg bygger en Next.js-applikasjon, og distribuerer med Vercel. Alt har fungert fint, helt til jeg nylig gjorde noen endringer i en stor JSON-fil som økte størrelsen med omtrent 20 %. Økningen i størrelse ser ut til å ha brutt en slags grense, og jeg får nå Webpack 5-feil, som ser ut til å skyldes TypeScript-typeoppløsning.

Jeg importerer JSON-filen direkte med en import. Fra det jeg har klart å samle inn, ser det ut til at resolveJsonModule compilerOption i tsconfig.json er ansvarlig for å fortelle webpack å forsøke å løse typene til JSON-filene på farten, slik at det antagelig kan sjekke at jeg gjør fornuftige ting med JSON-filen.

Det er faktisk en ganske enkel fil - det er bare et array av ganske enkle FoodItem-objekter som følger (illustrativt eksempel nedenfor):

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 i seg selv er omtrent 1,4 millioner linjer lang, som er rundt 82021 elementer. Det ser ut til at dette rett og slett er for stort, da det kaster feilen i loggene nedenfor når den kompilere i Vercel-distribusjonen.

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 jeg kjører npm run build lokalt, får jeg rett og slett en Javascript heap out of memory-feil.

Jeg er glad for å ikke måtte bry meg om typetesting av JSON-filen, men jeg vet ikke hvordan jeg skal deaktivere typetesting fra innenfor min NextJs-applikasjon.

Hvis jeg setter resolveJsonModule til false, settes det automatisk tilbake til true av byggeprosessen som hevder å vite bedre.

Finnes det noen alternativer for å deaktivere typekontrollen for denne JSON-filen alene?

Oppdatering

Det ser ut til å være mulig å overvinne denne spesifikke typetjekkfeilen ved å laste 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[]

Dette introduserte imidlertid en annen feil, der sider ikke lenger ble generert dynamisk ved forespørsel, og i stedet fikk jeg en 404-feil. Hvis jeg satte fs.readFileSync()-kallet inne i getStaticProps-funksjonen, fikk jeg en 500-feil. Disse feilene oppsto kun på Vercel-distribusjonen, og den lokale versjonen fungerte fortsatt fint.

Det kan finnes en måte å løse disse problemene på, men jeg endte opp med en annen løsning:

Omvei

Å bare dele JSON-filen i to mindre filer og slå dem sammen under kjøring 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[]

Ikke egentlig et spesielt tilfredsstillende svar, så jeg lar spørsmålet stå ubesvart i håp om å finne en bedre måte å overvinne det på.