@@ -311,15 +311,54 @@ async function init() {
311311
312312 // Render tsconfigs
313313 render ( 'tsconfig/base' )
314+
315+ // The content of the root `tsconfig.json` is a bit complicated,
316+ // So here we are programmatically generating it.
317+ const rootTsConfig = {
318+ // It doesn't target any specific files because they are all configured in the referenced ones.
319+ files : [ ] ,
320+ // All templates contain at least a `.node` and a `.app` tsconfig.
321+ references : [
322+ {
323+ path : './tsconfig.node.json'
324+ } ,
325+ {
326+ path : './tsconfig.app.json'
327+ }
328+ ]
329+ }
330+
314331 if ( needsCypress ) {
315332 render ( 'tsconfig/cypress' )
333+ // Cypress uses `ts-node` internally, which doesn't support solution-style tsconfig.
334+ // So we have to set a dummy `compilerOptions` in the root tsconfig to make it work.
335+ // I use `NodeNext` here instead of `ES2015` because that's what the actual environment is.
336+ // (Cypress uses the ts-node/esm loader when `type: module` is specified in package.json.)
337+ // @ts -ignore
338+ rootTsConfig . compilerOptions = {
339+ module : 'NodeNext'
340+ }
316341 }
317342 if ( needsCypressCT ) {
318343 render ( 'tsconfig/cypress-ct' )
344+ // Cypress Component Testing needs a standalone tsconfig.
345+ rootTsConfig . references . push ( {
346+ path : './tsconfig.cypress-ct.json'
347+ } )
319348 }
320349 if ( needsVitest ) {
321350 render ( 'tsconfig/vitest' )
351+ // Vitest needs a standalone tsconfig.
352+ rootTsConfig . references . push ( {
353+ path : './tsconfig.vitest.json'
354+ } )
322355 }
356+
357+ fs . writeFileSync (
358+ path . resolve ( root , 'tsconfig.json' ) ,
359+ JSON . stringify ( rootTsConfig , null , 2 ) + '\n' ,
360+ 'utf-8'
361+ )
323362 }
324363
325364 // Render ESLint config
0 commit comments