Skip to content

Commit 8248e68

Browse files
authored
perf: replace execa to nano-spawn (#101)
* fix: module resolution is bundler * feat: replace exca to nano-spawn
1 parent e811937 commit 8248e68

File tree

4 files changed

+27
-22
lines changed

4 files changed

+27
-22
lines changed

bun.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"commander": "^13.1.0",
3838
"eslint": "^9.23.0",
3939
"execa": "^8.0.1",
40+
"nano-spawn": "^1.0.1",
4041
"nanospinner": "^1.2.2",
4142
"np": "^10.2.0",
4243
"picocolors": "^1.1.1",

src/hooks/dependencies.ts

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import confirm from '@inquirer/confirm'
22
import select from '@inquirer/select'
3-
import { execa } from 'execa'
3+
import spawn, { SubprocessError } from 'nano-spawn'
44
import { createSpinner } from 'nanospinner'
55
import * as picocolor from 'picocolors'
6-
import { exec } from 'node:child_process'
76
import type { EventEmitter } from 'node:events'
8-
import { chdir, exit } from 'node:process'
7+
import { exit } from 'node:process'
98
import { projectDependenciesHook } from '../hook'
109

1110
type PackageManager = 'npm' | 'bun' | 'deno' | 'pnpm' | 'yarn'
@@ -57,7 +56,7 @@ const registerInstallationHook = (
5756
if (installedPackageManagerNames.includes('deno')) {
5857
let isVersion1 = false
5958
try {
60-
const { stdout } = await execa('deno', ['-v'])
59+
const { stdout } = await spawn('deno', ['-v'])
6160
isVersion1 = stdout.split(' ')[1].split('.')[0] === '1'
6261
} catch {
6362
isVersion1 = true
@@ -101,29 +100,31 @@ const registerInstallationHook = (
101100
emitter.emit('packageManager', packageManager)
102101

103102
emitter.on('dependencies', async () => {
104-
chdir(directoryPath)
105-
106103
if (!knownPackageManagers[packageManager]) {
107104
exit(1)
108105
}
109106

110107
const spinner = createSpinner('Installing project dependencies').start()
111-
const proc = exec(knownPackageManagers[packageManager])
112108

113-
const procExit: number = await new Promise((res) => {
114-
proc.on('exit', (code) => res(code == null ? 0xff : code))
115-
})
109+
const [command, ...args] = knownPackageManagers[packageManager].split(' ')
116110

117-
if (procExit === 0) {
118-
spinner.success()
119-
} else {
120-
spinner.stop({
121-
mark: picocolor.red('×'),
122-
text: 'Failed to install project dependencies',
111+
try {
112+
await spawn(command, args, {
113+
cwd: directoryPath,
123114
})
124-
exit(procExit)
115+
} catch (error: unknown) {
116+
if (error instanceof SubprocessError) {
117+
spinner.stop({
118+
mark: picocolor.red('×'),
119+
text: 'Failed to install project dependencies',
120+
})
121+
exit(error.exitCode ?? 1)
122+
}
123+
throw error
125124
}
126125

126+
spinner.success()
127+
127128
emitter.emit('completed')
128129
})
129130

@@ -152,7 +153,7 @@ function getCurrentPackageManager(): PackageManager {
152153

153154
function checkPackageManagerInstalled(packageManager: string) {
154155
return new Promise<boolean>((resolve) => {
155-
execa(packageManager, ['--version'])
156+
spawn(packageManager, ['--version'])
156157
.then(() => resolve(true))
157158
.catch(() => resolve(false))
158159
})

tsconfig.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"compilerOptions": {
33
"target": "ESNext",
44
"module": "ESNext",
5-
"moduleResolution": "node",
5+
"moduleResolution": "bundler",
66
"resolveJsonModule": true,
77
"esModuleInterop": true,
88
"strict": true,
@@ -11,6 +11,6 @@
1111
],
1212
"lib": [
1313
"esnext"
14-
],
15-
},
16-
}
14+
]
15+
}
16+
}

0 commit comments

Comments
 (0)