vue-cli脚手架源码解析(一)

前言:前段时间撸过react脚手架,现在新公司用vue,最近花时间撸一下vue-cli,撸完之后,再亲自写一个简化版的cli。

看脚手架的思路,就是顺着package.json文件看下去即可,看bin字段到底执行的是什么文件。

正式开始

react,vue脚手架都用的lerna分包,所以一进来直接去看packages目录,进入@vue目录,最后来到cli目录下。

《vue-cli脚手架源码解析(一)》

1. 按照惯例,这种脚手架都可以分为两部分

  • 生成项目基本文件,组织文件结构,说白了就是创建样板项目,如 vue create hello-word
  • 开发命令如 vue-cli-service serve | build | lint。

vue create hello-word

就从这个命令出发,看看这个命令到底做了哪些操作。

《vue-cli脚手架源码解析(一)》

可以看到vue其实是执行了bin 目录下的vue.js文件。

《vue-cli脚手架源码解析(一)》

2. vue.js,了解依赖的库和文件
这个文件我讲细致一点点,直接从上而下过代码。

const chalk = require('chalk')  // 相等于console的时候加上了颜色,
const semver = require('semver') // 规范版本号
const requiredVersion = require('../package.json').engines.node // 获取依赖的node最低版本
const didYouMean = require('didyoumean') // 有点类似于纠正输出错误,用户输出错误命令,给出联想提示。
checkNodeVersion(requiredVersion, 'vue-cli') // 这个方法,判定当前node版本是否低于最低要求版本requiredVersion 
const fs = require('fs')    //文件模块
const path = require('path') //路径模块
const slash = require('slash') // 用于转换 Windows 反斜杠路径转换为正斜杠路径 \ => /
const minimist = require('minimist') // 解析命令行参数 process.argv,有的项目用arg。
const program = require('commander') //这个就是命令库,定义命令,说白点,就是定义一个create命令,当你输入vue create的时候就会执行对应的方法。

const loadCommand = require('../lib/util/loadCommand') // 这个是自定义方法,根据不同的参数加载不同的js文件,比如test就加载test.js,里面有异常流处理,比如文件不存在怎么办,这里就不多复述。

3. create命令
他这里定义非常非常多的命令,但是我们一般就用一个create,这里只详细讲解这一个。
前置知识点,commander库,这个库是用来定义命令的,有一些基本知识点,可以先去了解一下。

program
  .command('create <app-name>')
  .description('create a new project powered by vue-cli-service')
  .option('-p, --preset <presetName>', 'Skip prompts and use saved or remote preset')
  .option('-d, --default', 'Skip prompts and use default preset')
  .option('-i, --inlinePreset <json>', 'Skip prompts and use inline JSON string as preset')
  .option('-m, --packageManager <command>', 'Use specified npm client when installing dependencies')
  .option('-r, --registry <url>', 'Use specified npm registry when installing dependencies (only for npm)')
  .option('-g, --git [message]', 'Force git initialization with initial commit message')
  .option('-n, --no-git', 'Skip git initialization')
  .option('-f, --force', 'Overwrite target directory if it exists')
  .option('-c, --clone', 'Use git clone when fetching remote preset')
  .option('-x, --proxy', 'Use specified proxy when creating project')
  .option('-b, --bare', 'Scaffold project without beginner instructions')
  .option('--skipGetStarted', 'Skip displaying "Get started" instructions')
  .action((name, cmd) => {
    const options = cleanArgs(cmd) // 对options参数做一些格式化

    if (minimist(process.argv.slice(3))._.length > 1) {
      // 输入的参数太多,不合法,走默认值
    }
    // --git makes commander to default git to true
    if (process.argv.includes('-g') || process.argv.includes('--git')) {
      options.forceGit = true
    }
    require('../lib/create')(name, options)
  })

看源码说话,create 代表命令 <app-name>表示项目名,后面带-表示参数,一个完整的命令就是 create hello -p 。一旦process.argvs中带了 create 就会执行这个命令,并且进入到action中去,执行对应的操作。
require(‘../lib/create’)(name, options) 到这里算是走完了最简单的一步,解析出参数,然后执行真正的create文件,并将参数传过去。 至于create文件里面的故事,下一章再讲。
vue-cli脚手架源码解析(二)

    原文作者:白衣卿相
    原文地址: https://segmentfault.com/a/1190000020012194
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞