脚手架工具开发

项目创建

初步创建

  • 创建index.js

    • 编写一些简单代码
  • 创建package.json

    • npm init -y
  • 创建hype 命令

    • 入口文件中,添加如下指令(shebang也称为hashbang)

      • #!/usr/bin/env node
        • 根据配置环境执行当前文件
    • 修改package.json

      1
      2
      3
      "bin":{
      "hype":"index.js"
      }
    • npm link

Commander的使用

  • npm install commander

    1
    2
    3
    4
    5
    6
    7
    const program = require('commander')

    //查看版本号
    program.version(require('./package.json').version)

    //解析终端指令
    program.parse(process.argv)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //添加自己的option
    const program = require('commander')
    const helpOptions = () => {
    //增加自己的options
    program.option('-h --hype', 'a hype cli')
    program.option('-d --dest<dest>', 'a destination folder,例如:-d /src/components')
    program.option('-f --framework<framework>', 'your framework')

    program.on('--help', function () {
    console.log("");
    console.log("other");
    console.log(" ohter options");
    })
    }
  • 创建项目指令实现思路

    • 创建解析create指令

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      const program = require('commander')
      const {createProjectAction}=require('./action')
      const createCommands =()=>{
      program
      .command('create <project> [others...]')
      .description('clone a repository into a folder')
      /*会在action中执行相关函数*/
      .action(createProjectAction)
      }

      module.exports= {createCommands}

      通过download-git-repo从代码仓库中下载模板

    1
    2
    3
    download('flippidippi/download-git-repo-fixture', 'test/tmp', function (err) {
    console.log(err ? 'Error' : 'Success')
    })
    1
    2
    利用内部的一个方法 可以将代码转成promise形式 
    const {promisify} = require('util')
    1
    await download(vueRepo,project,{clone: true});

  • 进入目录,并且执行 npm install命令

    • 执行终端命令

      • const { spawn } = require(‘child_process’) // 子进程

      • child_process.spawn(command[, args][, options])

      • which/where yarn/npm... 查看所在路径

      • 需要加上一个判断是否是windows系统

        1
        2
        const command = process.platform === 'win32' ? 'npm.cmd' : 'npm'  
        await commandSpawn(command,['install'],{ cwd: `./${project}` })
  • 执行 npm run serve命令

    1
    await commandSpawn(command, ['run','serve'],{cwd: `./${project}`})
  • 打开浏览器

    • open()
    • 但是在vue cli 自己打开浏览器是通过webpack 做的 因为它知道启用的哪个端口
  • 实现其他的指令

    • addcpn

      1. 首先要有一个组件的模板 .ejs

        1. ejs的一个语法:<%= %>
      2. 编译ejs模板 result字符串

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        const compile = (tempName,data)=>{
        const templatePosition = `../templates/${tempName}`
        const templatePath = path.resolve(__dirname,templatePosition)

        console.log(templatePath);
        return new Promise((resolve,reject)=>{
        ejs.renderFile(templatePath,{data},{},(err,result)=>{
        if(err){
        console.log(err);
        reject(err);
        return
        }
        resolve(result)
        })
        })
        }
        1
        const result = await compile('vue-component.ejs',{name,lowerName:name.toLowerCase()})
      3. 将result写入到.vue 文件

        1
        2
        3
        4
        5
        6
        7
        8
        9
        program
        .command('addcpn <name>')
        .description('add vue component , 例如:hype addcpn HelloHype -d src/components')
        .action((name)=>{ 敲完指令执行的action
        addCpnAction(name,program.dest || 'src/components') ->dest出处
        })

        const targetPath = path.resolve(dest,`${name}.vue`)
        writeTofile( targetPath,result)
      4. 放到对应的文件夹

    • addcpn的逻辑

  • addpage

    1
    2
    3
    4
    5
    6
    program
    .command('addpage <page>')
    .description('add vue page and router config, 例如: hype addpage Home [-d src/pages]')
    .action((page) => {
    addPageAndRouteAction(page, program.dest || 'src/pages')
    })
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    //添加组件 路由
    const addPageAndRouteAction = async (name, dest) => {
    // 1.编译ejs模板
    const data = {name, lowerName: name.toLowerCase()};
    const pageResult = await compile('vue-component.ejs', data);
    const routeResult = await compile('vue-router.ejs', data);

    // 3.写入文件
    const targetDest = path.resolve(dest, name.toLowerCase());
    if (createDirSync(targetDest)) {
    const targetPagePath = path.resolve(targetDest, `${name}.vue`);
    const targetRoutePath = path.resolve(targetDest, 'router.js')
    writeToFile(targetPagePath, pageResult);
    writeToFile(targetRoutePath, routeResult);
    }
    }
    • 生成路径方法createDirSync

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      const createDirSync = (pathName) => {
      if (fs.existsSync(pathName)) {
      return true;
      } else {
      if (createDirSync(path.dirname(pathName))) {
      fs.mkdirSync(pathName);
      return true;
      }
      }
      }
    • 写入文件方法writeToFile

      1
      2
      3
      4
      const writeToFile = (path, content) => {
      // 判断path是否存在, 如果不存在, 创建对应的文件夹
      return fs.promises.writeFile(path, content);
      }
  • addstore与addpage类似

项目发布

  • 在npm网站创建账号
  • npm login 登陆
  • npm publish 发布
  • 更新的话更新package.json中的版本号
  • 然后npm install -g coderhyp

  • 就可以使用啦