UNPKG

lizi-wxapp-cli

Version:

微信小程序快速创建cli脚手架

266 lines (243 loc) 9.27 kB
import autocomplete from '@moyuyc/inquirer-autocomplete-prompt' import chalk from 'chalk' import fuzzy from 'fuzzy' import inquirer, { Answers, ConfirmQuestion, InputQuestion } from 'inquirer' import jsonFormat from 'json-format' import ora, { Ora } from 'ora' import path from 'path' import { regName } from '../ulits/ulits' import Base from './base' interface CreateFs { init(): Promise<void> makeProjectDir(): Promise<any> copyProjectFiles(): void modifyAppJson(): Promise<void> create(): Promise<Ora> } export default abstract class Create extends Base implements CreateFs { protected _name: string = '' protected _isSubpackage: boolean = false protected _selectSubpackage: string = '' protected _createMain?: string protected _isIndependent?: boolean protected newItemRoot: string = '' protected newItemJsonRoot: string = '' protected newItemJsonName: string = '' protected constructor() { super() } public async init(): Promise<void> { await this.getAppJson() // 注册插件 inquirer.registerPrompt('autocomplete', autocomplete) inquirer.prompt([ this.__checkName(), this.__isSubPackage(), this.__modifyName(), this.__selectSubPackage(), this.__createSubPackage(), this.__modifySubPackageChildName(), this.__isIndependent() ]).then((answers: any) => { let {name, isSubpackage, selectSubpackage, createMain, isIndependent} = answers this._name = name this._isSubpackage = isSubpackage this._selectSubpackage = selectSubpackage this._createMain = createMain this._isIndependent = isIndependent }).then(() => this.create()).catch((error) => { console.log(error) }) } public async create(): Promise<Ora> { const loading: Ora = ora(`creating ${this.typeRoot}...`).start() loading.text = `创建${this.typeName}目录` await this.makeProjectDir() loading.text = `正在创建${this.typeName}文件` await this.copyProjectFiles() loading.text = '正在修改【app.json】文件' await this.modifyAppJson() return Promise.resolve(loading) } public async makeProjectDir(): Promise<any> { // 默认不分包 let newItemRoot = path.join(this.projectRoot, this.typeRoot, this._name) // 如果分包 if (this._isSubpackage) { let name: string = this._selectSubpackage === '新增分包' && this._createMain ? path.join(this.subpackageRoot, this._createMain) : this._selectSubpackage newItemRoot = path.join(this.projectRoot, name, this.typeRoot, this._name) } this.newItemRoot = newItemRoot // 判断下文件是否存在 if (!await this.checkFileIsExists(newItemRoot)) this.makeDir(newItemRoot) } public copyProjectFiles(): void { // 读取project.config.json获取配置信息 this.getProjectConfig().then(async () => { const copyRoot = path.join(this.templateRoot, 'component') // 复制wxml,json文件 await this.copyFilesArr(copyRoot, this.newItemRoot, ['index.wxml', 'index.json']) .catch(({result}) => this.fileIsRepeat(result)) // 复制脚本文件 this._copyTypeFiles(copyRoot, this.projectMode) // 复制样式文件 this._copyTypeFiles(copyRoot, this.projectCss) }) } public async modifyAppJson(): Promise<void> { // 是否分包 let newItemJson: string = path.join(this.typeRoot, this._name, 'index').split(path.sep).join('/') let newItemName: string = this._name if (this._isSubpackage) { if (this._selectSubpackage === '新增分包' && this._createMain) { this.AppJson.subpackages.push({ root: path.join(this.subpackageRoot, this._createMain), pages: this.typeRoot === 'pages' ? [newItemJson] : [], components: this.typeRoot === 'components' ? [newItemJson] : [], isIndependent: this._isIndependent }) newItemName = path.join(this._createMain, this._name) newItemJson = path.join(this.subpackageRoot, this._createMain, newItemJson) } else { let index: number = this.subRoots.findIndex(v => v === this._selectSubpackage) this.AppJson.subpackages[index][this.typeRoot].push(newItemJson) newItemName = path.join(this._selectSubpackage.replace(this.subpackageRoot + '/', ''), this._name) newItemJson = path.join(this._selectSubpackage, newItemJson) } } else { this.AppJson[this.typeRoot].push(newItemJson) } this.newItemJsonRoot = newItemJson.split(path.sep).join('/') this.newItemJsonName = newItemName.split(path.sep).join('/') await this.writeFile(this.projectRoot, 'app.json', jsonFormat(this.AppJson)) } private async _copyTypeFiles(copyRoot, type): Promise<void> { const root: string = path.join(copyRoot, type) const files: string[] = await this.readDirs(root) await this.copyFilesArr(root, this.newItemRoot, files) .catch(({result}) => this.fileIsRepeat(result)) } // 验证名称 private __checkName(): InputQuestion<Answers> { return { type: 'input', name: 'name', message: `请输入${this.typeName}名:`, validate: (input: string): Promise<boolean | string> => { return new Promise<boolean | string>((resolve) => { // 验证名是否正确 if (!regName.test(input)) resolve(chalk.red(`输入的${this.typeName}名不正确!`)) resolve(true) }) } } } // 是否分包 private __isSubPackage(): ConfirmQuestion<Answers> { return { type: 'confirm', name: 'isSubpackage', message: `当前${this.typeName}是否分包:`, default: false } } // 如果不分包,判断是否重复 private __modifyName(): InputQuestion<Answers> { return { type: 'input', name: 'name', message: answer => `【${this.typeRoot}】中已存在【${answer.name}】${this.typeName},请重新输入${this.typeName}名:`, when: answer => { return !answer.isSubpackage && this.mainRoots.find(v => v === answer.name) !== undefined }, validate: (input: string): Promise<boolean | string> => { return new Promise<boolean | string>(resolve => { if (this.mainRoots.find(v => v === input)) resolve(chalk.red(`${this.typeName}名重复,请更换!`)) resolve(true) }) } } } // 选择分包 private __selectSubPackage(): object { return { type: 'autocomplete', name: 'selectSubpackage', message: `选择${this.typeName}所属分包:`, choices: [], suggestOnly: false, source: (_answers, input: string) => { return Promise.resolve(fuzzy.filter(input, ['新增分包', ...this.subRoots]).map(e => e.original)) }, when: (answer) => { return answer.isSubpackage && this.subRoots.length >= 0 } } } // 创建分包 private __createSubPackage(): InputQuestion<Answers> { return { type: 'input', name: 'createMain', message: '创建新的分包:', when: (answer) => { return answer.isSubpackage && this.subRoots.length <= 0 || answer.selectSubpackage === '新增分包' }, validate: (input: string): Promise<boolean | string> => { return new Promise<boolean | string>(resolve => { // 验证名是否正确 if (!regName.test(input)) { resolve(chalk.red('输入的分包名不正确!')) }// 检查分包名是否重复 else if (this.subRoots.find(v => v === input)) resolve(chalk.red('该分包已存在,请换个分包名!')) resolve(true) }) } } } // 分包下的子包如果重复则需要修改子包名 private __modifySubPackageChildName(): InputQuestion<Answers> { return { type: 'input', name: 'name', message: answer => `【${answer.selectSubpackage}】分包已存在【${answer.name}】${this.typeName},请更换${this.typeName}名:`, when: answer => { return answer.isSubpackage && answer.selectSubpackage !== '新增分包' && this.subChild[answer.selectSubpackage].find(v => v === answer.name) !== undefined }, validate: (input: string, answers: any): Promise<boolean | string> => { return new Promise<boolean | string>(resolve => { // 验证名是否正确 if (!regName.test(input)) { resolve(chalk.red(`输入的${this.typeName}名不正确!`)) }// 验证是否重复 else if (this.subChild[answers.selectSubpackage].find(v => v === input)) { resolve(chalk.red(`${this.typeName}名重复,请更换${this.typeName}名!`)) } resolve(true) }) } } } // 新增分包是否为独立分包 private __isIndependent(): ConfirmQuestion<Answers> { return { type: 'confirm', name: 'isIndependent', message: '是否设置独立分包:', default: false, when: (answers) => { return answers.isSubpackage && answers.selectSubpackage === '新增分包' && answers.createMain } } } }