vue-cli源码学习1.x
说起vue-cli源码的阅读,主要源于公司实习时候,对公司的前端脚手架比较感兴趣,然后就开始看了看,但是看的不是很明白。就准备先看看比较熟悉的vue-cli,而且vue-cli使用人数比较多,也有一些源码分析的文章,有助于代码的理解。
但其实看一遍别人的文章,感觉只是稍微明白了一点。于是,本着学习cli工具的开发思路,因此,从master分支的第一个提交开始看起,准备梳理一下整个cli工具的开发流程,以及作者的一些思考。
这篇文章将主要分析vue-cli 1.x
版本的一些原理。
整体思路
- bin/ 目录下面放命令文件,比如
vue
,vue-init
,vue-list
,注意这里没有加js后缀 - lib/ 目录下面放一些公共的方法
其实vue-cli最初只提供了两种命令,分别是vue init
初始化项目,以及vue list
查看模板列表。命令行的控制则主要是引入commander
包来控制。这里选项交互暂时没用到inquirer
包,后面版本会用到。
bin目录写到package.json文件中作用是可直接命令行启动,即npm i -g
后可直接使用vue init <package-name> <project-name>
形式。
同时,为了方便调试,可以直接在目录下面npm link
到全局,这样改动后可以直接看到效果。原理即创建软连接,使用npm unlink
即可取消。
脚本文件调用
主文件vue如何根据用户输入选择执行不同脚本文件?
最开始使用child_process.spawn(脚本路径,参数)
直接执行,如下
1 | // 这里执行子进程,根据命令行输入,执行不同bin下文件 |
后来的提交直接使用了commander特性,如下所示,command加入第二个参数,就可以在目录下面寻找vue-init与vue-list文件执行,省了一大段调用nodeAPI获取输入参数,选择脚本路径与参数的代码。
1 | require('commander') |
vue init
vue init
的思路很简单,就是预先写好一个模板,放到远程仓库中。然后当使用vue init
选择不同模板构建时,则下载不同的模板。先将模板下载到/tmp
下,然后再将其generate
到项目位置,而不是直接将其下载到目标位置。
一些预设选项是通过下载下来的模板中meta.json
中的选项来交互。版本目前暂时还不能init
成功,据我推测是代码比较老,和template不太匹配的缘故。比较有意思的是作者最初使用的Khaos
包来generate
到目标位置,可能作者觉得这个太麻烦了,重新封装了一下这个包叫khaos-patched
,一行代码就能实现功能。也有些借鉴意义。
这里有一个用法比较独特(之前没见过)
1 | // 举例:如果返回-1,则 ~-1 为 0, 也就是说没有找到,即为false,加上!,即为 true,既没有找到就进入 |
算的上奇淫巧技吧,但是有意思的事,作者在后面的版本中修改了,变成了如下,可能是觉得可读性不太好?
1 | var hasSlash = template.indexOf('/') > -1 |
vue list
vue list实现思路很简单,直接发请求获取一些模板列表,显示出来。这里就不多做解释了。
更新情况
2.0.x
依赖
完成功能
- 使用 inquirer 和 metalsmith 代替 Khaos 和 prompt-for
- 添加lint和test,以及重构项目,将Metalsmith所用插件方法单独抽离,放进lib
- 使用ora代替lib/spinner.js
- 添加vue-cli版本检查
1.4.x
完成功能
- 添加lib/spinner.js下载动画
1.3.x
依赖
- prompt-for-patched: 命令行问题及选择
完成功能
- 添加-c参数,可直接下载任意git仓库
- 添加没有指定project-name时,可将当前目录初始化功能
1.2.x
依赖
- download-git-repo: 下载github仓库
完成功能
- 使用download-git-repo替换download-github-repo
1.1.x
依赖
- khaos-patched: yyx自己基于khaos写的
完成功能
- 将khaos替换为khaos-patched
- 添加lib/git-user.js获取作者
1.0.x
依赖
- commander: 命令行交互
- chalk: 命令行高亮
- cross-spawn: Node子进程
- download-github-repo: 下载github上仓库
- khaos: 生成项目
- rimraf: rm -rf
- uid: 生成一串随机数
完成功能
- 构建项目主框架,完成vue init功能和vue list功能,使用子进程切换执行脚本
- 抽离lig/logger.js信息输出
- 使用commander的方法,删除大量vue脚本代码
- 增加目录下是否已有模板判断
总结
当然,目前只是看了最初的几次提交,1.x版本还有好多次提交,代码结构比较简单,后面会愈发复杂。同时上述原理只是1.x的前期版本,不包括2.x以及3.x版本。特别是3.x有了较大的改进。
———————-2019.8.3—————————-
1.x版本已经看完了,2.x版本也已经看完了。看完后觉得还是非常清晰地,当然和3.x版本相比,之前的版本还是有比较大的去别的。1.x和2.x版本总体上来讲,还是从远程仓库下载模板,可配置性虽然有但还是不够灵活,而且扩展性非常不好。3.x版本的最大特点就是插件式引入,而且开发者也可以直接开发自己的插件,更加灵活。
- 感谢你的欣赏!