import { checkbox, input, select } from '@inquirer/prompts' import chalk from 'chalk' import fs from 'fs-extra' import { globby } from 'globby' import ora from 'ora' import path from 'path' import paths from './config/paths' const pkg = fs.readJsonSync(paths.resolveOwn('package.json')) async function step(msg: string, callback: (spinner: import('ora').Ora) => void | Promise) { const spinner = ora(msg).start() try { await callback(spinner) spinner.succeed() } catch (error) { spinner.fail() throw error } } export default async function autoRefactor() { if (await fs.pathExists(paths.public)) { console.log(chalk.green('已完成改造,不需要重复执行,如果运行报错请查看文档')) console.log(`文档: ${chalk.underline(pkg.homepage)}`) process.exit(0) } const appPkg = fs.readJsonSync(paths.package) const name = await input({ message: '请输入模块名称,要求唯一,不能与其他工程相同', default: appPkg.name, validate: (v) => /^[a-z][a-z0-9_-]+$/.test(v) || '请按格式输入 /^[a-z][a-z0-9_-]+$/ 只能使用小写字母、连字符、下划线', }) const version = await input({ message: '版本号', default: '1.0.0', validate: (v) => /^\d+\.\d+\.\d+$/.test(v) || '请按格式输入 /^\\d+\\.\\d+\\.\\d+$/ 例如: 1.0.0', }) const mode = await select({ message: '项目使用的哪种模式', choices: [ { name: '教育子工程模式', value: '' }, { name: '教育主工程模式', value: 'main' }, { name: '独立模式', value: 'single' }, ], }) let deploy: string[] = [] if (mode !== 'single') { deploy = await checkbox({ message: '项目需要部署到哪里', choices: [ { name: '校端', value: '-s' }, { name: '局端', value: '-b' }, { name: '公文端', value: '-d' }, ], validate: (v) => (!!v && v.length > 0) || '必须选一个', }) } const answers = { name, version, mode, deploy } appPkg.name = answers.name appPkg.version = answers.version await step('创建 public 文件夹', async () => { await fs.mkdir(paths.public) }) await step('移动 js 文件夹', async () => { if (await fs.pathExists(path.resolve(paths.src, 'js'))) { await fs.move(path.resolve(paths.src, 'js'), path.resolve(paths.public, 'js')) } }) await step('移动 html 文件', async () => { const HTMLFiles = await globby('*.html', { cwd: paths.src }) for (const file of HTMLFiles) { await fs.move(path.resolve(paths.src, file), path.resolve(paths.public, file)) } }) await step('删除 dll 文件夹', async () => { if (await fs.pathExists(path.resolve(paths.src, 'dll'))) { await fs.remove(path.resolve(paths.src, 'dll')) } }) await step('删除没用的 babel 和 webpack 配置', async () => { const deleteFiles = [ ...(await globby('{.,*}babel*')), ...(await globby('*webpack*')), ...(await globby('package-lock.json')), paths.nodeModules, paths.sshSftp, ] for (const filePath of deleteFiles) { await fs.remove(filePath) } }) await step('设置项目模式', () => { if (answers.mode) { appPkg.edu = { mode: answers.mode } } }) await step('修改 package.json 的 scripts', () => { const scripts = appPkg.scripts scripts.start = 'edu-scripts start' scripts.build = 'edu-scripts build' scripts.analyze = 'edu-scripts build --analyze' if (answers.mode !== 'single') { scripts.deploy = `edu-scripts deploy ${answers.deploy.join(' ')}` } else { scripts.deploy = `edu-scripts deploy` scripts['commit-dist'] = 'edu-scripts commit-dist --rm-local' } scripts['one-key-deploy'] = 'npm version patch' scripts.postversion = 'npm run build && npm run deploy' }) await step('删除 babel/webpack 相关依赖', (spinner) => { const deleteRe = /(babel|autoprefixer|webpack|loader|less|css|sass|hmr|ssh-sftp|regenerator-runtime|nowa|prettier)/i const deletePkgs = { dependencies: [] as string[], devDependencies: [] as string[], } Object.entries(deletePkgs).forEach(([scope, pkgs]) => { for (const key in appPkg[scope]) { if (Object.hasOwnProperty.call(appPkg[scope], key)) { if (deleteRe.test(key)) { pkgs.push(key) delete appPkg[scope][key] } } } }) spinner.clear() console.log(`删除的pkgs\n${chalk.green(JSON.stringify(deletePkgs, null, 2))}\n`) appPkg.devDependencies['@qse/edu-scripts'] = '^' + pkg.version }) await fs.writeFile(paths.package, JSON.stringify(appPkg, null, 2), 'utf-8') console.log( chalk.green(` 改造还未完成,剩余步骤请查看文档 ${pkg.homepage}#/refactor 运行 npm i 安装依赖 运行 edu-scripts start 启动服务 `) ) }