[ 记录 ]nodeJs实现一个自定义脚手架工具

219 阅读2分钟

废话不多说, 直接上干货,

实现过程

  • 1、 新建一个文件夹 gkm_node, yarn init 初始化package.json
  • 2、 package.json中新增 "bin": "cli.js"并在同级目录中新建cli.js 文件
  • 3、 安装 inquirer, ejs 依赖; (npm install inquirer / yarn add inquirer)
  • 4、 编辑cli.js
    • 4.1、 写入文件头 #!/usr/bin/env node
    • 4.2、 mac通过 sudo chmod 755 cli.js修改文件读写权限为 755
    • 4.3、 引入 inquirer ( 一个用户与命令行交互的工具 ), 并书写代码
    // prompt 接收一个数组, 数组中是每一个问题配置对象
    inquirer.prompt([
      {
        type: 'input', // 用户输入的方式
        name: 'name', // 接收输入的键
        message: 'your project name' // 界面上显示的问题
      }
    ])
    .then(anwser => {
      // anwser 返回的结果
    })
    
    • 4.4、 在cli.js同级添加 templates 目录, 这个目录里面结构是我们想要脚手架自动生成的项目结构. 这里我们就简单添加了index.html index.css index.js 三个文件 index.html 页面修改title 为 ejs模版动态渲染 (<%= name %>)
    • 4.5、 cli.js文件内处理返回结果 声明模版目录 const tmplDir = path.join(__dirname, 'templates')
    • 4.6、 声明目标目录(当前执行命令的目录) const destDir = process.cwd()
    • 4.7、 将模版目录全部转换到目标目录
    fs.readdir(tmplDir, (err, files) => {
      if (err) throw err
      files.forEach(file => {
        // 通过模版引擎渲染文件
        ejs.renderFile(path.join(tmplDir, file), anwsers, (err, result) => {
          if (err) throw err
          fs.writeFileSync(path.join(destDir, file), result)
        })
      })
    })
    
  • 5、 代码书写完成, 使用yarn link方式放在yarn 全局内存里, 这样我们就可以在本地任何目录使用这个脚手架工具了.我们也可以通过上传npm 通过包形式就可以实现vue-cli一类的功能了.

注意:

1、 index.html内的 title 中的 name 是指 inquirer.prompt 接收数组item中接收输入的变量

2、 yarn link 不成功时请检查文件头 #!/usr/bin/env node 这里是 usr, 不是 user(别问我为什么要写这一点)

最后附上部分代码

cli.js

#!/usr/bin/env node

// Node CLI 应用入口文件必须要有这样的文件头
// 如果是 Linux 或者 macOS 系统下还需要修改此文件的读写权限为 755
// 具体就是通过 sudo chmod 755 文件名(cli.js) 实现修改

const inquirer = require('inquirer')
const path = require('path')
const fs = require('fs')
const ejs = require('ejs')

// 脚手架的工作过程:
// 1. 通过命令行交互询问用户问题
// 2. 根据用户回答的结果生成文件

inquirer.prompt([
  {
    type: 'input',
    name: 'name',
    message: 'your project name'
  }
])
  .then(anwsers => {
    console.log(anwsers)
    // 根据用户的回答生成文件

    // 模版目录
    const tmplDir = path.join(__dirname, 'templates')
    // 目标目录  当前命令执行的目录
    const destDir = process.cwd()

    // 将模版下的文件全部转换到目标目录
    fs.readdir(tmplDir, (err, files) => {
      if (err) throw err
      files.forEach(file => {
        // 通过模版引擎渲染文件
        ejs.renderFile(path.join(tmplDir, file), anwsers, (err, result) => {
          if (err) throw err
          fs.writeFileSync(path.join(destDir, file), result)
        })
      })
    })
  })

1641453321676.jpg

这个只是一个开始, 后续我们可以把代码检测, webpack通用配置一些东西集成进去,打造属于我们自己的cli工具.