搭建快速启动不同模板的前端脚手架

371 阅读4分钟

在日常开发中,我们会根据公司项目和实际经验沉淀出一些项目模板,来很好的在不同项目中重复使用和快速开发,如果每次都通过拷贝代码的形式到新项目的话,会变得比较麻烦,并且容易增大出错的概率。这时我们就可以搭建一套集成常用模板的前端脚手架,方便我们快速的进行初始化创建。

初始化项目

首先创建一个名为 any-starter-cli 的项目,当然名字可以随意更改,之后在该目录下执行 pnpm init 来初始化 package.json 文件。

pnpm init

安装依赖

初始化完项目之后,继续安装以下依赖,注意:请锁定ora、log-symbols、chalk的版本,因为最新版本只支持ESM

pnpm i chalk commander download-git-repo inquirer ora log-symbols
依赖版本作用
chalk4.1.2控制台输出内容样式
commander9.3.0命令行工具
ownload-git-repo3.0.2下载远程模板
inquirer8.2.4交互式命令行工具
ora3.2.0显示加载动画
log-symbols4.0.0显示出 √ 或 × 等的图标
cli-table0.3.11允许从 node.js 脚本在命令行上呈现 unicode 辅助表

编写代码

在开始编写代码之前,我们需要了解 commander 的用法

  • usage(): 设置 usage 值
  • command(): 定义一个命令名字
  • description(): 描述
  • option(): 定义参数,需要设置“关键字”和“描述”,关键字包括“简写”和“全写”两部分,以 , | 空格 做分隔。
  • parse(): 解析命令行参数 argv
  • action(): 注册一个 callback 函数
  • version(): 终端输出版本号

接着根目录下创建 bin/starter 文件,并写入以下内容

#!/usr/bin/env node
const program = require('commander')

program.usage('<command>')

program.version(require('../package').version)

program
  .command('list')
  .description('List the templateList')
  .action(() => {
    require('../commands/list')
  })

program
  .command('init')
  .description('Init a project')
  .action(() => {
    require('../commands/init')
  })

program.parse(process.argv)

接着,在 package.json 中添加以下命令

"bin": {
  "starter": "bin/starter"
},

此时我们执行 npm link将命令挂载到全局,然后再输入 starter 就可以看到的效果了。

创建模板

为了能让脚手架后续可以下载到对应的模板,我们需在跟根目录下创建 tempalte.json, 并写入以下代码,当然,这些模板可以根据实际情况替换,这里只是为了演示。

{
  "vue-element-plus-admin": "https://github.com:kailong321200875/vue-element-plus-admin#master",
  "webpack-multi-page-cli": "https://github.com:kailong321200875/webpack-multi-page-cli#master"
}

编写指令

编写指令之前,我们需要了解 inquirer 的基本用法

  • type:表示提问的类型,包括:input, confirm, list, rawlist, expand, checkbox, password, editor
  • name: 存储当前问题回答的变量
  • message:问题的描述
  • default:默认值
  • choices:列表选项,在某些 type 下可用,并且包含一个分隔符(separator)
  • validate:对用户的回答进行校验
  • filter:对用户的回答进行过滤处理,返回处理后的值
  • when:根据前面问题的回答,判断当前问题是否需要被回答
  • prefix:修改 message 默认前缀
  • suffix:修改 message 默认后缀

List the templateList

接下来我们编写列举所有项目模板的命令

在根目录下创建 commands/list.js 文件,并写入以下代码

const { showTable } = require(`${__dirname}/../utils/index`)
const templateList = require(`${__dirname}/../template`)

showTable(templateList)

在根目录下创建 utils/index.js 文件,并写入以下代码

const Table = require('cli-table')

const table = new Table({
  head: ['name', 'url'],
  style: {
    head: ['green']
  }
})

function showTable (tempList) {
  const list = Object.keys(tempList)
  if (list.length > 0) {
    list.forEach((key) => {
      table.push([key, tempList[key]])
      if (table.length === list.length) {
        console.log(table.toString())
        process.exit()
      }
    })
  } else {
    console.log(table.toString())
    process.exit()
  }
}

exports.showTable = showTable

配置完之后重新运行 npm link, 然后执行 starter list 命令即可查看效果

image.png

Init a project

接着需要配置 init 指令,用于选择初始化的模板

commands 下创建 init.js 文件,并写入以下代码

const ora = require('ora')
const download = require('download-git-repo')
const templateList = require('../template.json')
const symbols = require('log-symbols')
const chalk = require('chalk')
const inquirer = require('inquirer')

inquirer
  .prompt([
    {
      type: 'rawlist',
      message:'请选择初始化项目模板',
      name:'template',
      choices: Object.keys(templateList)
    }
  ])
  .then(answers => {
    const templateName = answers.template
    const url = templateList[templateName]
    console.log(chalk.green('\n Start generating... \n'))
    // 出现加载图标
    const spinner = ora("Downloading...")
    spinner.start()
    download(
      `${url}`,
      `./${templateName}`,
      err => {
        if (err) {
          spinner.fail()
          console.log(chalk.red(symbols.error), chalk.red(`Generation failed. ${err}`))
          return
        }
        // 结束加载图标
        spinner.succeed()
        console.log(chalk.green(symbols.success), chalk.green('Generation completed!'))
        console.log('\n To get started')
        console.log(`\n    cd ${templateName} \n`)
      }
    )
  })
  .catch(error => {
    console.log(error)
    process.exit()
  })

到这里,我们就完成了一个快速启动不同模板的前端脚手架,后续就可以直接 npm publish 上传到 npm 上。

上传成功之后,全局安装 pnpm add any-starter-cli -g

之后执行 starter -h,出现以下提示就代表发布成功

image.png

最后,就可以使用 starter init 初始化想要的模板了

结语

当我们项目启动模板越来越多时,提供一个快速初始化的脚手架,更方便也更不容易出错。

文章中的源码地址:any-starter-cli