理解脚手架
什么是脚手架?
脚手架本质是一个操作系统的客户端,它通过执行命令来实现相应的功能。比如:vue create vue-test
,表示创建一个名为 vue-test 的 vue 项目。
脚手架的必要性
开发脚手架的核心目标是:提升前端研发效率。
脚手架的核心价值是可以将研发过程自动化、标准化、数据化。
- 自动化:项目重复代码拷贝、git 操作、发布上线操作。
- 标准化:项目创建、git flow、发布流程、回滚流程。
- 数据化:研发过程系统化、数据化、使得研发过程可量化。
和自动化工具的区别
问题:jenkins、travis等自动化构建工具已经比较成熟了,为什么还要自研脚手架?
- 不满足需求:jenkins、travis 通常在 git hooks 中触发,需要在服务端执行,无法覆盖研发人员本地的功能。如:创建项目自动化,本地 git 操作自动化等。
- 定制复杂:jenkins、travis 定制过程需要开发插件,其过程较为复杂,需要使用 java 语言,对前端同学不够友好。
脚手架执行命令解析
例如: vue create vue-test
上面这条命令由 3 个部分组成:
- 主命令: vue
- command: create
- command 的 param: vue-test
这条命令表示创建一个 vue 项目,项目的名字叫 vue-test。
以上是最一个较为简单的脚手架命令,但实际场景往往更加复杂,比如:
vue create vue-test-app --force -r https://registry.npm.taobao.org
这里的 --force
,-r
都叫做 option
,只不过 -r
使用的是简写形式,可以替换成 --registry
。
-r https://registry.npm.taobao.org
后面的 https://registry.npm.taobao.org
成为 option
的 param
,其实 --force
可以理解为:--force true
,简写为:--force
。
脚手架的执行原理
执行原理如下:
- 在终端执行命令 vue create vue-test
- 终端解析 vue 命令
- 终端在环境变量中查找 vue 命令
- 终端根据 vue 命令链接到实际文件 vue.js
- 终端使用 node 执行 vue.js 文件
- vue.js 解析 command 、options
- vue.js 执行 command
- 执行完成,退出执行
脚手架实现原理
实现原理
如果你能回答以下三个问题,就掌握了脚手架实现原理。
- 为什么全局安装的
@vue/cli
后会添加的命令为vue
? - 全局安装
@vue/cli
时发生了什么? - 执行
vue
命令时发生了什么?为什么vue
指向了一个 js 文件,却可以通过vue
命令去执行它?
问题 1:
在 @vue/cli 的 npm 包的 package.json 中设置了 bin 属性
{
...
"bin": {
"vue": "bin/vue.js"
},
...
}
该属性决定了安装包后添加的命令为 vue。
问题 2:
npm
会将@vue/cli
下载到/usr/local/lib/node_modules
(全局安装的 node) 目录下- 下载完成后会解析
package.json
文件 - 根据
package.json
中的bin
属性,在node
的执行目录/usr/local/bin
下创建名为vue
的软链接,并将vue
链接到bin
属性中配置的文件bin/vue.js
问题 3:
执行 vue
命令时发生了什么?
- 在环境变量中查找 vue
- 不存在:提示命令不存在
- 存在:根据 vue 命令找到实际文件 vue.js 并执行该文件
为什么 vue
指向了一个 js 文件,却可以通过 vue
命令去执行它?
在 vue.js 文件最顶部声明了使用环境变量中的 node 来执行此文件
#!/usr/bin/env node
...
思考:以下两种方式有啥区别?
#!/usr/bin/env node
#!/usr/bin/node
第二种是 node 的实际安装目录,只不过别人安装这个包时,如果 node 的目录不一致就无法运行了。
原理进阶
- 为什么说脚手架本质是操作系统的客户端?它和我们在PC上安装的应用/软件有什么区别?
- 如何为 node 脚手架命令创建别名?
问题 1:
执行脚手架的时候,其实是作为操作系统上的一个可执行文件来进行执行,所以可以理解脚手架就是操作系统的一个客户端。但是这个客户端本质上并不是我们编写的文件,因为执行脚手架需要借助 node 来执行,node 才是系统的客户端,而我们编写的脚手架文件仅仅只是 node 一个参数。
脚手架和 PC 上安装的软件本质上没什么区别,只是安装的软件存在 GUI 而已,我们也可以通过 node 来调取系统的 GUI 绘制 API 来绘制窗口。
问题 2:
比如:给 vue 设置别名。
vue 在系统中的软链接如下
ll /usr/local/bin/vue
# lrwxr-xr-x 1 zhoujiawei wheel 39B 12 26 14:35 /usr/local/bin/vue -> ../lib/node_modules/@vue/cli/bin/vue.js
配置别名为 vue2
cd /usr/local/bin/
ln -s ./vue vue2