腳手架
搭建腳手架的目的就是快速的搭建項(xiàng)目的基本結(jié)構(gòu)并提供項(xiàng)目規(guī)范和約定啼县。目前日常工作中常用的腳手架有 vue-cli甘邀、create-react-app伟骨、angular-cli 等等仔夺,都是通過(guò)簡(jiǎn)單的初始化命令咆畏,完成內(nèi)容的快速構(gòu)建南捂。
其實(shí)我們也可以用git clone url來(lái)新建(復(fù)制)項(xiàng)目,再 low 一點(diǎn)的方法就是復(fù)制粘貼整個(gè)文件夾旧找,一樣也能達(dá)到初始化的目的溺健。
腳手架的本質(zhì)也是從遠(yuǎn)程下載一個(gè)模板來(lái)進(jìn)行一個(gè)新項(xiàng)目,但是腳手架可是高級(jí)版的克隆钮蛛,它主要是提供了交互式的命令讓我們可以動(dòng)態(tài)的更改模板鞭缭,然后用一句命令就可以實(shí)現(xiàn)其他內(nèi)置依賴的初始化,方便了多人協(xié)作,不需要將文件傳來(lái)傳去魏颓。
接下來(lái)我們就開始實(shí)現(xiàn)一個(gè)簡(jiǎn)易版的腳手架heaven-cli(可自行命名)岭辣,目標(biāo)是實(shí)現(xiàn)一個(gè)heaven init template-name project-name這樣的命令,廢話少說(shuō)甸饱,開始進(jìn)入正題吧沦童!
前置知識(shí)了解
其實(shí)一個(gè)簡(jiǎn)易版的 heaven-cli的代碼量并不多,所以這里我們先來(lái)介紹一下其中要使用到的第三方庫(kù)
commander
這是用來(lái)編寫指令和處理命令行的,用法如下:
const program = require("commander");
// 定義指令
program
.version('0.0.1')
.command('init', 'Generate a new project from a template')
.action(() => {
// 回調(diào)函數(shù)
})
// 解析命令行參數(shù)
program.parse(process.argv);
復(fù)制代碼
inquirer
這是個(gè)強(qiáng)大的交互式命令行工具搞动,用法如下:
const inquirer = require('inquirer');
inquirer
.prompt([
// 一些交互式的問(wèn)題
])
.then(answers => {
// 回調(diào)函數(shù)躏精,answers 就是用戶輸入的內(nèi)容,是個(gè)對(duì)象
});
復(fù)制代碼
chalk
這是用來(lái)修改控制臺(tái)輸出內(nèi)容樣式的鹦肿,起到了美化輸出內(nèi)容的作用矗烛,用法如下:
const chalk = require('chalk');
console.log(chalk.green('success'));
console.log(chalk.red('error'));
復(fù)制代碼
ora
這是一個(gè)好看的加載交互組件,用于下載過(guò)程中的loading效果箩溃,用法如下:
const ora = require('ora')
let spinner = ora('downloading template ...')
spinner.start()
復(fù)制代碼
download-git-repo
用于下載遠(yuǎn)程模板的瞭吃,支持 GitHub、 GitLab 和 Bitbucket 等涣旨,用法如下:
const download = require('download-git-repo')
download(repository, destination, options, callback)
復(fù)制代碼
其中 repository 是遠(yuǎn)程倉(cāng)庫(kù)地址歪架;destination 是存放下載的文件路徑,也可以直接寫文件名霹陡,默認(rèn)就是當(dāng)前目錄和蚪;options 是一些選項(xiàng),比如{ clone:boolean }表示用 http download 還是 git clone 的形式下載烹棉。
初始化目錄
首先我們先創(chuàng)建一個(gè)空文件夾攒霹,取名 heaven-cli;
目錄結(jié)構(gòu)
├── bin //可執(zhí)行文件
└── lib
├── init.js //init command
├── template
└── index.js //內(nèi)置的所有模版
└── utils
└── utils.js // 公共方法
├── package.json
├── README.md
復(fù)制代碼
在該目錄下執(zhí)行npm init命令浆洗,進(jìn)行初始化催束。
安裝依賴
npm install chalk commander inquirer ora download-git-repo
復(fù)制代碼
我這邊的package.json的依賴是這樣的
"dependencies": {
"chalk": "^4.1.2",
"commander": "^8.3.0",
"download-git-repo": "^3.0.2",
"inquirer": "^8.1.2",
"ora": "^5.4.1"
}
復(fù)制代碼
node.js 內(nèi)置了對(duì)命令行操作的支持,package.json 中的 bin 字段可以定義命令名和關(guān)聯(lián)的執(zhí)行文件伏社。在 package.json 中添加 bin 字段
"bin": {
"heaven": "bin/heaven.js"
},
復(fù)制代碼
bin 目錄下新建一個(gè)heaven.js抠刺,并在行首加入一行 #!/usr/bin/env node 指定當(dāng)前腳本由node.js進(jìn)行解析
#!/usr/bin/env node
const program = require('commander')
const init = require("../lib/init");
program
.command('init <template> <app-name>')
.description('generate a project from a remote template (legacy API, requires @heaven-cli)')
.action((template, name) => {
init(template, name)
})
// 解析命令行參數(shù)
program.parse(process.argv)
復(fù)制代碼
這個(gè)文件的主要作用就是定義指令,我們用node ./bin/heaven運(yùn)行一下摘昌,就能看到運(yùn)行結(jié)果了速妖,
當(dāng)然,在開發(fā)過(guò)程中為了方便調(diào)試第焰,在當(dāng)前的 heaven-cli 目錄下執(zhí)行 npm link买优,將 heaven 命令鏈接到全局環(huán)境,
這樣我們每次只要輸入heaven挺举,就可以直接運(yùn)行了。
后面就可以編寫 /lib/init.js的代碼了
// 交互式命令行
const inquirer = require('inquirer')
// 修改控制臺(tái)字符串的樣式
const chalk = require('chalk')
// node 內(nèi)置文件模塊
const fs = require('fs')
// 讀取template下內(nèi)置的模版
const tplObj = require("./template")
// 下載
const download = require("download-git-repo");
// 自定義交互式命令行的問(wèn)題及簡(jiǎn)單的校驗(yàn)
let question = [
{
name: "name",
type: 'input',
message: "Project name (" + name + ')',
validate (val) {
if (val === '') {
return 'Name is required!'
} else {
return true
}
}
},
{
name: "description",
type: 'input',
message: "Project description"
},
]
inquirer
.prompt(question).then(answers => {
// answers 就是用戶輸入的內(nèi)容烘跺,是個(gè)對(duì)象
let {
description
} = answers;
let projectName = answers.name
// 出現(xiàn)加載圖標(biāo)
const spinner = ora("Downloading...");
const url = tplObj.template[template]
// 執(zhí)行下載方法并傳入?yún)?shù)
download(
url,
projectName,
err => {
if (err) {
spinner.fail();
console.log(chalk.red(`Generation failed. ${err}`))
return
}
// 將用戶輸入的內(nèi)容湘纵,寫入package.json內(nèi)
const packageFile = path.join(process.cwd(), projectName + '/package.json');
const package = require(packageFile);
package.description = description;
package.name = projectName;
fs.writeFileSync(file, `module.exports = ${JSON.stringify(package, null, '\t')};`, 'utf8');
// 結(jié)束加載圖標(biāo)
spinner.succeed();
console.log(chalk.green('\n Generation completed!'))
console.log('\n To get started')
console.log(`\n cd ${projectName} \n`)
}
)
})
復(fù)制代碼
至此,一個(gè)小小的腳手架就做完了滤淳。
接下來(lái)就測(cè)試一下heaven init vue my-project命令能否生效
很快就可以看到已經(jīng)成功初始化了my-project梧喷,此時(shí)可以看一下my-project文件夾下面
發(fā)布到 npm
既然以上命令可以執(zhí)行成功了,那接下來(lái)我們就把它發(fā)布到 npm 上吧,其它用戶就可以通過(guò) npm install heaven-cli-fe -g 全局安裝铺敌。 即可使用 heaven 命令汇歹。
可使用 template 包含如下
- vue
- vue-seo
- koa-react
- koa-vue
- microservice
vue
- vue-cli,webpack5.28版本
vue-seo (開發(fā)中)
- 基于vue-cli搭建的偽ssr腳手架偿凭,webpack5.28版本产弹,打包生成對(duì)應(yīng)的靜態(tài)html,并跳轉(zhuǎn)到真實(shí)網(wǎng)址弯囊,用于seo搜索痰哨。
koa-react
- koa+react 工程項(xiàng)目骨架,ssr模式匾嘱,支持mysql和mongodb數(shù)據(jù)庫(kù)
koa-vue
- koa+vue 工程項(xiàng)目骨架 mvc結(jié)構(gòu)斤斧, 前端vue單頁(yè)面應(yīng)用
microservice (開發(fā)中)
- 基于vite搭建微前端腳手架
原文鏈接:如何搭建一個(gè)自己的腳手架- 驚覺