@tarojs/cli
Version:
cli tool for taro
141 lines (132 loc) • 5.4 kB
text/typescript
import * as path from 'node:path'
import * as ora from 'ora'
import * as validatePkgName from 'validate-npm-package-name'
import { execCommand, getPkgNameByFilterVersion, getRootPath } from '../../util'
import type { IPluginContext } from '@tarojs/service'
type TPresetOrPluginAction = 'install' | 'uninstall'
type TPluginType = 'plugin' | 'preset'
const PRESET_OR_PLUGIN_COMMAND_CHINESE_MAP_MAP = {
install: '添加',
uninstall: '删除'
}
const PRESET_OR_PLUGIN_CHINESE_NAME_MAP = {
plugin: '插件',
preset: '插件集'
}
const PLUGIN_TYPE_TO_CONFIG_KEY = {
plugin: 'plugins',
preset: 'presets'
}
export default (ctx: IPluginContext) => {
ctx.registerCommand({
name: 'global-config',
synopsisList: [
'taro global-config add-plugin [pluginName]',
'taro global-config remove-plugin [pluginName]',
'taro global-config add-preset [presetName]',
'taro global-config remove-preset [presetName]',
'taro global-config reset',
],
optionsMap: {
'-r --registry [url]': '指定 npm registry',
'-h, --help': 'output usage information'
},
fn ({ _, options }) {
const [, action, pluginName] = _
const { getUserHomeDir, TARO_GLOBAL_CONFIG_DIR, fs, TARO_GLOBAL_CONFIG_FILE } = ctx.helper
const homedir = getUserHomeDir()
const globalPluginConfigDir = path.join(homedir, TARO_GLOBAL_CONFIG_DIR)
if (!homedir) return console.log('找不到用户根目录')
const rootPath = getRootPath()
const templatePath = path.join(rootPath, 'templates', 'global-config')
const registry = options.registry || options.r
function makeSureConfigExists () {
if (!fs.existsSync(globalPluginConfigDir)) {
const spinner = ora(`目录不存在,全局配置初始化`).start()
try {
fs.copySync(templatePath, globalPluginConfigDir)
spinner.succeed(`全局配置初始化成功,${globalPluginConfigDir}`)
} catch (e) {
spinner.fail(`全局配置初始化失败,${e}`)
process.exit(1)
}
}
}
function addOrRemovePresetOrPlugin (actionType: TPresetOrPluginAction, pluginType: TPluginType) {
makeSureConfigExists()
const presetOrPluginChineseName = PRESET_OR_PLUGIN_CHINESE_NAME_MAP[pluginType]
const chineseCommand = PRESET_OR_PLUGIN_COMMAND_CHINESE_MAP_MAP[actionType]
if (!pluginName) {
console.error(`缺少要${chineseCommand}的${presetOrPluginChineseName}`)
process.exit(1)
}
const spinner = ora(`开始${chineseCommand}${presetOrPluginChineseName} ${pluginName}`).start()
const pluginWithoutVersionName = getPkgNameByFilterVersion(pluginName)
if (!validatePkgName(pluginWithoutVersionName).validForNewPackages) {
spinner.fail('安装的插件名不合规!')
process.exit(1)
}
let command = `cd ${globalPluginConfigDir} && npm ${actionType} ${pluginName}`
if (registry) {
command += ` --registry=${registry}`
}
execCommand({
command,
successCallback (data) {
console.log(data.replace(/\n$/, ''))
spinner.start(`开始修改${presetOrPluginChineseName}配置`)
const configFilePath = path.join(globalPluginConfigDir, TARO_GLOBAL_CONFIG_FILE)
let globalConfig
try {
globalConfig = fs.readJSONSync(configFilePath)
} catch (e) {
spinner.fail('获取配置文件失败')
}
const configKey = PLUGIN_TYPE_TO_CONFIG_KEY[pluginType]
const configItem = globalConfig[configKey] || []
const pluginIndex = configItem.findIndex((item) => {
if (typeof item === 'string') return item === pluginWithoutVersionName
if (item instanceof Array) return item?.[0] === pluginWithoutVersionName
})
const shouldChangeFile = !(Number(pluginIndex !== -1) ^ Number(actionType === 'uninstall'))
if (shouldChangeFile) {
actionType === 'install' ? configItem.push(pluginWithoutVersionName) : configItem.splice(pluginIndex, 1)
try {
fs.writeJSONSync(configFilePath, {
[configKey]: configItem
})
} catch (e) {
spinner.fail(`修改配置文件失败:${e}`)
}
}
spinner.succeed('修改配置文件成功')
},
failCallback (data) {
spinner.stop()
spinner.warn(data.replace(/\n$/, ''))
}
})
}
switch (action) {
case 'add-plugin':
addOrRemovePresetOrPlugin('install', 'plugin')
break
case 'remove-plugin' :
addOrRemovePresetOrPlugin('uninstall', 'plugin')
break
case 'add-preset':
addOrRemovePresetOrPlugin('install', 'preset')
break
case 'remove-preset' :
addOrRemovePresetOrPlugin('uninstall', 'preset')
break
case 'reset':
if (fs.existsSync(globalPluginConfigDir)) fs.removeSync(globalPluginConfigDir)
fs.copySync(templatePath, globalPluginConfigDir)
break
default:
console.error('请输出正确的参数')
}
}
})
}