有了上一篇文章的的基礎準備知識,下面咱們開始動手作吧vue
mkdir mcf-cli && cd mcf-cli
npm init
複製代碼
此時,你的文件夾下回自動生成一個package.json,裏面的基本信息就是你在終端輸入的基本信息node
此時基本的文件目錄以下webpack
/bin # ------ 命令執行文件
package.json #------ 配置文件
template.json # ------ 模板列表對象
複製代碼
template.json 爲空對象git
{}
複製代碼
#!/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)
複製代碼
version('0.0.1') 版本號;github
usage('') 名字web
command('') 定義子命令;npm
parse(process.argv); 至於末尾,解析命令行輸入的命令;json
其餘的還包括:工具
在 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關聯到node環境中
打開cmd,輸入mcf 回車查看你的mcf是不是你想要的結果
#!/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上只需寫到用戶名/項目名)
#!/usr/bin/env node
const tplObj = require(`${__dirname}/../template`)
console.log(tplObj)
複製代碼
查看當地的模板列表
#!/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腳手架模板列表中刪除你要刪除的模板
#!/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到本地
{
...
"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命令行來得實在