參考
我們無(wú)論是使用react 還是 vue,都會(huì)找到相關(guān)的腳手架工具,比如 react 的 create-react-app,vue的 vue-cli。我們可以非常方便的初始化一個(gè)項(xiàng)目,不用太去關(guān)心什么 webpack 配置啊,babel 配置之類的。今天搭了一個(gè)類似 vue-cli 的腳手架,記錄一下搭建腳手架的詳細(xì)過(guò)程。
簡(jiǎn)單來(lái)說(shuō),就是讓用戶選擇,根據(jù)選擇的內(nèi)容從 GitHub 上下載相應(yīng)的模板。可能后面還要做根據(jù)用戶填寫的內(nèi)容修改模板,發(fā)布到 npm。這篇文章主要詳細(xì)講從 GitHub 上下載模板。
新建項(xiàng)目
首先新建一個(gè)項(xiàng)目,在新項(xiàng)目中執(zhí)行npm init
,暫時(shí)都使用默認(rèn)配置。到這里會(huì)生成一個(gè) package.json 的文件。在里面添加如下內(nèi)容:
"bin": {
" cli": "./command.js"
},
cli 就是使用腳手架的命令,后面的文件則是要執(zhí)行的文件。
入口文件 - command.js
在項(xiàng)目創(chuàng)建 command.js 文件 開頭必須是 #! /usr/bin/env node
,然后添加一條 log
現(xiàn)在,在終端項(xiàng)目文件夾下執(zhí)行npm link
,即可在該目錄下使用cli 命令,你會(huì)看到在終端打印了
命令
我們?cè)诮K端輸入 node -v
時(shí)會(huì)打印出 node 的版本號(hào)。這是怎么做到的呢?我們可以 用 commander來(lái)實(shí)現(xiàn)。首先安裝](https://github.com/tj/commander.js)來(lái)實(shí)現(xiàn)。首先安裝) npm install commander
。在 command.js 中添加:
<pre style="margin: 8px 0px; background-color: rgb(38, 40, 51); color: rgb(193, 199, 221); font-size: 0.871rem;">const commander = require('commander'); commander.version('1.0.0') commander
.command('init')
.description('init extension project')
.action(() => {
console.log('init a project')
}) commander.parse(process.argv)</pre>
現(xiàn)在就可以通過(guò)cli -V
查看版本,cli -h
查看幫助,cli init
執(zhí)行相應(yīng)的命令了。
在終端與用戶交互,獲取輸入信息
接下來(lái)使用 inquirer 在終端中與用戶交互,獲取信息。首先,安裝 inquirer npm install inquirer
。然后在 init 命令 action 中添加:
const questions = [
{
type: 'input',
name: 'projectName',
message: 'Please input your project name',
filter: function(val) {
return val;
}
},
{
type: 'list',
name: 'type',
message: 'What type do you need?',
choices: [ 'frontend', 'backend' ],
filter: function(val) {
return val.toLowerCase();
}
}
]
.action(() => {
inquirer.prompt(questions).then(answers => {
const { projectName, type } = answers
console.log(projectName)
console.log(type)
})
answers 就是用戶輸入的內(nèi)容對(duì)象。至此,我們拿到了用戶的輸入,可進(jìn)行下一步操作。
根據(jù)用戶輸入下載對(duì)應(yīng)的模板
模板的準(zhǔn)備就不再贅述,本文只說(shuō)到下載模板文件,不涉及修改。模板文件可以用download-git-repo下載,并且支持 GitHub、gitlab、bitbucket,詳見(jiàn)其文檔。本文將模板文件放在了 github。
.action(() => {
inquirer.prompt(questions).then(answers => {
const { projectName, type } = answers
download(`xxx/${type}`, projectName, { clone: true }, function(err) {
if (err) {
console.log('err')
} else {
const startCmd = projectName === 'frontend' ? 'npm start' : 'npm run dev'
conso.log(chalk.white('please run '), chalk.bgBlue(`cd ${projectName} && npm i && ${startCmd}`), chalk.white('to start it'))
}
})
});
})
chalk是一個(gè)日志的樣式庫(kù),可以在終端上面調(diào)整日志的樣式。這里只是給打印的信息添加一個(gè)顏色。
到這里,基本上已經(jīng)完成主要功能了。
添加一個(gè) loading 效果
接下來(lái),要在clone 代碼時(shí)展示一個(gè) loading 的動(dòng)畫,提示用戶。用到了ora,可以在終端實(shí)現(xiàn)Loading的效果。
.action(() => {
inquirer.prompt(questions).then(answers => {
const { projectName, type } = answers
spinner.color = 'green';
spinner.text = 'downloading template……';
spinner.start()
download(`xxx/${type}`, projectName, { clone: true }, function(err) {
if (err) {
spinner.text = `Error: ${err}`;
spinner.fail()
} else {
const startCmd = projectName === 'frontend' ? 'npm start' : 'npm run dev'
spinner.text = 'download success!';
spinner.succeed()
log(chalk.white('please run '), chalk.bgBlue(`cd ${projectName} && npm i && ${startCmd}`), chalk.white('to start it'))
spinner.stop()
}
})
});
})
到這里,就完成了所有的功能。
后續(xù)內(nèi)容:
根據(jù)用戶輸入修改模板文件
發(fā)布到 npm