如何搭建一個自己的腳手架

腳手架

搭建腳手架的目的就是快速的搭建項目的基本結構并提供項目規范和約定。目前日常工作中常用的腳手架有 vue-cli、create-react-app、angular-cli 等等,都是通過簡單的初始化命令,完成內容的快速構建。

其實我們也可以用git clone url來新建(復制)項目,再 low 一點的方法就是復制粘貼整個文件夾,一樣也能達到初始化的目的。

腳手架的本質也是從遠程下載一個模板來進行一個新項目,但是腳手架可是高級版的克隆,它主要是提供了交互式的命令讓我們可以動態的更改模板,然后用一句命令就可以實現其他內置依賴的初始化,方便了多人協作,不需要將文件傳來傳去。

接下來我們就開始實現一個簡易版的腳手架heaven-cli(可自行命名),目標是實現一個heaven init template-name project-name這樣的命令,廢話少說,開始進入正題吧!

前置知識了解

其實一個簡易版的 heaven-cli的代碼量并不多,所以這里我們先來介紹一下其中要使用到的第三方庫

commander

這是用來編寫指令和處理命令行的,用法如下:

const program = require("commander");
// 定義指令
program
  .version('0.0.1')
  .command('init', 'Generate a new project from a template')
  .action(() => {
    // 回調函數
  })
// 解析命令行參數
program.parse(process.argv);
復制代碼

inquirer

這是個強大的交互式命令行工具,用法如下:

const inquirer = require('inquirer');
inquirer
  .prompt([
    // 一些交互式的問題
  ])
  .then(answers => {
    // 回調函數,answers 就是用戶輸入的內容,是個對象
  });
復制代碼

chalk

這是用來修改控制臺輸出內容樣式的,起到了美化輸出內容的作用,用法如下:

const chalk = require('chalk');
console.log(chalk.green('success'));
console.log(chalk.red('error'));
復制代碼

ora

這是一個好看的加載交互組件,用于下載過程中的loading效果,用法如下:

const ora = require('ora')
let spinner = ora('downloading template ...')
spinner.start()
復制代碼

download-git-repo

用于下載遠程模板的,支持 GitHub、 GitLab 和 Bitbucket 等,用法如下:

const download = require('download-git-repo')
download(repository, destination, options, callback)
復制代碼

其中 repository 是遠程倉庫地址;destination 是存放下載的文件路徑,也可以直接寫文件名,默認就是當前目錄;options 是一些選項,比如{ clone:boolean }表示用 http download 還是 git clone 的形式下載。

初始化目錄

首先我們先創建一個空文件夾,取名 heaven-cli;

目錄結構

├── bin //可執行文件
└── lib
    ├── init.js         //init command
    ├── template 
        └── index.js        //內置的所有模版
    └── utils
        └── utils.js        // 公共方法
├── package.json
├── README.md
復制代碼

在該目錄下執行npm init命令,進行初始化。

安裝依賴

npm install  chalk commander inquirer ora download-git-repo
復制代碼

我這邊的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"
}
復制代碼

node.js 內置了對命令行操作的支持,package.json 中的 bin 字段可以定義命令名和關聯的執行文件。在 package.json 中添加 bin 字段

"bin": {
    "heaven": "bin/heaven.js"
  },
復制代碼

bin 目錄下新建一個heaven.js,并在行首加入一行 #!/usr/bin/env node 指定當前腳本由node.js進行解析

#!/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)
  })
  
// 解析命令行參數
program.parse(process.argv)
復制代碼

這個文件的主要作用就是定義指令,我們用node ./bin/heaven運行一下,就能看到運行結果了,

當然,在開發過程中為了方便調試,在當前的 heaven-cli 目錄下執行 npm link,將 heaven 命令鏈接到全局環境,

這樣我們每次只要輸入heaven,就可以直接運行了。

后面就可以編寫 /lib/init.js的代碼了

// 交互式命令行
const inquirer = require('inquirer')
// 修改控制臺字符串的樣式
const chalk = require('chalk')
// node 內置文件模塊
const fs = require('fs')
// 讀取template下內置的模版
const tplObj = require("./template")

// 下載
const download = require("download-git-repo");

// 自定義交互式命令行的問題及簡單的校驗
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 就是用戶輸入的內容,是個對象
    let {
        description
      } = answers;
      let projectName = answers.name
      // 出現加載圖標
      const spinner = ora("Downloading...");
      
      const url = tplObj.template[template]
      // 執行下載方法并傳入參數
      download(
        url,
        projectName,
        err => {
          if (err) {
            spinner.fail();
            console.log(chalk.red(`Generation failed. ${err}`))
            return
          }
          // 將用戶輸入的內容,寫入package.json內
          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');
          // 結束加載圖標
          spinner.succeed();
          console.log(chalk.green('\n Generation completed!'))
          console.log('\n To get started')
          console.log(`\n    cd ${projectName} \n`)
        }
      )
  })
復制代碼

至此,一個小小的腳手架就做完了。

接下來就測試一下heaven init vue my-project命令能否生效

image.png

很快就可以看到已經成功初始化了my-project,此時可以看一下my-project文件夾下面


image2.png

發布到 npm

既然以上命令可以執行成功了,那接下來我們就把它發布到 npm 上吧,其它用戶就可以通過 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 (開發中)

  • 基于vue-cli搭建的偽ssr腳手架,webpack5.28版本,打包生成對應的靜態html,并跳轉到真實網址,用于seo搜索。

koa-react

  • koa+react 工程項目骨架,ssr模式,支持mysql和mongodb數據庫

koa-vue

  • koa+vue 工程項目骨架 mvc結構, 前端vue單頁面應用

microservice (開發中)

  • 基于vite搭建微前端腳手架

原文鏈接:如何搭建一個自己的腳手架- 驚覺

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容