脚手架(一):初识脚手架

388 阅读6分钟

理解脚手架

我们对脚手架其实并不陌生,创建vue项目有其对应的脚手架:@vue/cli或者是使用vite的create-vue;react也有其对应的脚手架:create-react-app;
脚手架实际就是一个客户端工具,它帮助我们执行流程化的操作,来避免重复工作带来的耗时以提升工作效率,除此之外它还有很多其他价值:

  • 自动化:项目重复代码拷贝/git操作/发布上线操作
  • 标准化:项目创建/git flow/发布流程/回滚流程
  • 数据化:研发过程数据化、系统化,使得研发过程可量化

从使用角度理解脚手架

我们从创建vue项目最常用的@vue/cli脚手架的命令:vue create project入手。 这条看似简单常见的命令实际上由3个部分组成:

  • 主命令:vue
  • command:create
  • command的param:project,这条命令大家应该都很常见了,它表示创建一个vue项目,项目的名字叫project。

执行原理

在控制台输入vue create project命令后发生了什么?

  1. 查找vue环境变量:首先会查看电脑中是否存在vue环境变量,如果你没有安装@vue/cli,控制台会提示vue command不存在。安装以后其实通过类似which vue指令查找vue脚手架在全局的安装目录(/opt/homebrew/bin/vue,ps:也有可能在安装node目录下的bin/vue,这取决于你安装脚手架的方式),但这个路径指向的其实是一个软连接(可以理解为window操作系统的快捷方式)。
  2. 查找上述软连接指向的真正的执行文件的位置:/opt/homebrew/lib/node_modules/@vue/cli/bin/vue.js,执行vue.js文件,其中会解析create命令和project参数,并执行对应的代码。PS:是在bin同级目录lib文件夹中,这里是存放源码的位置。然后执行vue.js文件

总结:

  • 在终端输入vue create project
  • 终端解析出vue
  • 在环境变量中找到vue命令
  • 终端根据vue命令链接到实际文件vue.js
  • 终端利用node执行vue.js
  • vue.js解析command/options(create project)
  • vue.js执行command(create)
  • 执行完毕,退出执行

一些疑惑

全局安装@vue/cli发生了什么

  1. 将@vue/cli下载到全局的/lib/node_modules目录下。
  2. 解析@vue/cli的package.json文件中的bin配置项,在全局/bin目录下创建一个软连接,该软连接指向bin配置项的值的位置。

为什么安装了@vue/cli脚手架就能使用vue命令,不能是其他的吗?

其实是该项目的package.json文件中有这样的配置

{
  "bin": {
    "vue": "bin/vue.js"
  },
}

所以开发自己的脚手架时完全可以自定义脚手架的使用命令。

为什么vue.js会执行,好像也没有调用node vue.js命令

关键在于vue.js文件中的第一行代码:#!/usr/bin/env node,如果你在控制台直接执行/usr/bin/env命令可以看到打印的是所有的环境变量,那么#!/usr/bin/env node的意思就是找到node命令然后去执行本文件,等价于node xxx.js。如果你了解Python,在Python脚本文件的第一行也可能会有一行#!/usr/bin/env python命令,他们的原理都是一样的。
如果对#!/usr/bin/env node命令感兴趣,你完全可以自己随便创建一个js文件,然后第一行添加上#!/usr/bin/env node,再随便写一些测试代码,直接在控制台输入js文件的路径,你就会发现文件直接执行了。PS:如果遇到permission denied,可以使用chmod +x xxx.js命令为你的执行文件增加权限后再运行。

为什么说脚手架本质是操作系统的客户端?它和我们在PC上安装的应用/软件有什么区别?

1.node在window中是一个node.exe,在Mac中是一个可执行文件(node*),因为node是操作系统的一个客户端,脚手架的本质是通过node去执行js文件,所以也可以说脚手架的本质是操作系统的客户端。

2.本质来说没有区别,PC安装的应用只是提供了一个GUI,脚手架是通过命令的形式

自研脚手架和自动化构建工具的区别

市面上已经有了如Jenkins,travis等自动化构建工具,我们为什么还要自研脚手架?

  • 不满足需求:jenkins/travis通常需要在git hooks中触发,在服务端执行,无法覆盖研发人员本地的功能,如创建项目自动化,git操作自动化
  • 定制复杂:jenkins/travis等工具的定制过程需要开发插件,要用到Java语言,对前端开发人员并不友好

如何开发一个脚手架

  1. 新建一个文件夹(项目)使用npm进行初始化,打开package.json 配置bin字段,创建一个命令,指向bin/index.js;
  2. 将这个项目发布到npm;
  3. 全局安装这个脚手架;
  4. 使用第一步中bin字段中配置的命令来使用脚手架即可,会执行bin指向的那个js文件(别忘了增加#!/usr/bin/env node)。

脚手架本地link标准流程(调试)

脚手架开发通常是多个包同时管理,除了脚手架项目本身,还需要分其他的包来实现不同的功能,因此本地调试变得很重要,下面是常用的一些指令:
链接本地脚手架:

cd your-cli-dir
npm link

使用link链接到全局后,可以使用npm remove -g移除对应的命令

链接本地库文件:

cd your-lib-dir
npm link
cd your-cli-dir
npm link your-lib

取消链接本地库文件:

cd your-lib-dir
npm remove -g
cd your-cli-dir
# link存在
npm unlink your-lib
# link不存在
rm -rf node_modules
npm install -S your-lib

理解npm link:

  • npm link your-lib:将当前项目中的node_modules下指定的库文件链接到node全局node_modules下的库文件
  • npm link:将当前项目链接到node全局node_modules中作为一个库文件,并解析bin配置创建可执行文件

理解npm unlink:

  • npm remove -g:将当前项目从node全局node_modules中移除
  • npm unlink your-lib:将当前项目中的库文件依赖移除

脚手架开发难点解析

  • 分包:将复杂的系统拆分成若干个模块
  • 命令注册:
vue create
vue add
vue invoke
  • 参数解析:
vue command [options] <params>
  • help信息:包括全局help和命令help信息
  • 命令行交互
  • 日志打印
  • 命令行文字变色
  • 网络通信:HTTP、WebSocket
  • 文件处理
  • 等等..

原生脚手架开发痛点分析

  • 痛点一:重复操作
    • 多Package本地link
    • 多Package依赖安装
    • 多Package单元测试
    • 多Package代码提交
    • 多Package代码发布
  • 痛点二:版本一致性
    • 发布时版本一致性
    • 发布后相互依赖版本升级

package越多,管理复杂度越高,所以需要一个多包管理工具来管理我们的项目,下个章节会带大家认识lerna的使用和原理。