Skip to content

CLI

2023-04-06
Author:lzugis

1.初始化工程

shell
npm init -y

2.修改package.json

json
"bin": {
    "sfmap-cli": "index.js"
},

3.开发调试

通过命令npm link连接npm调试。

shell
npm link

4.安装依赖

需要安装的依赖如package.json文件

json
"dependencies": {
    "chalk": "^4.1.2",
    "child_process": "^1.0.2",
    "commander": "^9.0.0",
    "download-git-repo": "^3.0.2",
    "inquirer": "^8.2.0",
    "ora": "^5.4.0",
    "spinner": "^0.3.4"
},

注意:依赖安装必须带参数-S或者--save.

shell
npm i chalk -S

5.新建index.js

JS
let fs = require('fs')
const program = require('commander'); // 命令行工具
const download = require('download-git-repo'); // 远程下载
const ora = require('ora'); // loading
const exec = require('child_process').exec
const inquirer = require('inquirer'); // 命令行交互
const chalk = require('chalk'); // 输出样式化
const packageJson = require('./package.json');

// 版本信息
program.version(packageJson.version, '-v, --version') // 版本信息
    .usage('<command> [options]'); // 使用信息

/**
 * 删除文件夹下所有问价及将文件夹下所有文件清空
 * @param {*} path
 */
function emptyDir(path) {
    const files = fs.readdirSync(path);
    files.forEach(file => {
        const filePath = `${path}/${file}`;
        const stats = fs.statSync(filePath);
        if (stats.isDirectory()) {
            emptyDir(filePath);
        } else {
            fs.unlinkSync(filePath);
        }
    });
}
/**
 * 删除指定路径下的所有空文件夹
 * @param {*} path
 */
function rmEmptyDir(path, level=0) {
    const files = fs.readdirSync(path);
    if (files.length > 0) {
        let tempFile = 0;
        files.forEach(file => {
            tempFile++;
            rmEmptyDir(`${path}/${file}`, 1);
        });
        if (tempFile === files.length && level !== 0) {
            fs.rmdirSync(path);
        }
    }
    else {
        level !==0 && fs.rmdirSync(path);
    }
}

/**
 * 清空指定路径下的所有文件及文件夹
 * @param {*} path
 */
function clearDir(path) {
    const isExist = fs.existsSync(path)
    if(isExist) {
        console.log('')
        const spinner = ora('删除目录');
        spinner.start()
        spinner.text = `目录${path}删除中`;
        spinner.spinner = {
            interval: 120, // Optional
            frames: ['.  ', '.. ', '...', '.. ']
        }
        emptyDir(path);
        rmEmptyDir(path);
        spinner.succeed()
        spinner.color = 'green'
        console.log(' ')
    }
}

/**
 * 下载模板
 */
function downloadTemplate(projectName) {
    console.log(' ')
    inquirer.prompt([
        {
            type: "list",
            message: "是否使用TypeScript:",
            name: 'branch',
            default:"Yes",
            choices:[
                "Yes",
                "No"
            ]
        },
    ]).then(res => {
        const branch = res['branch'] === 'Yes' ? 'ts' : 'js'
        const gitUrl = `direct:${packageJson.template.url}#feature/${branch}`
        const spinner = ora('初始化项目');
        console.log(' ')
        console.log(gitUrl)
        console.log(' ')
        spinner.start()
        spinner.text = `项目${projectName}初始化,模板拉取中`;
        spinner.spinner = {
            interval: 120, // Optional
            frames: ['.  ', '.. ', '...', '.. ']
        }
        download(gitUrl, projectName, { clone: true }, async function (err) {
            if(err) {
                console.log(' ')
                spinner.fail('模板拉取失败,尝试重新拉取!')
                downloadTemplate(projectName)
                console.log(' ')
            } else {
                spinner.succeed('模板拉取成功!')
                const answerName = "dependence"
                console.log(' ')
                const answer = await inquirer.prompt([
                    {
                        type: "list",
                        message: "是否立即安装依赖:",
                        name: answerName,
                        default:"Yes",
                        choices:[
                            "Yes",
                            "No"
                        ]
                    },
                ]);
                const script = `cd ./${projectName} && npm install`
                if(answer[answerName] === 'Yes') {
                    const spinner = ora('安装依赖');
                    spinner.start()
                    spinner.text = `依赖安装中`;
                    spinner.spinner = {
                        interval: 120, // Optional
                        frames: ['.  ', '.. ', '...', '.. ']
                    }
                    exec(script, (err, stdout, stderr) => {
                        if (err){
                            console.log(' ')
                            spinner.fail('依赖安装失败!')
                        } else {
                            console.log(' ')
                            spinner.succeed('依赖安装成功!')
                            console.log('接下来你可以:')
                            console.log('')
                            console.log('      ' + chalk.blue('npm run dev'))
                            console.log(' ')
                        }
                    });
                } else {
                    console.log(' ')
                    console.log('接下来你可以:')
                    console.log(' ')
                    console.log('  ' + chalk.blue(`${script}`))
                    console.log('  ' + chalk.blue('npm run dev'))
                    console.log(' ')
                }
            }
        })
    })
}

program.command('create')
    .description('初始化项目')
    .action(() => {
        console.log(' ')
        inquirer.prompt([
            {
                type: 'input',
                message: '请输入项目名称:',
                name: 'projectName',
                default: packageJson.template.name // 默认值
            }
        ]).then(res => {
            console.log(' ')
            console.log('即将创建工程' + chalk.blue(res.projectName))
            console.log(' ')
            // 判断路径是否存在,存在则先删除
            clearDir(`./${res.projectName}`)
            // 下载模板
            downloadTemplate(res.projectName)
        })
    });

program.parse(process.argv);

6.登录npm发布

修改package.json,添加如下内容。

json

"publishConfig":{
    "registry":"http://artifactory.sf-express.com/artifactory/api/npm/npm-sf-local/"
  },

登录npm并发布

shell
# 登录, 用自己的工号(01416068),密码,邮箱登录(niujianping@sfmail.sf-express.com)
npm login --registry http://artifactory.sf-express.com/artifactory/api/npm/npm-sf-local/

# 发布
npm publish

7.取消连接

shell
npm unlink sfmap-cli

8.安装cli并使用

shell
# 安装依赖
npm i sfmap-cli -g
# 创建工程
easymap-cli create

运行示例