实现简易 CLI

2023-05-17 16:41:41 浏览数 (2)

# 创建工程

初始化

代码语言:javascript复制
mkdir kkb-vue-auto-router-cli
cd kkb-vue-auto-router-cli
npm init -y
npm i commander download-git-repo ora handlebars figlet clear chalk open -s

设置启动入口 bin/kkb.js

代码语言:javascript复制
#!/usr/bin/env node
console.log('cli....');

package.json

代码语言:javascript复制
"bin": {
  "kkb": "./bin/kkb.js"
}

将npm 模块链接到对应的运⾏项⽬目中去,相当于设置全局命令或全局安装

代码语言:javascript复制
npm link

# 安装完成测试
kkb # 输出 cli...

# 定制命令行界面

初始化交互 kkb.js

代码语言:javascript复制
#!/usr/bin/env node
const program = require('commander');
program.version(require('../package').version);

program
  .command('init <name>')
  .description('init project')
  .action(name => {
    console.log(`init ${name}`);
  });

program.parse(process.argv);

测试

代码语言:javascript复制
kkb init test-app
# 输出 init test-app

将初始化模块化,并制作欢迎界面 lib/init.js

代码语言:javascript复制
const { promisify } = require('util');
const figlet = promisify(require('figlet'));
const clear = require('clear');
const chalk = require('chalk');
const log = content => console.log(chalk.green(content));

module.exports = async name =>  {
  clear();
  const data = await figlet('KKB Welcome');
  log(data);
};

kkb.js

代码语言:javascript复制
#!/usr/bin/env node
const program = require('commander');
program.version(require('../package').version);

program
  .command('init <name>')
  .description('init project')
  .action(require('../lib/init'));

program.parse(process.argv);

# 远程下载

添加下载模块 libdownload.js

代码语言:javascript复制
const { promisify } = require('util');

const downloadGitRepo = require('download-git-repo');
const ora = require('ora');

module.exports.clone = async function(repo, desc) {
  const download = promisify(downloadGitRepo);
  const process = ora(`下载...${repo}`);
  process.start();
  await download(repo, desc);
  process.succeed();
}

下载模板 libinit.js

代码语言:javascript复制
const { promisify } = require('util');
const figlet = promisify(require('figlet'));
const clear = require('clear');
const chalk = require('chalk');
const log = content => console.log(chalk.green(content));
const { clone } = require('./download');

module.exports.init = async name =>  {
  // 欢迎界面
  clear();
  const data = await figlet('KKB Welcome');
  log(data);
  // 下载模板
  await clone('github:cellinlab/vue-template', name);
};

测试

代码语言:javascript复制
kkb init testapp

# 安装依赖

lib/init.js

代码语言:javascript复制
// ...
module.exports.init = async name =>  {
  // ...

  // 安装依赖
  log('安装依赖');
  await spawn(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['install'], { cwd: `./${name}` });
  log(chalk.green(`
安装完成:
To get Start:
===========================
cd ${name}
npm run serve
===========================
 `))
};

// 对接输出流
const spawn = async (...args) => {
  const { spawn } = require('child_process');
  return new Promise((resolve, reject) => {
    const proc = spawn(...args);
    proc.stdout.pipe(process.stdout);
    proc.stderr.pipe(process.stderr);
    proc.on('close', () => {
      resolve();
    });
  });
};

# 自动启动

lib/init.js

代码语言:javascript复制
const open = require('open');

module.exports.init = async name =>  {
  // ...

  // 启动项目
  open(`http://localhost:8080`);
  await spawn(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['run', 'serve'], { cwd: `./${name}` });
};

# 约定路由

生成文件 lib/refresh.js

代码语言:javascript复制
const fs = require('fs');
const handlebars = require('handlebars');
const chalk = require('chalk');

module.exports = async () => {
  // 获取页面列表
  const list = fs.readdirSync('./src/views')
    .filter(fname => fname !== 'Home.vue')
    .map(fname => ({
      name: fname.replace('.vue', '').toLowerCase(),
      file: fname,
    }));
  
  // 生成路由
  compile({
    list,
  }, './src/router.js', './template/router.js.hbs');

  // 生成菜单
  compile({
    list,
  }, './src/App.vue', './template/App.vue.hbs');

  /**
   * 编译模板文件
   * @param {*} meta 
   * @param {*} filePath 
   * @param {*} templatePath 
   */
  function compile(meta, filePath, templatePath) {
    if (fs.existsSync(templatePath)) {
      const content = fs.readFileSync(templatePath).toString();
      const result = handlebars.compile(content)(meta);
      fs.writeFileSync(filePath, result);
    }
    console.log(chalk.green(`${filePath} 创建成功`));
  }
};

自动刷新 bin/kkb.js

代码语言:javascript复制
#!/usr/bin/env node
const program = require('commander');
// ...
program
  .command('refresh')
  .description('refresh project')
  .action(require('../lib/refresh'));

program.parse(process.argv);

# 发布 npm

新建发布脚本 publish.sh

代码语言:javascript复制
#!/usr/bin/env bash
npm config get registry
npm config set registry=http://registry.npmjs.org
echo "请进行登录操作:"
npm login
echo "---publishing---"
npm publish
npm config set registry=https://registry.npm.taobao.org
echo "发布完成"
exit

发布

代码语言:javascript复制
./publish.sh # win

0 人点赞