packages/f2elint/src/f2elint.ts (137 lines of code) (raw):

#!/usr/bin/env node import { cancel, confirm, intro, isCancel, outro, select, spinner, text } from '@clack/prompts'; import chalk from 'chalk'; import { Command } from 'commander'; import { existsSync, readFileSync } from 'fs'; import { dirname, join, resolve } from 'path'; import { fileURLToPath } from 'url'; import f2elint from '.'; import { runCommand } from './private/runCommand'; import { TemplateType } from './types'; const __dirname = dirname(fileURLToPath(import.meta.url)); const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8')); if (process.argv.length > 2 && !process.argv.includes('init')) { // Non-interactive const program = new Command('f2elint'); program .argument('[project]', '项目位置') .option('--template <template>', '模版类型', 'react') .option('--stylelint', '启用 Stylelint', false) .option('--prettier', '启用 Prettier', false) .option('--lint-staged', '启用 Lint-Staged', false) .option('--commitlint', '启用 Commitlint', false) .action(f2elint); program.helpOption('-h, --help', '显示帮助'); program.version(packageJson.version as string, '-v, --version', '显示版本'); program.parse(); } else { // Interactive (async () => { // 空行 console.log(' '); intro(`${chalk.bold(chalk.cyan('🚀 阿里巴巴前端规约'))} ${chalk.dim(packageJson.version)}`); const project = await text({ message: '📁 选择项目位置', initialValue: process.cwd(), validate: (value) => { if (!value || value.length === 0) { return '根目录路径必填!'; } else { return undefined; } }, }); if (isCancel(project)) { cancel('👋 已取消'); process.exit(0); } const projectPath = resolve(project || '.'); const isGitRoot = existsSync(join(projectPath, '.git')); const template = await select<TemplateType>({ message: '🧰 选择预设模版', options: [ { value: 'react', label: 'React' }, { value: 'base', label: 'Base' }, ], }); if (isCancel(template)) { cancel('👋 已取消'); process.exit(0); } const stylelint = await confirm({ message: '💅 启用 Stylelint 样式检查', }); if (isCancel(stylelint)) { cancel('👋 已取消'); process.exit(0); } const prettier = await confirm({ message: '💅 启用 Prettier 代码格式化', }); if (isCancel(prettier)) { cancel('👋 已取消'); process.exit(0); } let lintStaged: boolean | symbol = false; let commitlint: boolean | symbol = false; if (isGitRoot) { lintStaged = await confirm({ message: '👮‍ 启用 Lint Staged 检查', }); if (isCancel(lintStaged)) { cancel('👋 已取消'); process.exit(0); } commitlint = await confirm({ message: '👮‍ 启用 Commitlint 检查', }); if (isCancel(commitlint)) { cancel('👋 已取消'); process.exit(0); } } const s1 = spinner(); s1.start('🚧 正在初始化项目'); try { await f2elint(projectPath, { template, stylelint, prettier, lintStaged, commitlint, disableLog: true, }); s1.stop('✅ 初始化项目完成'); } catch (error) { s1.stop('❌ 初始化项目失败'); console.error(error); process.exit(1); } const npmCommand = await select<string>({ message: '📦 安装或更新依赖', options: [ { value: 'npm i', label: 'npm' }, { value: 'pnpm i', label: 'pnpm' }, { value: 'yarn', label: 'yarn' }, { value: 'tnpm i', label: 'tnpm' }, { value: 'cnpm i', label: 'cnpm' }, { value: '', label: '跳过' }, ], }); if (isCancel(npmCommand)) { cancel('👋 已取消'); process.exit(0); } if (npmCommand) { const s2 = spinner(); s2.start('🚧 正在安装依赖'); try { await runCommand(projectPath, npmCommand); s2.stop('✅ 安装依赖成功'); } catch (error) { s2.stop('❌ 安装依赖失败,请尝试手动运行命令'); console.error(error); process.exit(1); } } outro('🎉 规约初始化完成,建议安装推荐的 VS Code 插件并重启 VS Code'); })(); }