Quellcode durchsuchen

pnpm setup问题

黄中银 vor 3 Wochen
Ursprung
Commit
111bb3b485

+ 36 - 2
ApqInstaller/electron/modules/installer.ts

@@ -1078,8 +1078,42 @@ export async function installAll(options: InstallOptions, onStatus: StatusCallba
     // 使用完整路径,避免 PATH 未生效的问题
     // 检测是否已安装 pnpm,优先使用 pnpm
     const hasPnpm = await commandExistsWithRefresh('pnpm')
-    const pkgManager = hasPnpm ? getPnpmPath() : getNpmPath()
-    await executeCommand(pkgManager, ['install', '-g', '@anthropic-ai/claude-code'], true)
+
+    if (hasPnpm) {
+      // 使用 pnpm 安装,需要确保 PNPM_HOME 环境变量已设置
+      const { getRefreshedPath } = await import('./utils')
+      const refreshedPath = await getRefreshedPath()
+      const execEnv: Record<string, string> = { ...process.env as Record<string, string>, PATH: refreshedPath }
+
+      // 先执行 pnpm setup
+      try {
+        await execa('pnpm', ['setup'], { env: execEnv, shell: platform === 'win32' })
+        logger.installInfo('pnpm setup 完成')
+      } catch (error) {
+        logger.installWarn('pnpm setup 失败', error)
+      }
+
+      // 手动设置 PNPM_HOME 环境变量
+      if (platform === 'win32') {
+        const localAppData = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local')
+        const pnpmHome = path.join(localAppData, 'pnpm')
+        execEnv.PNPM_HOME = pnpmHome
+        execEnv.PATH = `${pnpmHome};${execEnv.PATH}`
+        logger.installInfo(`设置 PNPM_HOME: ${pnpmHome}`)
+      } else {
+        const pnpmHome = path.join(os.homedir(), '.local', 'share', 'pnpm')
+        execEnv.PNPM_HOME = pnpmHome
+        execEnv.PATH = `${pnpmHome}:${execEnv.PATH}`
+        logger.installInfo(`设置 PNPM_HOME: ${pnpmHome}`)
+      }
+
+      // 使用 pnpm 安装 Claude Code
+      await execa('pnpm', ['install', '-g', '@anthropic-ai/claude-code'], { env: execEnv, shell: platform === 'win32' })
+    } else {
+      // 使用 npm 安装
+      const pkgManager = getNpmPath()
+      await executeCommand(pkgManager, ['install', '-g', '@anthropic-ai/claude-code'], true)
+    }
     currentStep++
   }
 

+ 19 - 2
ApqInstaller/electron/modules/ipc-handlers.ts

@@ -384,17 +384,34 @@ export function registerHandlers(): void {
 
       // 获取刷新后的 PATH,确保能找到新安装的命令
       const refreshedPath = await getRefreshedPath()
-      const execEnv = { ...process.env, PATH: refreshedPath }
+      const execEnv: Record<string, string | undefined> = { ...process.env, PATH: refreshedPath }
 
       // 检测是否已安装 pnpm,优先使用 pnpm
       const hasPnpm = await commandExistsWithRefresh('pnpm')
       const pkgManager = hasPnpm ? 'pnpm' : 'npm'
 
-      // 如果使用 pnpm,确保全局目录已配置(pnpm setup 是幂等的)
+      // 如果使用 pnpm,确保全局目录已配置
       if (hasPnpm) {
         try {
           await execa(pkgManager, ['setup'], { shell: isWindows, env: execEnv })
           logger.installInfo('pnpm setup 完成')
+
+          // pnpm setup 后需要手动设置 PNPM_HOME 环境变量,因为它不会在当前进程中生效
+          // Windows 上 PNPM_HOME 默认是 %LOCALAPPDATA%\pnpm
+          if (isWindows) {
+            const localAppData = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local')
+            const pnpmHome = path.join(localAppData, 'pnpm')
+            execEnv.PNPM_HOME = pnpmHome
+            // 将 PNPM_HOME 添加到 PATH 的开头
+            execEnv.PATH = `${pnpmHome};${execEnv.PATH}`
+            logger.installInfo(`设置 PNPM_HOME: ${pnpmHome}`)
+          } else {
+            // macOS/Linux 上 PNPM_HOME 默认是 $HOME/.local/share/pnpm
+            const pnpmHome = path.join(os.homedir(), '.local', 'share', 'pnpm')
+            execEnv.PNPM_HOME = pnpmHome
+            execEnv.PATH = `${pnpmHome}:${execEnv.PATH}`
+            logger.installInfo(`设置 PNPM_HOME: ${pnpmHome}`)
+          }
         } catch (setupError) {
           // pnpm setup 失败不是致命错误,可能已经配置过了
           logger.installWarn('pnpm setup 失败,尝试继续安装', setupError)