如何写一个前端cli项目

Talk is cheep, show you the code!

1.package.json搞起来

{
  "name": "ukulele-cli",
  "version": "1.0.0",
  "description": "风戏辞的VUE脚手架项目",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "bin": {
    "timing": "bin/timing",
    "timing-add": "bin/timing-add",
    "timing-delete": "bin/timing-delete",
    "timing-list": "bin/timing-list",
    "fline-init": "bin/timing-init"
  },
  "author": "风戏辞",
  "license": "MIT",
  "dependencies": {
    "chalk": "^2.4.2",
    "commander": "^3.0.2",
    "download-git-repo": "^2.0.0",
    "inquirer": "^7.0.0",
    "ora": "^4.0.2"
  }
}

2. 安装依赖

别说你不知道node哦

npm install

3.建一个bin文件夹

4.开始创建命令文件

4.1 timing.js

#!/usr/bin/env node
console.log('hello timing');

const program = require('commander')
 
// 定义当前版本
// 定义使用方法
// 定义四个指令
program
 .version(require('../package').version)
 .usage('<command> [options]')
 .command('add', 'add a new template')
 .command('delete', 'delete a template')
 .command('list', 'list all the templates')
 .command('init', 'generate a new project from a template')
  
// 解析命令行参数
program.parse(process.argv)

4.2 timing-add(添加项目模板的命令)

没错,不需要扩展名

#!/usr/bin/env node
 
// 交互式命令行
const inquirer = require('inquirer')
// 修改控制台字符串的样式
const chalk = require('chalk')
// node 内置文件模块
const fs = require('fs')
// 读取根目录下的 template.json
const tplObj = require(`${__dirname}/../template`)
 
// 自定义交互式命令行的问题及简单的校验
let question = [
 {
 name: "name",
 type: 'input',
 message: "请输入模板名称",
 validate (val) {
  if (val === '') {
  return 'Name is required!'
  } else if (tplObj[val]) {
  return 'Template has already existed!'
  } else {
  return true
  }
 }
 },
 {
 name: "url",
 type: 'input',
 message: "请输入模板地址",
 validate (val) {
  if (val === '') return 'The url is required!'
  return true
 }
 }
]
 
inquirer
 .prompt(question).then(answers => {
 // answers 就是用户输入的内容,是个对象
 let { name, url } = answers;
 // 过滤 unicode 字符
 tplObj[name] = url.replace(/[\u0000-\u0019]/g, '')
 // 把模板信息写入 template.json 文件中
 fs.writeFile(`${__dirname}/../template.json`, JSON.stringify(tplObj), 'utf-8', err => {
  if (err) console.log(err)
  console.log('\n')
  console.log(chalk.green('Added successfully!\n'))
  console.log(chalk.grey('The latest template list is: \n'))
  console.log(tplObj)
  console.log('\n')
 })
 })

4.3 timing-delete(删除项目模板的命令)

#!/usr/bin/env node

const inquirer = require('inquirer')
const chalk = require('chalk')
const fs = require('fs')
const tplObj = require(`${__dirname}/../template`)

let question = [
  {
    name: "name",
    message: "请输入要删除的模板名称",
    validate (val) {
      if (val === '') {
        return 'Name is required!'
      } else if (!tplObj[val]) {
        return 'Template does not exist!'
      } else  {
        return true
      }
    }
  }
]

inquirer
  .prompt(question).then(answers => {
    // answers 就是用户输入的内容
    let { name } = answers;
    delete tplObj[name]
    // 更新 template.json 文件
    fs.writeFile(`${__dirname}/../template.json`, JSON.stringify(tplObj), 'utf-8', err => {
      if (err) console.log(err)
      console.log('\n')
      console.log(chalk.green('Deleted successfully!\n'))
      console.log(chalk.grey('The latest template list is: \n'))
      console.log(tplObj)
      console.log('\n')
    })
  })

4.4 timing-init(初始化项目的命令)

#!/usr/bin/env node

const program = require('commander')
const chalk = require('chalk')
const ora = require('ora')
const download = require('download-git-repo')
const tplObj = require(`${__dirname}/../template`)

program
  .usage('<template-name> [project-name]')
program.parse(process.argv)
// 当没有输入参数的时候给个提示
if (program.args.length < 1) return program.help()

// 好比 vue init webpack project-name 的命令一样,第一个参数是 webpack,第二个参数是 project-name
let templateName = program.args[0]
let projectName = program.args[1]

if (!tplObj[templateName]) {
  console.log(chalk.red('\n Template does not exit! \n '))
  return
}
if (!projectName) {
  console.log(chalk.red('\n Project should not be empty! \n '))
  return
}

url = tplObj[templateName]
console.log(chalk.white('\n Start generating... \n'))
const spinner = ora("Downloading...");
spinner.start();

download (
  url,
  projectName,
  err => {
    if (err) {
      spinner.fail();
      console.log(chalk.red(`Generation failed. ${err}`))
      return
    }

    spinner.succeed();
    console.log(chalk.green('\n Generation completed!'))
    console.log('\n To get started')
    console.log(`\n    cd ${projectName} \n`)
  }
)

4.5 timing-list(获取模板列表的命令)

#!/usr/bin/env node

const tplObj = require(`${__dirname}/../template`)
console.log(tplObj)

5 创建一个空的模板文件template.json

名称要与上面那些命令代码里的名称一致。

{}

完成编码,编译并发布到npm仓库,然后就可以使用啦。


6.全局安装timing-cli

npm i timing-cli -g

7.检验是否安装成功

timing

会在控制台显示add,delele,init,list的命令解释

8.查看当前所有的模板项目

timing-list

模板里是空的,所以此处应该只有一个空的json串({})

9.添加一个模板仓库

timing-add 

按照提示,依次输入模板名称和模板项目所在的git地址(目前不支持私有的git仓库)

10. 查看是否添加成功

timing-list

这个时候控制台输出的应该就是你刚刚添加的模板项目了,大概是这样的

{'timing-test':'https://github.com/timing/timing-test.git'}

11 使用模板创建一个项目

timing-init timing-test test
第一个参数为刚刚添加的模板项目名称,第二个参数为新建项目的名称

好了,就这么简单。

 

欢迎来我的个人网站逛逛:往后码生

 

上一篇:程序员工作2年月薪12K,我先收藏为敬


下一篇:du 命令计算隐藏文件夹或文件