commander-scripts-ivan
Version:
102 lines (88 loc) • 2.96 kB
JavaScript
/* eslint-disable no-console, import/no-unresolved */
const path = require('path')
const { execSync } = require('child_process')
const chalk = require('chalk')
const commander = require('commander')
const fs = require('fs-extra')
const spawn = require('cross-spawn')
const validateProjectName = require('validate-npm-package-name')
const STARTER = 'web-scripts-ivan'
function red(...x) {
return console.error(chalk.red(x.join('\n')))
}
// 创建项目指令处理
let name
commander.arguments('<project-directory>')
.usage(`${chalk.cyan('starter')} ${chalk.green('<project-directory>')} [options...]`)
.action((projectDirectory) => { name = projectDirectory })
.allowUnknownOption()
.parse(process.argv)
if (typeof name === 'undefined') {
red('Please specify the project directory:')
process.exit(1)
}
// 检查项目名合法性
const validationResult = validateProjectName(name)
if (!validationResult.validForNewPackages) {
console.error(`Could not create a project called ${chalk.red(`"${name}"`)} because of npm naming restrictions:`)
red(validationResult.errors)
red(validationResult.warnings)
process.exit(1)
}
// 检查项目名文件夹是否不存在
if (fs.existsSync(name)) {
console.log(`The directory ${chalk.red(name)} exists!`)
process.exit(1)
}
function shouldUse() {
try {
execSync('yarn --version', { stdio: 'ignore' })
return {
command: 'yarn',
args: ['add', '-D', '-E', STARTER],
}
} catch (err) {
return {
command: 'npm',
args: ['install', '-D', '-E', STARTER],
}
}
}
Promise.resolve(STARTER)
.then((packageName) => {
fs.ensureDirSync(name) // Like mkdir -p
const root = path.resolve(name) // 把一个路径或路径片段的序列解析为一个绝对路径
const packageJson = { name, version: '0.0.1', private: true }
fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify(packageJson, null, 2))
process.chdir(root)
console.log(chalk.cyan('Installing packages. This might take a couple of minutes...\n\n'))
const { args, command } = shouldUse()
// 异步执行npm install指令以promise resolve得到
const child = spawn.sync(command, args, { stdio: 'inherit' })
if (child.status !== 0) {
red('\n\nAborting installation.')
// 删除文件夹
fs.removeSync(path.join(root))
process.exit(1)
}
console.log(chalk.green(`\n\n${packageName} has been installed...\n\n`))
// 执行对应打包库里的文件配置
const scriptsPath = path.resolve(
process.cwd(),
'node_modules',
packageName,
'init.js',
)
const init = require(scriptsPath) // eslint-disable-line
init(root, name)
})
.catch((error) => {
console.error(chalk.red('\n\nExecute init script failed...'))
if (error) {
console.error(error)
}
// 删除文件夹
fs.removeSync(path.join(root))
process.exit(1)
})