前言:前段时间撸过react脚手架,现在新公司用vue,最近花时间撸一下vue-cli,撸完之后,再亲自写一个简化版的cli。
看脚手架的思路,就是顺着package.json文件看下去即可,看bin字段到底执行的是什么文件。
正式开始
react,vue脚手架都用的lerna分包,所以一进来直接去看packages目录,进入@vue目录,最后来到cli目录下。
1. 按照惯例,这种脚手架都可以分为两部分
- 生成项目基本文件,组织文件结构,说白了就是创建样板项目,如 vue create hello-word
- 开发命令如 vue-cli-service serve | build | lint。
vue create hello-word
就从这个命令出发,看看这个命令到底做了哪些操作。
可以看到vue其实是执行了bin 目录下的vue.js文件。
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脚手架源码解析(二)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。