vue-cli@2的原理解析

做爲一個菜鳥,我有一顆好奇的心,每當vue init 的時候,看到那流暢的進度和神奇的結果,內心都充滿一窺其本質的指望……前端

如下就是我不斷的console,大體理出來的一個流程心得,紀錄在此,以做備忘。vue

一、which vue,定位vue命令的實際位置node

 

二、去往命令vue的目錄,查看代碼webpack

這裏的commander包是用來建立命令行的工具,其npm官網粗略瞭解,瞭解到其中的init、list命令會在當前目錄尋找執行vue-init、vue-list文件git

The commander will try to search the executables in the directory of the entry script (like ./examples/pm) with the name program-command, like pm-installpm-search.es6

 

三、查看vue-init文件及其代碼github

經過ls命令咱們能夠看到,命令文件的真實位置是在全局node_modules下的vue-cli裏面,因此代碼裏的require包都是從vue-cli包下找的web

這個文件就是init命令的主體了,裏面主要有vue-cli

download-git-repo、inquirer等包 和 cli/lib下的功能函數 check-version、generate等

 

3.一、check-version 的做用npm

首先其會比對vue-cli的package.json裏的node版本和當前process.version的環境版本,若是環境版本低就會報錯。

其次其會請求線上vue-cli的最新版本,來告訴用戶是否有新的vue-cli版本能夠更新,只是給用戶一個提示

const request = require('request')
const semver = require('semver')
const chalk = require('chalk')
const packageConfig = require('../package.json')

module.exports = done => {
  // Ensure minimum supported node version is used
  if (!semver.satisfies(process.version, packageConfig.engines.node)) {
    return console.log(chalk.red(
      '  You must upgrade node to >=' + packageConfig.engines.node + '.x to use vue-cli'
    ))
  }

  request({
    url: 'https://registry.npmjs.org/vue-cli',
    timeout: 1000
  }, (err, res, body) => {
    if (!err && res.statusCode === 200) {
      const latestVersion = JSON.parse(body)['dist-tags'].latest
      const localVersion = packageConfig.version
      if (semver.lt(localVersion, latestVersion)) {
        console.log(chalk.yellow('  A newer version of vue-cli is available.'))
        console.log()
        console.log('  latest:    ' + chalk.green(latestVersion))
        console.log('  installed: ' + chalk.red(localVersion))
        console.log()
      }
    }
    done()
  })
}

  

3.2 、download-git-repo的做用

用來經過git clone 或者  http下載的方式,從github、gitlab等平臺下載倉庫代碼,具體可去官網查看,

默認,咱們沒有指定clone參數,程序會從 https://github.com/vuejs-templates/webpack/archive/master.zip 下載模版

若是用 vue init webpack -c 則會經過 git clone git@github.com:vuejs-templates/webpack.git 來下載(本地配置sshkey,能夠下載私有庫)

tmp變量是臨時存放模版的目錄,默認在 ~/.vue-templates/

 

const tmp = path.join(home, '.vue-templates', template.replace(/[\/:]/g, '-'))
……
download(template, tmp, { clone }, err => {
    spinner.stop()
    if (err) logger.fatal('Failed to download repo ' + template + ': ' + err.message.trim())
    generate(name, tmp, to, err => {
      if (err) logger.fatal(err)
      logger.success('Generated "%s".', name)
    })
})

  

若是咱們要配置本身項目的模版目錄,就好好看看vue-init文件裏的run函數吧 ^_^,祝你成功^_^。

3.三、inquirer的做用

起到一個prompt confirm的做用

Generate project in current directory?

Target directory exists. Continue?

 

3.四、generate函數的做用

主要代碼

 

  metalsmith.clean(false)
    .source('.') // start from template root instead of `./src` which is Metalsmith's default for `source`
    .destination(dest)
    .build((err, files) => {
      done(err)
      if (typeof opts.complete === 'function') {
        const helpers = { chalk, logger, files }
        opts.complete(data, helpers)
      } else {
        logMessage(opts.completeMessage, data)
      }
    })

  

下載完模版後的處理邏輯都在這裏面了,函數文件位於 vue-cli/lib/generate.js,這裏面主要用了

metalsmith、handlebars等包 和 lib/options.js 

options.js 會去 ~/.vue-templates/模版 目錄下獲取 meta.js 或者 meta.json 中的配置。

這個配置就是用來配置圖中的東西。

 

3.4.一、metalsmith 的做用

相似於gulp,是一個流程工具,英文很差,我看它看的頭疼,只知道它幹了什麼,但不知道它是怎麼作的。

它會配置options.js裏獲取的配置數據,對模版文件進行過濾

 

3.4.二、handlebars 的做用

一個js模版工具,相似服務端的smarty、前端的artemplate、es6的字符串模版等。

它會在metalsmith的流程裏處理模版裏的變量,把咱們填寫的項目名等數據渲染成最終的文件,寫進當前項目目錄裏。《完》


 

好久沒寫博客,寫着好彆扭啊,不支持markdown,只能憑感受來寫了,估計預覽起來會很難看,但願你們見諒。

最後吟詩一首:

「衆鳥高飛盡,孤雲獨去閒。相看兩不厭,只有敬亭山。」

相關文章
相關標籤/搜索