# Vue ClI 源码探索

它号称 Vue.js 开发的标准工具

具有以下特性:

  • 功能丰富:对于 Babel、Typescript、ESLint、PostCSS、PWA、单元测试和End-to-End测试提供开箱即用的支持。
  • 易于扩展:它的插件系统可以让社区常见需求构建和共享可复用的解决方案。
  • 无需Eject (eject说的是啥):Vue CLI 完全是可配置的,无需eject。这样你的项目就可以长期保持更新了。
  • CLI 之上的图形化:图形化界面创建、开发和管理你的项目。(对于开发的我感觉这个功能用处不大)
  • 即刻创建原型:单个 Vue 文件即刻实践新的灵感
  • 面向未来:为现代浏览器轻松产出原生的 ES2015 代码,或将你的 Vue 组件构建为原生的 Web Components 组件。

# How

上面提到的这些特点,我们通过代码层面,一层层的来看,怎么能够做到这么厉害,揭秘这个工具的内部逻辑。

# 探索步骤

  • 先搞清楚大的流程,然后慢慢深入
  • Vue create xxx 命令开始逐步分析
  • 找出插件注册的方式
  • 发现一些有趣的写法

# TODO

  • 清晰整体结构
  • @vue/cli
  • @vue/cli-init
  • @vue/cli-plugin-xxx
  • 上面提到的特性的实现方式
  • 如何实现的插件机制

# 目录结构

整个项目是通过 lerna 来管理,使用固定模式,所有包使用相同的版本。

https://github.com/llccing-demo/vue-cli 这里是fork项目,与文章中的代码相呼应。

|-- packages
|-- |-- @vue // 命令、插件集合
|-- |-- |-- cli // 全局命令注册
|-- |-- |-- cli-init
|-- |-- |-- cli-overlay
|-- |-- |-- cli-service // vue-cli-service serve/build/inspect/help 命令的核心
|-- |-- |-- cli-service-global // 壳,核心内容在 ../cli-service
|-- |-- |-- cli-shared-utils // 封装的各种工具函数
|-- |-- |-- cli-test-utils
|-- |-- |-- babel-preset-app
|-- |-- |-- cli-ui
|-- |-- |-- cli-ui-addon-webpack
|-- |-- |-- cli-ui-addon-widgets
|-- |-- |-- cli-plugin-babel
|-- |-- |-- cli-plugin-e2e-cypress
|-- |-- |-- cli-plugin-e2e-nightwatch
|-- |-- |-- cli-plugin-eslint
|-- |-- |-- cli-plugin-pwd
|-- |-- |-- cli-plugin-typescript
|-- |-- |-- cli-plugin-unit-jest
|-- |-- |-- cli-plugin-unit-mocha
|-- |-- |-- cli-plugin-vuex
|-- |-- |-- cli-plugin-router
|-- |-- test // 给开发的同学测试
|-- |-- vue-cli-version-marker // 用来更加快速的获取 @vue/cli 的最新版本
|-- script // 脚本目录
|-- docs // 文档当然用自家的 VuePress
|-- lerna.json // 通过 lerna 来管理包
|-- yarn.lock // 通过 yarn 来管理依赖
|-- .circleci // 通过 circleCI 测试、构建项目

# 调试

只有代码能够调试,我们才能够逐步跟踪代码执行,掌握脉络。

文档中有说明如何参与开发,这和能够进行调试的原理是一致的,做如下调整,重要的是先卸载全局安装的 @vue/clivue-cli 因为你可能是 CLI2 版本的,然后进入到 packages/@vue/cli 目录,执行 yarn link 即可。

# install dependencies
yarn

# link `vue` executable
# if you have the old vue-cli installed globally, you may
# need to uninstall it first.
cd packages/@vue/cli
yarn link

# create test projects in /packages/test
cd -
cd packages/test
vue create test-app
cd test-app
yarn serve

# 项目依赖

  • commander tj大神的node命令行工具,用于获取参数、设置默认值
  • slash 修改资源路径,保证 Unix 和 Windows 返回路径一致
  • minimist 命令行参数解析器
  • didyoumean 一个简单的,经过优化的 js 库 和 node.js 模块,能够将人的个性化输入和各种可能性进行匹配
  • debug 带有命名空间的日志输出工具,能够彩色打印,支持浏览器和node.js,使用的时候,需要设置以下代码 debug.enabled = true
  • resolve 实现 node.js require.resolve() 算法。
  • dotenv 载入项目根目录的环境变量
  • requestrequest-promise-native 这个两个库已经弃用了;@vue/cli-share-utils/lib/request.js 中有用到 request-promise-native,这个以后可以对应升级
  • chalk 为命令行字符串添加样式
  • execa 改善了 node.js 原来的 Child Process 进程,执行脚本命令
  • semver 语义化版本,同时能够进行版本的比较
  • lru-catch 高速缓存对象,用于删除最近最少使用的项目
  • envinfo 为了调试和提 issue,针对当前的开发环境生成一个报告
  • leven 测量两个不同的字符串的差别,实现莱温斯坦距离算法最快的js实现,没有之一...
  • ora 优雅的终端旋转器
  • portfinder 在当前机器找到空闲端口号的小工具,解决了项目启动端口号冲突的痛点
  • @hapi/joi 参数校验 'Build powerful, scalable applications, with minimal overhead and full out-of-the-box functionality'
  • Inquirer 命令行的通用交互界面集合
  • memfs 内存型文件系统,在这里的用处主要是运行jest测试的时候使用
  • deepmerge 对象的深度(递归)合并
  • yaml-front-matter 从字符串或者文件中解析 YAML 或者 json
  • ejs 嵌入式的 JavaScript 模板引擎
  • hash-sum 快速独特的哈希生成器
  • vue-jscodeshift-adapter 在 Vue 单文件组件中执行 jscodeshift
  • jscodeshift A JavaScript codemod toolkit。两个介绍:jscodeshift 简易教程代码重构利器-jscodeshift
Last Updated: 2020-05-11 19:55:00