作为一个菜鸟, 我有一颗好奇的心, 每当 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-install, pm-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, 只能凭感觉来写了, 估计预览起来会很难看, 希望大家见谅.
最后吟诗一首:
"众鸟高飞尽, 孤云独去闲. 相看两不厌, 只有敬亭山."
来源: https://www.cnblogs.com/wshiqtb/p/10697804.html