1. 判断当前目录是否为空功能开发
本周代码从commands/init/lib/index.js文件中的exec方法开始启动。 根据上面的两小节分析,exec方法的代码逻辑为:
- 准备阶段 【this.prepare()】
- 下载模版
- 安装模版(下周实现)
prepare方法的代码逻辑为:
- 判断当前目录是否为空
- 是否强制清空
- 选择创建项目或组件
- 获取项目/组件的基本信息
本节主要实现的代码是判断当前目录是否为空
prepare() {
    // 1. 判断当前目录是否为空
    if (!this.isCwdEmpty()) {
        // 1.1 询问是否继续创建
    }
    console.log(ret);
    // 2. 是否启动强制更新
    // 3. 选择创建项目或组件
    // 4. 获取项目的基本信息
}
// 判断当前目录是否为空
isCwdEmpty() {
    const localPath = process.cwd() // 当前工作目录
    let fileList = fs.readdirSync(localPath)
    fileList = fileList.filter(file => (
        !file.startsWith('.') && ['node_modules'].indexOf(file) < 0
    ))
    return !fileList || fileList.length <= 0
}
本节知识点:
- 拿到当前目录的方法一:process.cwd()
- 拿到当前目录的方法二: path.resolve('.')
- path.resolve(__dirname):拿到的是当前执行代码的目录
- 读取当前目录下的文件列表:fs.readdirSync()
2. 强制清空当前目录功能开发
本节主要是清空当前目录,进行清空下,使用命令行交互inquirer问询,以及用 force这个参数添加业务逻辑,进行目录的清空判断
清空目录功能主要是使用了第三方库*fs-extra*的*emptyDirSync***(localPath)**方法。
const inquirer = require('inquirer')
const fse = require('fs-extra')
// 1. 判断当前目录是否为空
const localPath = process.cwd() // 当前工作目录
if (!this.isDirEmpty(localPath)) {
    let ifContinue = false
    if (!this.force) {
        // 询问是否继续创建
        ifContinue = (await inquirer.prompt({
            type: 'confirm',
            name: 'ifContinue',
            message: '当前文件夹不为空,是否继续创建项目?'
        })).ifContinue
        if (!ifContinue) {
            return
        }
    }
    // 2. 是否启动强制更新
    if (ifContinue || this.force) {
        // 给用户做二次确认
        const { confirmDelete } = await inquirer.prompt({
            type: 'confirm',
            name: 'confirmDelete',
            message: '是否确认清空当前目录下的文件?'
        })
        if (confirmDelete) {
            // 清空当前目录
            fse.emptyDirSync(localPath)
        }
    }
}
3. 获取项目基本信息功能开发
本节使用inquirer进行了项目或者组件的选择询问、以及版本号控制台输入功能,但未对输入内容进行校验 这里调整好代码逻辑即可。
async getProjectInfo() {
        const projectInfo = {}
        // 1. 选择创建项目或组件
        const { type } = await inquirer.prompt({
            type: 'list',
            name: 'type',
            message: '请选择初始化类型',
            default: TYPE_PROJECT,
            choices: [{
                name: '项目',
                value: TYPE_PROJECT
            }, {
                name: '组件',
                value: TYPE_COMPONENT
            }]
        })
        log.verbose('type', type)
        // 2. 获取项目的基本信息
        if (type === TYPE_PROJECT) {
            const o = await inquirer.prompt([{
                type: 'input',
                name: 'projectName',
                message: '请输入项目名称',
                default: '',
                validate: function (v) {
                    const done = this.async();
                    setTimeout(function () {
                        // 1. 输入的首字符必须为英文字母
                        // 2. 尾字符必须为英文或数字,不能为字符
                        // 3. 字符允许"-_"
                        // 合法: a, a-b, a_b, a-b-c, a-b1-c1,a_b1_c1a1,a1,a1-b1-c1, a1_b1_c1
                        // 不合法: 1,a_,a-.a_1,a-1
                        const reg = /^[a-zA-Z]+([-][a-zA-Z][a-zA-Z0-9]*|[_][a-zA-Z][a-zA-Z0-9]*|[a-zA-Z0-9])*$/
                        if (!reg.test(v)) {
                            done('请输入合法的项目名称');
                            return;
                        }
                        done(null, true);
                    }, 0);
                },
                filter: function (v) {
                    return v
                }
            }, {
                type: 'input',
                name: 'projectVersion',
                message: '请输入项目版本号',
                default: '1.0.0',
                validate: function (v) {
                    const done = this.async();
                    setTimeout(function () {
                        if (!(!!semver.valid(v))) {
                            done('请输入合法的版本号');
                            return;
                        }
                        done(null, true);
                    }, 0);
                },
                filter: function (v) {
                    if (semver.valid(v)) {
                        return semver.valid(v)
                    } else {
                        return v
                    }
                }
            }])
            console.log(o);
        } else if (type === TYPE_COMPONENT) {
        }
        return projectInfo
    }