作前端也有三四年了,本身帶了個五人前端小團隊,第一次寫腳手架,也是第一次寫分享文章。文筆太差,勿噴、勿噴、勿噴 每次人肉搬運代碼的時候,就想本身能不能給團隊作一個跟vue-cli同樣的腳手架?想了好久,苦於各類緣由一直沒有實施。 正好最近不忙,此時不搞,更待什麼時候!開搞,網上查文檔,gitHub扒vue-cli的源碼,坑哧吭哧的搗鼓了兩天……成了。拿出來分享一下吧。
這個不難,一張圖歸納,按照提示步驟填寫信息就行了。以下圖,我建立了一個叫template-organization
的組織。前端
組織建立完以後,就能夠在template-organization
這個組織下建立新的倉庫demo-template
vue
重點來了,https://api.github.com/users/...,獲取template-organization這個組織下的全部倉庫信息。node
** 註冊帳號:** [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