如何本身搭一個腳手架

前言

作前端也有三四年了,本身帶了個五人前端小團隊,第一次寫腳手架,也是第一次寫分享文章。文筆太差,勿噴、勿噴、勿噴    
每次人肉搬運代碼的時候,就想本身能不能給團隊作一個跟vue-cli同樣的腳手架?想了好久,苦於各類緣由一直沒有實施。
正好最近不忙,此時不搞,更待什麼時候!開搞,網上查文檔,gitHub扒vue-cli的源碼,坑哧吭哧的搗鼓了兩天……成了。拿出來分享一下吧。

準備工做

1、gitHub新建組織和倉庫

這個不難,一張圖歸納,按照提示步驟填寫信息就行了。以下圖,我建立了一個叫template-organization的組織。前端

clipboard.png

組織建立完以後,就能夠在template-organization這個組織下建立新的倉庫demo-templatevue

clipboard.png

clipboard.png

重點來了,https://api.github.com/users/...,獲取template-organization這個組織下的全部倉庫信息。node

2、npm帳號

** 註冊帳號:** 
    [https://www.npmjs.com/][2]
** 登陸: ** 
    npm login
** 添加用戶信息到註冊表 ** 
    npm adduser

主體內容

寫代碼

準備工做作齊了,開始coding……git

打開終端,初始化項目
$ `mkdir edu-test-cli`
$ `cd edu-test-cli/`
$ `npm init`
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (edu-test-cli) 
version: (1.0.0) 
description: 這個是一個簡單的腳手架
entry point: (index.js) 
test command: 
git repository: 
keywords: cli edu zhx
author: 張鑫
license: (ISC) MIT
About to write to /Users/zhangxin/study/edu-test-cli/package.json:

{
  "name": "edu-test-cli",
  "version": "1.0.0",
  "description": "這個是一個簡單的腳手架",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "cli",
    "edu",
    "zhx"
  ],
  "author": "張鑫",
  "license": "MIT"
}


Is this ok? (yes) yes

項目的package.json結構就基本出來了。github

加入依賴的包
npm i chalk commander download-git-repo inquirer ora request --save
修改package.json中配置,以下
{
  "name": "edu-test-cli",
  "version": "1.0.0",
  "description": "這個是一個簡單的腳手架",
  "preferGlobal": true,
  "bin": {
    "edu": "bin/edu"
  },
  "dependencies": {
    "chalk": "^1.1.3",
    "commander": "^2.9.0",
    "download-git-repo": "^1.1.0",
    "inquirer": "^6.2.0",
    "ora": "^3.0.0",
    "request": "^2.88.0"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "cli",
    "edu",
    "zhx"
  ],
  "author": "張鑫",
  "license": "MIT"
}
項目結構,以下
>edu-test-cli
    |--bin
       |--edu
    |--lib
       |--list.js
       |--init.js
    |--package.json
    |--README.md
在bin目錄下新建 edu (沒有後綴),代碼以下
#!/usr/bin/env node
process.env.NODE_PATH = __dirname + '/../node_modules/'

const program = require('commander')

program
  .version(require('../package.json').version)
  .usage('<command> [options]')
program
  .command('list')
  .description('查看全部的模版')
  .alias('l')
  .action(() => {
    require('../lib/list')()
  })
program
  .command('init')
  .description('生成一個新項目')
  .alias('i')
  .action(() => {
    require('../lib/init')()
  })
program
  .parse(process.argv)

if(!program.args.length){
  program.help()
}
lib目錄下 init.js,代碼以下
const ora = require('ora')
const inquirer = require('inquirer')
const chalk = require('chalk')
const request = require('request')
const download = require('download-git-repo')

module.exports = () => {
  request({
    url: 'https://api.github.com/users/template-organization/repos',
    headers: {
      'User-Agent': 'edu-test-cli'
    }
  }, (err, res, body) =>{
    if (err) {
      console.log(chalk.red('查詢模版列表失敗'))
      console.log(chalk.red(err))
      process.exit();
    }

    const requestBody = JSON.parse(body)
    if (Array.isArray(requestBody)) {
      let tplNames = [];
      requestBody.forEach(repo => {
        tplNames.push(repo.name);
      })

      let promptList = [
        {
          type: 'list',
          message: '請選擇模版',
          name: 'tplName',
          choices: tplNames
        },
        {
          type: 'input',
          message: '請輸入項目名字',
          name: 'projectName',
          validate (val) {
            if (val !== '') {
              return true
            }
            return '項目名稱不能爲空'
          }
        }
      ]
      inquirer.prompt(promptList).then(answers => {

        let ind = requestBody.find(function (ele) {
          return answers.tplName == ele.name;
        });
        let gitUrl = `${ind.full_name}#${ind.default_branch}`,
          defaultUrl = './',
          projectUrl = `${defaultUrl}/${answers.projectName}`,
          spinner = ora('\n 開始生成項目,請等待...');
          spinner.start();
        download(gitUrl, projectUrl, (error)=>{
          spinner.stop();
          if (error) {
            console.log('模版下載失敗……')
            console.log(error)
            process.exit()
          }
          console.log(chalk.green(`\n √ ${answers.projectName} 項目生成完畢!`))
          console.log(`\n cd ${answers.projectName} && npm install \n`)
        })
      })
    } else {
      console.error(requestBody.message)
    }
  })
}
lib目錄下的 list.js,代碼以下:
const request = require('request');
const chalk = require('chalk')
const ora = require('ora')
module.exports = () => {
  let spinner = ora('\n ' + chalk.yellow('正在查詢模版列表,請等待...'));
  spinner.start();
  request({
    url: 'https://api.github.com/users/template-organization/repos',
    headers: {
      'User-Agent': 'edu-test-cli'
    }
  }, (err, res, body) => {
    spinner.stop();
    if (err) {
      console.log(chalk.red('查詢模版列表失敗'))
      console.log(chalk.red(err))
      process.exit();
    }
    const requestBody = JSON.parse(body)
    if (Array.isArray(requestBody)) {
      console.log()
      console.log(chalk.green('可用的模版列表:'))
      console.log()
      requestBody.forEach(repo => {
        console.log(
        '  ' + chalk.yellow('★') +
        '  ' + chalk.blue(repo.name) +
        ' - ' + repo.description)
      })
    } else {
      console.error(requestBody.message)
    }
  })
}

到這裏這個簡單的腳手架就開發完了。代碼都在這裏,是否是很簡單呢?vue-cli

開發、測試、發佈

開發時,可以使用如下命令查看效果
node bin/edu list   查看全部可用的模版
node bin/edu init   把模版下載下來,做爲初始項目進行開發
測試時,如何使用全局的 edu list/init 的命令呢?
npm link    ///只能本身本地使用。
開發、測試完成,發佈
npm publish  ///將包發佈到npm上,全部人均可以安裝使用。

例子:
edu-test-cli> $ npm publish
+ edu-test-cli@1.1.0

使用方法

安裝
npm install -g edu-test-cli
查看模版列表
$ edu list

可用的模版列表:

  ★  demo-template - 這是一個關於移動端適配方案的示例項目。
建立項目
$ edu init
? 請選擇模版 (Use arrow keys)
❯ demo-template 
  
? 請輸入項目名字

結尾

終於寫完了。寫文章比寫代碼還累。。。。。。npm

相關文章
相關標籤/搜索