Skip to content

Commit 07d86a3

Browse files
committed
fix(typecheck): avoid unnecessary preparation
1 parent 6ff5c36 commit 07d86a3

2 files changed

Lines changed: 65 additions & 26 deletions

File tree

‎packages/nuxt-cli/src/commands/typecheck.ts‎

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const TYPE_CHECKERS: Record<TypeChecker, TypeCheckerBackend> = {
8686
configFiles: GOLAR_CONFIG_FILES,
8787
configNote: `Golar also requires a ${styleText('cyan','golar.config.ts')} file. One will be created automatically the first time Golar is used.`,
8888
resolve(cwd,{ cache =true}={}){
89-
constbin=resolveGolarBin(cwd)
89+
constbin=resolveGolarBin(cwd,cache)
9090
constvuePlugin=resolveModulePath('@golar/vue',{from: withNodePath(cwd),try: true, cache })
9191
return{
9292
bin,
@@ -135,20 +135,20 @@ export default defineCommand({
135135
return
136136
}
137137

138-
const[tsConfig,typechecker]=awaitPromise.all([
138+
consttypechecker=awaitresolveTypeChecker(cwd,checkerArgasTypeChecker|undefined)
139+
if(!typechecker){
140+
process.exitCode=1
141+
return
142+
}
143+
144+
const[tsConfig]=awaitPromise.all([
139145
readTSConfig(cwd).catch(()=>({}asTSConfig)),
140-
resolveTypeChecker(cwd,checkerArgasTypeChecker|undefined),
141146
writeTypes(cwd,ctx.args.dotenv,ctx.args.logLevelas'silent'|'info'|'verbose',{
142147
...ctx.data?.overrides,
143148
...(ctx.args.extends&&{extends: ctx.args.extends}),
144149
}),
145150
])
146151

147-
if(!typechecker){
148-
process.exitCode=1
149-
return
150-
}
151-
152152
constuseProjectReferences=ctx.args.build??supportsProjectReferences(tsConfig)
153153

154154
if(ctx.args.build===undefined&&!useProjectReferences&&hasNuxtProjectReferences(tsConfig)){
@@ -217,8 +217,8 @@ function hasCheckerConfig(checker: TypeChecker, cwd: string) {
217217
returnTYPE_CHECKERS[checker].configFiles?.some(file=>existsSync(resolve(cwd,file)))??false
218218
}
219219

220-
functionresolveGolarBin(cwd: string): string|undefined{
221-
constentry=resolveModulePath('golar/unstable',{from: withNodePath(cwd),try: true})
220+
functionresolveGolarBin(cwd: string,cache=true): string|undefined{
221+
constentry=resolveModulePath('golar/unstable',{from: withNodePath(cwd),try: true, cache})
222222
if(!entry){
223223
returnundefined
224224
}
@@ -301,8 +301,8 @@ async function promptTypeCheckerInstall(cwd: string, preferred?: TypeChecker): P
301301
}
302302

303303
constresolved=TYPE_CHECKERS[selected].resolve(cwd,{cache: false})
304-
if(!resolved.bin){
305-
logger.error(`Failed to resolve ${styleText('cyan',selected)} after installation. Please check your installation.`)
304+
if(!resolved.bin||resolved.missing.length>0){
305+
logger.error(`Failed to resolve ${styleText('cyan',resolved.missing.join(' and ')||selected)} after installation. Please check your installation.`)
306306
return
307307
}
308308

@@ -378,7 +378,11 @@ async function writeTypes(cwd: string, dotenv?: string, logLevel?: 'silent' | 'i
378378
},
379379
})
380380

381-
awaitwriteTypes(nuxt)
382-
awaitbuildNuxt(nuxt)
383-
awaitnuxt.close()
381+
try{
382+
awaitwriteTypes(nuxt)
383+
awaitbuildNuxt(nuxt)
384+
}
385+
finally{
386+
awaitnuxt.close()
387+
}
384388
}

‎packages/nuxt-cli/test/unit/commands/typecheck.spec.ts‎

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,27 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
55
import{runCommand}from'../../../src/run'
66
import{logger}from'../../../src/utils/logger'
77

8-
const{ x, loadKit }=vi.hoisted(()=>({
9-
x: vi.fn((_bin: string,_args: string[])=>Promise.resolve({exitCode: 0})),
10-
loadKit: vi.fn(()=>Promise.resolve({
11-
loadNuxt: ()=>Promise.resolve({close: ()=>Promise.resolve()}),
12-
buildNuxt: ()=>Promise.resolve(),
13-
writeTypes: ()=>Promise.resolve(),
14-
})),
15-
}))
8+
const{ buildNuxt, closeNuxt, loadKit, resolveModulePath, writeTypes, x }=vi.hoisted(()=>{
9+
constbuildNuxt=vi.fn(()=>Promise.resolve())
10+
constcloseNuxt=vi.fn(()=>Promise.resolve())
11+
constwriteTypes=vi.fn(()=>Promise.resolve())
12+
return{
13+
buildNuxt,
14+
closeNuxt,
15+
writeTypes,
16+
x: vi.fn((_bin: string,_args: string[])=>Promise.resolve({exitCode: 0})),
17+
loadKit: vi.fn(()=>Promise.resolve({
18+
loadNuxt: ()=>Promise.resolve({close: closeNuxt}),
19+
buildNuxt,
20+
writeTypes,
21+
})),
22+
resolveModulePath: vi.fn((id: string): string|undefined=>id.includes('vue-tsc') ? '/node_modules/vue-tsc/bin/vue-tsc.js' : '/node_modules/typescript/index.js'),
23+
}
24+
})
1625

1726
vi.mock('tinyexec',()=>({ x }))
1827
vi.mock('../../../src/utils/kit',()=>({ loadKit }))
19-
vi.mock('exsolve',()=>({
20-
resolveModulePath: (id: string)=>id.includes('vue-tsc') ? '/node_modules/vue-tsc/bin/vue-tsc.js' : '/node_modules/typescript/index.js',
21-
}))
28+
vi.mock('exsolve',()=>({ resolveModulePath }))
2229

2330
functionfixture(name: string){
2431
returnfileURLToPath(newURL(`../../fixtures/typecheck/${name}`,import.meta.url))
@@ -32,6 +39,9 @@ async function run(cwd: string, ...args: string[]) {
3239
describe('nuxt typecheck command',()=>{
3340
beforeEach(()=>{
3441
vi.clearAllMocks()
42+
process.exitCode=undefined
43+
resolveModulePath.mockImplementation((id: string)=>id.includes('vue-tsc') ? '/node_modules/vue-tsc/bin/vue-tsc.js' : '/node_modules/typescript/index.js')
44+
x.mockResolvedValue({exitCode: 0})
3545
})
3646

3747
it('should use build mode for Nuxt project references',async()=>{
@@ -56,4 +66,29 @@ describe('nuxt typecheck command', () => {
5666
expect(warn).toHaveBeenCalledWith(expect.stringContaining('"files": []'))
5767
warn.mockRestore()
5868
})
69+
70+
it('should not prepare Nuxt when the requested checker is unavailable',async()=>{
71+
resolveModulePath.mockReturnValue(undefined)
72+
73+
awaitrun(fixture('nuxt-references'),'--checker','vue-tsc')
74+
75+
expect(process.exitCode).toBe(1)
76+
expect(loadKit).not.toHaveBeenCalled()
77+
})
78+
79+
it('should close Nuxt when preparing types fails',async()=>{
80+
writeTypes.mockRejectedValueOnce(newError('could not write types'))
81+
82+
awaitexpect(run(fixture('nuxt-references'))).rejects.toThrow('could not write types')
83+
expect(buildNuxt).not.toHaveBeenCalled()
84+
expect(closeNuxt).toHaveBeenCalledOnce()
85+
})
86+
87+
it('should propagate the checker exit code',async()=>{
88+
x.mockResolvedValueOnce({exitCode: 2})
89+
90+
awaitrun(fixture('nuxt-references'))
91+
92+
expect(process.exitCode).toBe(2)
93+
})
5994
})

0 commit comments

Comments
 (0)