從react-start到co源碼(二)

react做爲當前十分流行的前端框架,相信不少前端er都有蠢蠢欲動的學習它的想法。工欲善其事,必先利其器。這篇文章就簡單的給你們介紹一下如何我快速的搭建一個react前端開發環境。主要針對於react小白,大神不喜勿噴。
從標題能夠看出,這裏不會僅僅只介紹一下react的開發環境如何搭建。我將這個系列分紅三篇介紹:前端


接下來就開始介紹如何去開發一個簡單的react-start腳手架,從而一鍵生成react開發環境。github

目錄結構

首先來看一下腳手架的目錄結構,基本結構以下:npm

-bin
  |--reactGenerator
-commander
  |--init.js
-config.json
-package.json

bin/reactGenerator:定義基本的命令json

commander/init.js:定義命令所對應的操做segmentfault

config.json:腳手架的一些配置文件bash

package.json:項目的包文件前端框架

項目依賴

package.json文件中能夠看出,項目的基本依賴主要有以下幾個:

"dependencies": {
  "chalk": "^1.1.3",
  "co": "^4.6.0",
  "co-prompt": "^1.0.0",
  "commander": "^2.9.0",
  "ora": "^0.4.1"
}

chalk:給命令行輸出添加顏色

co:執行generator函數

co-prompt:用於命令行交互

commander:定義命令行操做和執行指定的命令

ora:一個頗有趣的命令行loading動畫

定義命令

命令的基本定義主要是在reactGenerator中,瞭解該文件以前,請確保本身對commander這個庫有基本的瞭解,不瞭解的同窗請自行前往github
下面就是reactGenerator的完整內容:

#!/usr/bin/env node

const program = require('commander')
const package = require('../package')

// 定義版本號
program.version(package.version)

// 定義使用的方法
program.usage('<command>')

// 定義腳手架的初始化工做
program
  .command('init')
  .alias('i')
  .description('generator a react project')
  .action(() => {
    require('../commander/init')()
  })

// 解析參數
program.parse(process.argv)

// 若是沒有輸入命令 顯示幫助的內容
if (!program.args.length) {
  program.help()
}

在這個文件中咱們只定義一個init操做,當咱們全局安裝腳手架工具的時候,咱們就能夠經過以下命令建立咱們的項目。

react-to-start init 或者 react-to-start i

其中react-to-start是你在package.jsonbin字段中指定的。

"bin": {
  "react-to-start": "bin/reactGenerator"
}

初始化項目

初始化項目主要使用的是init命令,這個命令的基本定義以下:

const co = require('co')
const chalk = require('chalk')
const prompt = require('co-prompt')
const ora = require('ora')
const fs = require('fs')
const exec = require('child_process').exec
const config = require('../config.json')

const init = () => {
  co(function* () {
    let templateName = yield prompt('what is your template name?  ')
    let projectName =  yield prompt('what is your project name?  ')
    let branchesName = config.branchesName

    if (!branchesName.includes(templateName)) {
      process.stdout.write(chalk.red(`\n ${templateName} does not exit, you can choose one of the template  listed below`))
      branchesName.forEach((name, index) => {
        process.stdout.write(chalk.green(` \n ${index + 1}. ${name} \n`))
      })
      process.exit(1)
    }

    // 若是說有對應的template 拼接git url進行下載
    let git = ''

    fs.exists('./.git', function(exists) {
      if (exists) {
        git = `git clone ${config.templateUrl} ${projectName} && cd ${projectName} && git checkout ${templateName}`
      } else {
        git = `git init && git clone ${config.templateUrl} ${projectName} && cd ${projectName} && git checkout ${templateName}`
      }

      // 使用 ora 打印出 loading + log
      let spinner = ora(`is downloading the template for ${templateName}...`)
      // 開始 loading 動畫
      spinner.start()

      exec(git, (error, stdout, stderr) => {
        spinner.stop()
        if (error) {
          console.log(error)
          process.exit()
        }
        process.stdout.write(chalk.green('\n $$$ Generation completed! To use step by step as following: '))
        process.stdout.write(chalk.green(`\n 1. cd ${projectName} `))
        process.stdout.write(chalk.green(`\n 2. npm install \n`))
        process.exit(0)
      })
    })
  })
}

module.exports = init

這個初始化命令的定義十分簡單,有點nodejs基礎且瞭解co的同窗都會很輕鬆的讀懂,這裏就不在多述(感冒好難受的說)。

腳手架配置

腳手架所對應的模板目錄就是在上篇文章中所講的內容,不瞭解的同窗請戳從react-start到co源(一)以下就是配置文件:

{
  "templateUrl": "https://github.com/pavoooo/template.git",
  "branchesName": ["react"]
}

templateUrl就是模板地址(暫存在個人github上),branchesName就是項目的名稱,在github中以分支表示。

以上就是腳手架的基本架構,有點頭暈,有的地方寫的可能有點粗糙。有疑問的同窗歡迎留言或者到個人githubissue。晚安。

相關文章
相關標籤/搜索