vue2.X之vue-cli源码学习

前言

熟悉vue开发的同窗确定对vue-cli不陌生,Vue-cli是一款基于模板化的开发工具,等于就是把别人的项目结构给照搬过来,全部的配置都是暴露出来的,你能够根据实际状况去作一些配置的修改,更加灵活自由一点。前段时间也学习了下cli的源码,特此来记录下。javascript

常见 npm 包

在正式开始cli源码以前,先介绍下一些经常使用的npm包vue

  • commander:一款重量轻,表现力和强大的命令行框架,提供了用户命令行输入和参数解析强大功能。
  • handlebars:一个 javascript 语义模版库。能够利用 Handlebars.registerHelper 方法注册了一些 helper,这样就能够在模板中方便的使用这些 helper
  • metalsmith:静态网站生成器,能够用在批量处理模板的场景。它最大的特色就是全部的逻辑都是由插件处理,你只须要将这些插件用 metalsmith 链接起来使用便可。
  • chalk:用于修改控制台字符串的样式,包括字体样式(加粗),颜色以及背景颜色等。
  • download-git-repodownload-git-repo 是用于 从 GitHub, GitLab, Bitbucket 下载一个 git 仓库。
  • consolidateconsolidate 是一个模版引擎整合库。

vue-init 流程图

从图中能够看出init主要分为两步:

  1. 拉取模版
  2. 渲染模版

接下去将根据源码对每一步进行说明。java

注册命令

从图中能够看出vue-init的使用方法为vue-init template-name project-name。同时他提供了-c和--offline这两个选项。其中-c表明是利用git拉取模版,--offline使用缓存的模板,位于~/.vue-templates目录下面。

输入命令后,会利用commend包来分别读取模版名称,文件名,以及选项,并根据选项来进行后续的模版拉取操做,从代码中能够看到。本地存储模版的路径为根目录下的.vue-templates文件夹。

这段代码的做用是:

  1. 若是没有填写 app-name ,则默认在当前目录生成模版。
  2. 若是当前目录有与 app-name 重名的,是否要继续。 而后根据用户的回答执行run函数来拉取模版及渲染模版到目录中。

拉取模版

咱们来看一下run函数webpack

run函数会先判断是不是本地模版,若是是,会判断是否存在,存在则调用generate函数进行渲染,不存在则提醒。 若是不是本地模版,则判断是不是官方模版进行路径及版本的判断,再调用 downloadAndGenerate方法。

downloadAndGenerate会先判断本地是否存在模版,若是存在则删除,在调用download方法。

download方法主要根据选项clone来判断是调用git仍是http方法去下载模版,下载成功后执行回调 generate函数进行模版的渲染。

模版渲染

总体来看 generate函数仍是比较晦涩难懂的,接下来,咱们对这个方法分块来阅读。 首先来看 getOption方法

getOption中会先从模版的 template文件夹中的 meta.json或者 meta.js来读取配置,以后对你输入的文件名进行验证,同时添加些默认的配置。其中 meta.jsonmeta.js是动态加载模版的关键。

截取webpack模版中的meta.js,其中的message和default是否以为很熟悉。

接着经过metalsmith获取模版下的template文件夹作为后续的文件模版。再经过 Handlebars.registerHelper注册逻辑命令,从而处理一些数据,像webpack中就注册了if_eq来判断是否相等。

注册完命令以后会执行 meta.js中的before函数,webpack中的方法为 addTestAnswers

metalsmith.before 结果就是将 metalsmith metadata 数据和 isNotTest 合并,若是 isTest 为 ture,还会自动设置 name,description等字段。它的做用就是为模版添加自动测试脚本,它会将 isNotTest 设置为 false,而经过 inquirer 来提问又会是在 isNotTest 为 true 的状况下才会发生,所以设置了VUE_TEMPL_TEST的值会省略 inquirer 提问过程,而且会根据你设置的值来生成对应的模板,有如下三种值能够设置:

  1. minimal:这种不会设置 router,eslint 和 tests
  2. full: 会带有 router,eslint (standard) 和 tests (jest & e2e)
  3. full-airbnb-karma:带有 router eslint(airbnb) 和 tests(karma) 具体的使用方式:
VUE_TEMPL_TEST=full vue init webpack demo
复制代码

调用完before函数后会调用 metalsmith.use来使用 askQuestionfilterFilesrenderTemplateFiles这三个插件。下面逐个来看这三个插件是干啥的。 askQuestion调用了 ask函数。

ask函数就是经过 inquirer.prompt 来实现命令行交互,并将交互的值经过 metalsmith.metadata() 存到全局,而后在渲染模板的时候直接获取这些值。

filterFiles则是经过用户的回答将一些须要过滤调的文件删除

renderTemplateFiles 的主要功能就是利用 consolidate.handlebars.render~/.vue-templates下面的 handlebars 模板文件渲染成正式的文件。

以后执行 afterbuild函数完成整个渲染流程。

结语

至此,vue-init的整个流程及源码就结束了,其实总体流程仍是比较清晰的,经过对次源码的学习咱们在往后能够构建本身的脚手架和模版。毕竟懒惰是第一辈子产力!git

相关文章
相关标签/搜索