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.