@@ -4,6 +4,7 @@ import chalk from 'next/dist/compiled/chalk'
44import crypto from 'crypto'
55import { isMatch } from 'next/dist/compiled/micromatch'
66import { promises , writeFileSync } from 'fs'
7+ import { Worker as JestWorker } from 'next/dist/compiled/jest-worker'
78import { Worker } from '../lib/worker'
89import devalue from 'next/dist/compiled/devalue'
910import { escapeStringRegexp } from '../shared/lib/escape-regexp'
@@ -34,7 +35,6 @@ import { nonNullable } from '../lib/non-nullable'
3435import { recursiveDelete } from '../lib/recursive-delete'
3536import { verifyAndLint } from '../lib/verifyAndLint'
3637import { verifyPartytownSetup } from '../lib/verify-partytown-setup'
37- import { verifyTypeScriptSetup } from '../lib/verifyTypeScriptSetup'
3838import {
3939 BUILD_ID_FILE ,
4040 BUILD_MANIFEST ,
@@ -229,30 +229,74 @@ export default async function build(
229229 const ignoreTypeScriptErrors = Boolean (
230230 config . typescript . ignoreBuildErrors
231231 )
232+
233+ const ignoreESLint = Boolean ( config . eslint . ignoreDuringBuilds )
234+ const eslintCacheDir = path . join ( cacheDir , 'eslint/' )
235+ const shouldLint = ! ignoreESLint && runLint
236+
237+ if ( ignoreTypeScriptErrors ) {
238+ Log . info ( 'Skipping validation of types' )
239+ }
240+ if ( runLint && ignoreESLint ) {
241+ // only print log when build requre lint while ignoreESLint is enabled
242+ Log . info ( 'Skipping linting' )
243+ }
244+
245+ let typeCheckingAndLintingSpinnerPrefixText : string | undefined
246+ let typeCheckingAndLintingSpinner :
247+ | ReturnType < typeof createSpinner >
248+ | undefined
249+
250+ if ( ! ignoreTypeScriptErrors && shouldLint ) {
251+ typeCheckingAndLintingSpinnerPrefixText =
252+ 'Linting and checking validity of types'
253+ } else if ( ! ignoreTypeScriptErrors ) {
254+ typeCheckingAndLintingSpinnerPrefixText = 'Checking validity of types'
255+ } else if ( shouldLint ) {
256+ typeCheckingAndLintingSpinnerPrefixText = 'Linting'
257+ }
258+
259+ // we will not create a spinner if both ignoreTypeScriptErrors and ignoreESLint are
260+ // enabled, but we will still verifying project's tsconfig and dependencies.
261+ if ( typeCheckingAndLintingSpinnerPrefixText ) {
262+ typeCheckingAndLintingSpinner = createSpinner ( {
263+ prefixText : `${ Log . prefixes . info } ${ typeCheckingAndLintingSpinnerPrefixText } ` ,
264+ } )
265+ }
266+
232267 const typeCheckStart = process . hrtime ( )
233- const typeCheckingSpinner = createSpinner ( {
234- prefixText : `${ Log . prefixes . info } ${
235- ignoreTypeScriptErrors
236- ? 'Skipping validation of types'
237- : 'Checking validity of types'
238- } `,
239- } )
240268
241- const verifyResult = await nextBuildSpan
242- . traceChild ( 'verify-typescript-setup' )
243- . traceAsyncFn ( ( ) =>
269+ const [ [ verifyResult , typeCheckEnd ] ] = await Promise . all ( [
270+ nextBuildSpan . traceChild ( 'verify-typescript-setup' ) . traceAsyncFn ( ( ) =>
244271 verifyTypeScriptSetup (
245272 dir ,
246273 [ pagesDir , viewsDir ] . filter ( Boolean ) as string [ ] ,
247274 ! ignoreTypeScriptErrors ,
248275 config ,
249- cacheDir
250- )
251- )
276+ cacheDir ,
277+ config . experimental . cpus ,
278+ config . experimental . workerThreads
279+ ) . then ( ( resolved ) => {
280+ const checkEnd = process . hrtime ( typeCheckStart )
281+ return [ resolved , checkEnd ] as const
282+ } )
283+ ) ,
284+ shouldLint &&
285+ nextBuildSpan . traceChild ( 'verify-and-lint' ) . traceAsyncFn ( async ( ) => {
286+ await verifyAndLint (
287+ dir ,
288+ eslintCacheDir ,
289+ config . eslint ?. dirs ,
290+ config . experimental . cpus ,
291+ config . experimental . workerThreads ,
292+ telemetry
293+ )
294+ } ) ,
295+ ] )
252296
253- const typeCheckEnd = process . hrtime ( typeCheckStart )
297+ typeCheckingAndLintingSpinner ?. stopAndPersist ( )
254298
255- if ( ! ignoreTypeScriptErrors ) {
299+ if ( ! ignoreTypeScriptErrors && verifyResult ) {
256300 telemetry . record (
257301 eventTypeCheckCompleted ( {
258302 durationInSeconds : typeCheckEnd [ 0 ] ,
@@ -264,27 +308,6 @@ export default async function build(
264308 )
265309 }
266310
267- if ( typeCheckingSpinner ) {
268- typeCheckingSpinner . stopAndPersist ( )
269- }
270-
271- const ignoreESLint = Boolean ( config . eslint . ignoreDuringBuilds )
272- const eslintCacheDir = path . join ( cacheDir , 'eslint/' )
273- const shouldLint = ! ignoreESLint && runLint
274- if ( shouldLint ) {
275- await nextBuildSpan
276- . traceChild ( 'verify-and-lint' )
277- . traceAsyncFn ( async ( ) => {
278- await verifyAndLint (
279- dir ,
280- eslintCacheDir ,
281- config . eslint ?. dirs ,
282- config . experimental . cpus ,
283- config . experimental . workerThreads ,
284- telemetry
285- )
286- } )
287- }
288311 const buildLintEvent : EventBuildFeatureUsage = {
289312 featureName : 'build-lint' ,
290313 invocationCount : shouldLint ? 1 : 0 ,
@@ -2318,6 +2341,50 @@ export default async function build(
23182341 }
23192342}
23202343
2344+ /**
2345+ * typescript will be loaded in "next/lib/verifyTypeScriptSetup" and
2346+ * then passed to "next/lib/typescript/runTypeCheck" as a parameter.
2347+ *
2348+ * Since it is impossible to pass a function from main thread to a worker,
2349+ * instead of running "next/lib/typescript/runTypeCheck" in a worker,
2350+ * we will run entire "next/lib/verifyTypeScriptSetup" in a worker instead.
2351+ */
2352+ function verifyTypeScriptSetup (
2353+ dir : string ,
2354+ intentDirs : string [ ] ,
2355+ typeCheckPreflight : boolean ,
2356+ config : NextConfigComplete ,
2357+ cacheDir : string | undefined ,
2358+ numWorkers : number | undefined ,
2359+ enableWorkerThreads : boolean | undefined
2360+ ) {
2361+ const typeCheckWorker = new JestWorker (
2362+ require . resolve ( '../lib/verifyTypeScriptSetup' ) ,
2363+ {
2364+ numWorkers,
2365+ enableWorkerThreads,
2366+ }
2367+ ) as JestWorker & {
2368+ verifyTypeScriptSetup : typeof import ( '../lib/verifyTypeScriptSetup' ) . verifyTypeScriptSetup
2369+ }
2370+
2371+ typeCheckWorker . getStdout ( ) . pipe ( process . stdout )
2372+ typeCheckWorker . getStderr ( ) . pipe ( process . stderr )
2373+
2374+ return typeCheckWorker
2375+ . verifyTypeScriptSetup (
2376+ dir ,
2377+ intentDirs ,
2378+ typeCheckPreflight ,
2379+ config ,
2380+ cacheDir
2381+ )
2382+ . then ( ( result ) => {
2383+ typeCheckWorker . end ( )
2384+ return result
2385+ } )
2386+ }
2387+
23212388function generateClientSsgManifest (
23222389 prerenderManifest : PrerenderManifest ,
23232390 {
0 commit comments