黄中银 2 тижнів тому
батько
коміт
ca99a4a12d

+ 70 - 0
ApqInstaller/electron/modules/installer.ts

@@ -643,6 +643,76 @@ export async function installNodejs(
   onStatus('nodejs', STATUS_MESSAGES.COMPLETE, 100)
 }
 
+/**
+ * 单独安装 pnpm (需要 Node.js 已安装)
+ * @param onStatus 状态回调
+ */
+export async function installPnpm(onStatus: StatusCallback): Promise<void> {
+  resetCancelState()
+
+  const platform = os.platform() as Platform
+
+  // 检查 Node.js 是否已安装
+  const nodeInstalled = await checkInstalled('nodejs')
+  if (!nodeInstalled.installed) {
+    throw new Error('请先安装 Node.js')
+  }
+
+  onStatus('pnpm', '正在安装 pnpm...', 20)
+
+  // 刷新系统环境变量,确保能找到刚安装的 Node.js
+  const { getRefreshedPath } = await import('./utils')
+  const refreshedPath = await getRefreshedPath()
+
+  // 使用完整路径,避免 PATH 未生效的问题
+  const npmCmd = getNpmPath()
+
+  // 检查 npm 命令是否存在
+  if (platform === 'win32' && !fs.existsSync(npmCmd)) {
+    throw new Error(`未找到 npm 命令: ${npmCmd},请确保 Node.js 已正确安装`)
+  }
+
+  checkCancelled()
+
+  // 安装 pnpm,使用刷新后的 PATH
+  onStatus('pnpm', `${STATUS_MESSAGES.INSTALLING} pnpm...`, 40)
+  const installEnv = { ...process.env, PATH: refreshedPath }
+  await execa(npmCmd, ['install', '-g', 'pnpm'], { env: installEnv, shell: platform === 'win32' })
+
+  checkCancelled()
+
+  // 重新刷新 PATH,确保能找到刚安装的 pnpm
+  const pnpmRefreshedPath = await getRefreshedPath()
+
+  // 使用 pnpm 的完整路径,因为刚安装的 pnpm 可能还不在 PATH 中
+  const pnpmCmd = getPnpmPath()
+
+  // 构建环境变量,将 pnpm 所在目录添加到 PATH 开头
+  const pnpmDir = path.dirname(pnpmCmd)
+  const execEnv = { ...process.env, PATH: `${pnpmDir}${platform === 'win32' ? ';' : ':'}${pnpmRefreshedPath}` }
+
+  // 运行 pnpm setup 配置全局 bin 目录
+  onStatus('pnpm', `${STATUS_MESSAGES.CONFIGURING} pnpm 全局目录...`, 60)
+  try {
+    await execa(pnpmCmd, ['setup'], { env: execEnv, shell: platform === 'win32' })
+    logger.installInfo('pnpm setup 完成')
+  } catch (error) {
+    logger.installWarn('pnpm setup 失败', error)
+  }
+
+  checkCancelled()
+
+  // 配置 pnpm 镜像
+  onStatus('pnpm', `${STATUS_MESSAGES.CONFIGURING} pnpm 镜像...`, 80)
+  try {
+    await execa(pnpmCmd, ['config', 'set', 'registry', NPM_REGISTRY], { env: execEnv, shell: platform === 'win32' })
+  } catch (error) {
+    logger.installWarn('配置 pnpm 镜像失败', error)
+  }
+
+  onStatus('pnpm', STATUS_MESSAGES.COMPLETE, 100)
+}
+
 /**
  * 安装 VS Code (Windows 使用下载安装包)
  * @param version 版本号

+ 10 - 0
ApqInstaller/electron/modules/ipc-handlers.ts

@@ -16,6 +16,7 @@ import {
   cancelInstall,
   aptUpdate,
   installNodejs,
+  installPnpm,
   installVscode,
   installGit,
   installAll,
@@ -851,6 +852,15 @@ export function registerHandlers(): void {
           })
           break
 
+        case 'pnpm':
+          await installPnpm(onStatus)
+          sendToRenderer('install-complete', {
+            software: 'pnpm',
+            message: '✅ pnpm 安装完成!',
+            i18nKey: 'log.pnpmComplete'
+          })
+          break
+
         case 'all': {
           const installed = await installAll(options, onStatus)
           sendToRenderer('install-complete', {