從0到1創建屬於本身的腳手架二

有了上一篇文章的的基礎準備知識,下面咱們開始動手作吧vue

建立你的腳手架文件夾及名稱

mkdir mcf-cli  && cd mcf-cli

npm init
複製代碼

此時,你的文件夾下回自動生成一個package.json,裏面的基本信息就是你在終端輸入的基本信息node

建立bin文件夾和tempalte.json

此時基本的文件目錄以下webpack

/bin  # ------ 命令執行文件
package.json  #------ 配置文件
template.json  # ------ 模板列表對象
複製代碼

template.json 爲空對象git

{}
複製代碼

在bin目錄下建立mcf

#!/usr/bin/env node  
//定義執行解釋器
const program = require('commander')
const chalk = require('chalk')
console.log('**********************************************************************');
console.log('*      '+chalk.red('mcf-cli(閔長峯腳手架) 爲本身寫的一個腳手架工具:')+'               *');
console.log('*      '+chalk.green('一、讓項目從"搭建-開發-部署"更加快速以及規範')+'                   *');
console.log('*      '+chalk.green('二、避免建立項目時手動複製不全的尷尬')+'                           *');
console.log('*      '+chalk.green('三、多瞭解點原理,多學點東西老是好的')+'                           *');
console.log('**********************************************************************');
program
  .version(require('../package').version)
  .usage('<command> [options]')
  .command('add', '添加新的源 mcf add')
  .command('delete', '刪除源 mcf list')
  .command('list', '展現源列表 mcf list')
  .command('init', '從源初始化項目 mcf init <模板名> 項目名')
  .command('create-vue', '快速構建新vue項目 mcf create-vue <項目名>')

program.parse(process.argv)
複製代碼
  1. version('0.0.1') 版本號;github

  2. usage('') 名字web

  3. command('') 定義子命令;npm

  4. parse(process.argv); 至於末尾,解析命令行輸入的命令;json

其餘的還包括:工具

  1. description(‘hello ,I\’m zhao’) 描述
  2. allowUnknownOption 取消接收到未定義option時報錯的機制,不報錯;
  3. alias(‘a’) 定義子命令的短命令;
  4. action(cb) 回調
  5. option(‘-p, –peppers’,’Add oeooers’) 自定義選項參數和描述

將mcf命令行配置到package中

在 package.json中,添加bin屬性ui

{
    "bin":{
        "mcf":"bin/mcf"
    }
    ...
    "dependencies": {
    "commander": "^2.19.0",
    "metalsmith": "^2.3.0",
    "download-git-repo": "^1.1.0",
    "inquirer": "^6.2.2",
    "ora": "^3.2.0",
    "chalk": "^2.4.2",
    "latest-version": "^3.1.0",
    "log-symbols": "^2.2.0",
    "glob": "^7.1.2",
    "handlebars": "^4.0.11"
  }
  ...
}
複製代碼

npm link

將當前開發的npm關聯到node環境中

打開cmd,輸入mcf 回車查看你的mcf是不是你想要的結果

QQ截圖20191009144638.png

依次建立mcf-add、mcf-init、mcf-list、mcf-delete

mcf-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 name 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('O(∩_∩)~ Added successfully!\n'))
      console.log(chalk.grey('The latest template list is: \n'))
      console.log(tplObj)
      console.log('\n')
    })
  })
複製代碼

mcf-add命令行的做用主要在於,添加一個模板到腳手架本地庫中,輸入用模板名以及模板對應的url(github上只需寫到用戶名/項目名)

mcf-list文件

#!/usr/bin/env node

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

查看當地的模板列表

mcf-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 => {
    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')
    })
  })
複製代碼

mcf-delete <模板名>

從本地mcf腳手架模板列表中刪除你要刪除的模板

mcf-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`)
  }
)
複製代碼

mcf-init <模板名> <項目名>

將模板copy到本地

添加進package.json

{
    ...
    "bin":{
        "mcf-add": "bin/mcf-add",
        "mcf-delete": "bin/mcf-delete",
        "mcf-list": "bin/mcf-list",
        "mcf-init": "bin/mcf-init",
    }
    ...
}
複製代碼

總結

到這裏你會發現,其實這只是基礎的git clone的方法,你也許會說,寫這麼多,還不如我以一句git clone命令行來得實在

相關文章
相關標籤/搜索