@tarojs/cli
Version:
cli tool for taro
180 lines (154 loc) • 5.66 kB
text/typescript
import * as path from 'node:path'
import * as inquirer from 'inquirer'
import * as getLatestVersion from 'latest-version'
import * as ora from 'ora'
import * as semver from 'semver'
import packagesManagement from '../../config/packagesManagement'
import { execCommand, getPkgItemByKey } from '../../util'
import type { IPluginContext } from '@tarojs/service'
export default (ctx: IPluginContext) => {
ctx.registerCommand({
name: 'update',
synopsisList: [
'taro update self [version]',
'taro update project [version]'
],
optionsMap: {
'--npm [npm]': '包管理工具',
'-h, --help': 'output usage information'
},
async fn ({ _, options }) {
const { npm } = options
const [, updateType, version] = _ as [string, ('self' | 'project')?, string?]
const { appPath, configPath } = ctx.paths
const {
chalk,
fs,
PROJECT_CONFIG,
UPDATE_PACKAGE_LIST
} = ctx.helper
const pkgPath = path.join(appPath, 'package.json')
const pkgName = getPkgItemByKey('name')
const conf = {
npm: null
}
const prompts: Record<string, unknown>[] = []
async function getTargetVersion () {
let targetTaroVersion
if (version) {
targetTaroVersion = semver.clean(version)
} else {
try {
targetTaroVersion = await getLatestVersion(pkgName, {
version: 'latest'
})
} catch (e) {
targetTaroVersion = await getLatestVersion(pkgName)
}
}
if (!semver.valid(targetTaroVersion)) {
console.log(chalk.red('命令错误:无效的 version ~'))
throw Error('无效的 version!')
}
return targetTaroVersion
}
function execUpdate (command: string, version: string, isSelf = false) {
const updateTarget = isSelf ? ' CLI ' : ' Taro 项目依赖'
const spinString = `正在更新${updateTarget}到 v${version} ...`
const spinner = ora(spinString).start()
execCommand({
command,
successCallback (data) {
spinner.stop()
console.log(data.replace(/\n$/, ''))
},
failCallback (data) {
spinner.stop()
spinner.warn(data.replace(/\n$/, ''))
}
})
}
/** 更新全局的 Taro CLI */
async function updateSelf () {
const spinner = ora('正在获取最新版本信息...').start()
const targetTaroVersion = await getTargetVersion()
spinner.stop()
console.log(chalk.green(`Taro 最新版本:${targetTaroVersion}\n`))
askNpm(conf, prompts)
const answers = npm ? { npm } : await inquirer.prompt(prompts)
const command = `${packagesManagement[answers.npm].globalCommand}@${targetTaroVersion}`
execUpdate(command, targetTaroVersion, true)
}
/** 更新当前项目中的 Taro 相关依赖 */
async function updateProject () {
if (!configPath || !fs.existsSync(configPath)) {
console.log(chalk.red(`找不到项目配置文件 ${PROJECT_CONFIG},请确定当前目录是 Taro 项目根目录!`))
process.exit(1)
}
const packageMap = require(pkgPath)
const spinner = ora('正在获取最新版本信息...').start()
const version = await getTargetVersion()
spinner.stop()
const oldVersion = packageMap.dependencies['@tarojs/taro']
// 更新 @tarojs/* 版本和 NervJS 版本
Object.keys(packageMap.dependencies || {}).forEach((key) => {
if (UPDATE_PACKAGE_LIST.indexOf(key) !== -1) {
packageMap.dependencies[key] = version
}
})
Object.keys(packageMap.devDependencies || {}).forEach((key) => {
if (UPDATE_PACKAGE_LIST.indexOf(key) !== -1) {
packageMap.devDependencies[key] = version
}
})
// 写入package.json
try {
await fs.writeJson(pkgPath, packageMap, { spaces: '\t' })
console.log(chalk.green(`项目当前 Taro 版本:${oldVersion},Taro 最新版本:${version},更新项目 package.json 成功!`))
console.log()
} catch (err) {
console.error(err)
}
askNpm(conf, prompts)
const answers = npm ? { npm } : await inquirer.prompt(prompts)
const command = packagesManagement[answers.npm].command
execUpdate(command, version)
}
function askNpm (conf, prompts) {
const packages = [
{
name: 'yarn',
value: 'yarn'
},
{
name: 'pnpm',
value: 'pnpm'
},
{
name: 'npm',
value: 'npm'
},
{
name: 'cnpm',
value: 'cnpm'
}
]
if ((typeof conf.npm as string | undefined) !== 'string') {
prompts.push({
type: 'list',
name: 'npm',
message: '请选择包管理工具',
choices: packages
})
}
}
if (updateType === 'self') return updateSelf()
if (updateType === 'project') return updateProject()
console.log(chalk.red('命令错误:'))
console.log(`${chalk.green(
'taro update self [version]')} 更新 Taro 开发工具 taro-cli 到指定版本或 Taro3 的最新版本`)
console.log(`${chalk.green(
'taro update project [version]')} 更新项目所有 Taro 相关依赖到指定版本或 Taro3 的最新版本`)
}
})
}