如何搭建一個(gè)自己的腳手架

腳手架

搭建腳手架的目的就是快速的搭建項(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命令能否生效

image.png

很快就可以看到已經(jīng)成功初始化了my-project梧喷,此時(shí)可以看一下my-project文件夾下面


image2.png

發(fā)布到 npm

既然以上命令可以執(zhí)行成功了,那接下來(lái)我們就把它發(fā)布到 npm 上吧,其它用戶就可以通過(guò) npm install heaven-cli-fe -g 全局安裝铺敌。 即可使用 heaven 命令汇歹。

源碼地址:github.com/hujinbin/he…

可使用 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è)自己的腳手架- 驚覺

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市霎烙,隨后出現(xiàn)的幾起案子撬讽,更是在濱河造成了極大的恐慌,老刑警劉巖悬垃,帶你破解...
    沈念sama閱讀 212,332評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件游昼,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡盗忱,警方通過(guò)查閱死者的電腦和手機(jī)酱床,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)趟佃,“玉大人扇谣,你說(shuō)我怎么就攤上這事∠姓眩” “怎么了罐寨?”我有些...
    開封第一講書人閱讀 157,812評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)序矩。 經(jīng)常有香客問(wèn)我鸯绿,道長(zhǎng),這世上最難降的妖魔是什么簸淀? 我笑而不...
    開封第一講書人閱讀 56,607評(píng)論 1 284
  • 正文 為了忘掉前任瓶蝴,我火速辦了婚禮,結(jié)果婚禮上租幕,老公的妹妹穿的比我還像新娘舷手。我一直安慰自己,他們只是感情好劲绪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,728評(píng)論 6 386
  • 文/花漫 我一把揭開白布男窟。 她就那樣靜靜地躺著盆赤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歉眷。 梳的紋絲不亂的頭發(fā)上牺六,一...
    開封第一講書人閱讀 49,919評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音汗捡,去河邊找鬼淑际。 笑死,一個(gè)胖子當(dāng)著我的面吹牛凉唐,可吹牛的內(nèi)容都是我干的庸追。 我是一名探鬼主播,決...
    沈念sama閱讀 39,071評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼台囱,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼淡溯!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起簿训,我...
    開封第一講書人閱讀 37,802評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤咱娶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后强品,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膘侮,經(jīng)...
    沈念sama閱讀 44,256評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,576評(píng)論 2 327
  • 正文 我和宋清朗相戀三年的榛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了琼了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,712評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡夫晌,死狀恐怖雕薪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晓淀,我是刑警寧澤所袁,帶...
    沈念sama閱讀 34,389評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站凶掰,受9級(jí)特大地震影響燥爷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜懦窘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,032評(píng)論 3 316
  • 文/蒙蒙 一前翎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧畅涂,春花似錦鱼填、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至苇经,卻和暖如春赘理,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扇单。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工商模, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜘澜。 一個(gè)月前我還...
    沈念sama閱讀 46,473評(píng)論 2 360
  • 正文 我出身青樓施流,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親鄙信。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瞪醋,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,606評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容