|
|
@@ -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 版本号
|