vue-cli@2的原理解析


作為一個菜鳥,我有一顆好奇的心,每當vue init 的時候,看到那流暢的進度和神奇的結果,心里都充滿一窺其本質的期望……

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

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

 

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

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

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.

 

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

通過ls命令我們可以看到,命令文件的真實位置是在全局node_modules下的vue-cli里面,所以代碼里的require包都是從vue-cli包下找的

這個文件就是init命令的主體了,里面主要有

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

 

3.1、check-version 的作用

首先其會比對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.3、inquirer的作用

起到一個prompt confirm的作用

Generate project in current directory?

Target directory exists. Continue?

 

3.4、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.1、metalsmith 的作用

類似於gulp,是一個流程工具,英文不好,我看它看的頭疼,只知道它干了什么,但不知道它是怎么做的。

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

 

3.4.2、handlebars 的作用

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

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


 

很久沒寫博客,寫着好別扭啊,不支持markdown,只能憑感覺來寫了,估計預覽起來會很難看,希望大家見諒。

最后吟詩一首:

“眾鳥高飛盡,孤雲獨去閑。相看兩不厭,只有敬亭山。”

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM