二、Node脚手架篇、打造自己的脚手架

167 阅读3分钟

1.自定义脚手架概述

1.全局命令行工具
2.创建项目初始化代码文件及目录

脚手架基本能力有哪些?
    1.全局命令行执行能力
    2.命令行交互能力(比如说会询问你的项目名,需要哪个版本等等..)
    3.初始化下载代码的能力
如何实现自己的一个脚手架工具?
    1.创建自定义全局命令
    2.命令行参数接收处理
    3.终端交互
  • 可以浅试一下通过vite创建vue项目
npm i -g create-vite-app  // 全局安装vite脚手架工具
create-vite-app  vite-project(项目名自定义)

1d4a16546a08f62b240541f83213706.png

2.创建自定义全局指令

1.在你的项目目录中新建一个文件夹bin/vite.js
2.然后在项目目录下执行 npm init
{
  "name": "my-vite",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  // 会生成一个这样的命令
  "bin": {
    "my-vite": "bin/vite.js"
  }
}
3.执行npm link(挂载的意思)  就可以把我们当前的命令(my-vite)挂载到全局命令行工具当中
4.然后就可以在任意项目下执行my-vite
5.那么如何获取到命令行的交互参数?
    1.在vite.js中 
    #! /usr/bin/env node
    if (process.argv[2] === '--help') {
        console.log('我获取到了命令行参数');
    }
    console.log('my-vite');
    console.log(process.argv); // [
      'D:\\node\\node.exe',
      'C:\\Users\\fllni\\AppData\\Roaming\\npm\\node_modules\\my-vite\\bin\\vite.js',
      '--help'
    ]

5194c5e10127b8eec3190c13652e001.png

3.使用commander命令参数处理工具

使用方式2: www.npmjs.com/package/com…

    npm i commander
        const { program } = require('commander');
        program
            // <> 意思就是如果使用了-f 那么后面必须要跟对应的参数  否则会报错
            // 第二个参数表示对此命令的描述
          .option('-f --first <first>', 'First'); 
          .option('-s, --separator <char>');
    program.parse(process.argv);  // 命令行所有的参数选项

1b796f176deb852c928a19c8d64d665.png

4.处理自定义指令选项

const {program} = require('commander')
program.option('-f --framwork <framwork>','设置框架')
program
.command('create <project> [other...]') // 命令选项
.alias('crt')            // 给命令选项别名
.description('创建项目')  // 描述
.action((project,args)=>{
  // 命令行的执行逻辑代码
  console.log(project);
  console.log(args);
})

program.parse(process.argv)

5.逻辑代码,模块化拆分

  • 新建一个文件夹 lib/core(核心代码)
  • 将自定义指令选项进行抽离以模块化的方式展现
const myaction = require('./action')
const mycommander = function (program) {
  program
    .command('create <project> [other...]')
    .alias('crt')
    .description('创建项目')
    .action(myaction)
}

module.exports = mycommander

6.命令行问答交互

  • 安装问答交互工具 npm i inquirer
  • 配置文件 config
module.exports = {
  // 可选择的框架
  framwork:['express', 'koa', 'egg'],
  // 框架对应的下载地址
  foramworkUrl:{
    express:'git@gitee.com:beiyaoyaoyao/express-template.git',
    koa:'git@gitee.com:beiyaoyaoyao/koa-template.git',
    egg:'git@gitee.com:beiyaoyaoyao/egg-template.git'
  }
}
  • 命令行执行逻辑
var inquirer = require('inquirer')
var config = require('../../config')

const myAction = async (project, args) => {
  const answer = await inquirer.prompt([
    {
      type: 'list',
      name: 'framwork',
      choices: config.framwork,
      message: '请选择你所使用的框架'
    }
  ])
  // console.log(answer);
}

module.exports = myAction

7.下载远程仓库模板代码

需要工具

  • npm i download-git-repo
  • npm i ora // 交互提示
  • npm i chalk // 命令行样式渲染输出
  1. 下载
  2. 下载过程交互提示
  3. 命令行样式输出
const download = require('download-git-repo')
const ora = require('ora')
const chalk = require('chalk')
const downloadFun = function (url, project) {
  const spinner = ora().start()
  spinner.text = '代码正在下载……'
  download('direct:' + url, project, { clone: true }, (err) => {
    if (!err) {
      spinner.succeed('代码下载成功')
      console.log(chalk.blue.bold('Done!'), chalk.bold('you run:'));
      console.log('cd ' + project);
      console.log('npm install ');
      console.log('npm run dev ');
    } else {
      spinner.fail('代码下载失败')
    }
  })
}
module.exports = downloadFun

// 命令行触发执行逻辑
var inquirer = require('inquirer')
var config = require('../../config')
var downloadFun = require('./download')
const myAction = async (project, args) => {
  // 命令行的执行逻辑代码
  // console.log(project);
  // console.log(args);
  // express koa egg 
  const answer = await inquirer.prompt([
    {
      type: 'list',
      name: 'framwork',
      choices: config.framwork,
      message: '请选择你所使用的框架'
    }
  ])
  // console.log(answer);
  // 下载代码模板
  downloadFun(config.foramworkUrl[answer.framwork],project)
}
module.exports = myAction

8.自定脚手架项目总结

  • 全局命令行工具
  • 命令参数接收处理
  • 终端交互
  • 下载远程仓库代码
  • 项目初始化完成提示