我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第9篇文章,点击查看活动详情
环境变量
在学习脚手架之前,首先要知道什么是环境变量。
环境变量的作用
你可能有个疑问,我们在Shell命令行中输入一个命令,Shell是如何知道去哪找到这个命令所对对应的执行文件,然后去执行它?
这通常是通过环境变量 PATH 来进行搜索的,熟悉Window的同学可能知道有这么一个叫PATH的环境变量。这个环境变量保存了Shell中执行的命令所对应的可执行文件的路径。
那环境变量存放在哪里呢?我们可以通过echo $PATH来查看:
可以看到环境变量 PATH 有好几个路径,当我们在终端输入一个命令的时候,电脑就会依次按照 PATH 中设定的路径来到目录中去查找,如果存在同名的环境变量,则执行先找到的那个。
这里面的文件都是一些链接文档,它们链接到真正执行的文件。
如何添加环境变量
现在你安装了mongodb的文件,在/usr/local/mongodb/bin路径下,一般你需要进入到这个路径才能启动mongodb,但是每次都要进入到这个文件太麻烦了,我能不能在任何地方输入mongodb都能启动程序呢?
通过设置环境变量即可完成,也就是把/usr/local/mongodb/bin路径添加到PATH上就行了,当你在命令行输入mongodb时,操作系统会从PATH上找到对应的路径,然后执行可执行文件。
vi .bash_profile
// 输入:
export PATH=$PATH://usr/local/mongodb/bin ($PATH代表已经存在的路径,它可以放前面或者后面)
// 立即生效
source .bash_profile
【注意】vi .bash_profile 表示在用户主目录下设置,针对当前特定的用户起作用的环境变量。你也可以设置系统目录下的profile文件,那么将会对所有用户都生效。
什么是脚手架?
脚手架本质
脚手架本质就是一个操作系统的客户端。比如node, 它在window系统下的可执行文件就是node.exe。
下面以Vue的脚手架来说明前端脚手架是如何运作的。
vue create vue-test
上面的命令由三部分组成:
- 主命令: vue
- command: create
- command的参数:vue-test
它表示创建了一个名叫vue-test的项目,以上是最简单的脚手架命令,实际情况往往更加复杂,比如: 当已经有了一个叫vue-test的项目,我们需要覆盖原有的项目,此时我们可以输入:
vue create vue-test --force
这里的--force 叫做 option,用来辅助脚手架确认在特定场景下用户的选择(可以理解为配置)。
还有一种场景是通过vue create 创建项目的时候,会执行npm intall来安装依赖,但是我们想用淘宝源来安装:
vue create vue-test -r https://registry.npmmirror.org
这里的 -r 也叫做 option,它与 --force 不同的是它使用 -,并且使用简写,这里的 -r 也可以替换成 --registry。
-r https://registry.npm.taobao.org 后面的 https://registry.npm.taobao.org 成为 option 的 param,其实 --force 可以理解为:--force true,简写为:--force 或 -f
这么配置项是怎么知道的呢?其实我们输入下面的命令就可以看到 vue create 支持的所有 options:
vue create --help
脚手架的执行过程
当输入vue create vue-test-app时,操作系统会去环境变量PATH中查找Vue对应的可执行文件路径(相当于执行which vue),发现它对应的路径是/***/.nvm/versions/node/v16.14.0/bin/vue,然后这个bin/vue是一个链接文档,它链接到lib/node_modules/@vue/cli/bin/vue.js。也就是最后执行的文件就是这个vue.js
脚手架的执行原理如下:
- 在终端输入
vue create vue-test-app - 终端解析出
vue命令 - 终端在环境变量中找到
vue命令 - 终端根据
vue命令链接到实际文件vue.js - 终端利用
node执行vue.js vue.js解析 command / optionsvue.js执行 command- 执行完毕,退出执行
脚手架的实现原理
要搞清楚脚手架的实现原理,从三个问题着手:
- 为什么全局安装
@vue/cli后会添加的命令为vue? - 全局安装
@vue/cli时发生了什么? - 执行
vue命令时发生了什么?为什么vue指向一个js文件,我们却可以直接通过vue命令去执行它? - 如何为node脚手架命令建立别名?
第一个问题
我们知道执行vue create **的时候,会找到真正的执行文件vue.js,这vue.js所在的工程目录中,有一个package.json文件:
这个package.json里面有个bin字段,是key/value的形式,当全局安装@vue/cli之后,node就会在自己的bin文件夹下配置一个叫vue(即,key)的软链接。这就可以回答第一个问题了。
第二个问题
当全局安装的时候,包被安装在node文件下面的lib/node_modules文件中,当包被下载完成后node会去解析package.json的bin字段,如果有bin字段,那么就会在node的bin目录下创建一个软连接。
第三个问题
当我们输入vue 命令的时候,其实跟输入which vue是等价的:
在vue.js的开头会有一行这样的代码:
#!/usr/bin/env node
它表示从环境变量中找到node,然后用node来执行vue.js脚本。
用node执行文件还有另一种写法:
#! /usr/bin/node
这种写法是不从环境变量中查找node,直接从/usr/bin/目录下查找node,但是不同用户安装导致/usr/bin/下没有node,所以,推荐使用第一种写法。
第四个问题
通过上面的了解,我们它们都是通过软链接的形式来执行命令的,既然要命名一个别名,当然也可以使用软链接。
比如imooc是一个链接到***/test.js的文件,那么我们可以再建立一个软链接到imooc上:
ls -s ./imooc imooc2
为什么要开发一个前端脚手架
目前我所在的公司要开始一个前端项目时,都会直接copy上一个项目的模板,然后进行增删操作,最后就得到了现在项目的模板。
如果你是个人开发者,这还能原谅。如果是一个几千人的公司还进行这种操作就显得很low,最主要的缺点是浪费时间。如果通过拷贝的方式创建一个模板花费1小时,大型公司一般都有上千个项目,那就是浪费了数千个小时了。
另外,各个团队使用的技术栈都不一样,使用的模板也不一样,因此需要有一个地方能对这些模板汇总,当你需要的时候直接选择你要的模板即可。因此,大型公司都会有一个通用的脚手架。
现在思考下,当你创建一个前端项目时,需要这个前端模板包含哪些功能呢?
- 通用功能:http请求方法封装,工具方法,组件库,埋点等功能
- 代码格式:统一代码格式 eslint + prettier
- git操作:提交规范,git hooks 设置(保证提交到仓库中的代码是符合规范)
- 构建与发布:依赖安装与构建,资源上传cdn,域名绑定等
上面列出了一个前端模板应该具有的通用功能,可以根据项目特点进行增删。
当你通过脚手架下载到这样的一个模板框架时,就极大提高开发效率,而不用从头开始搭建框架,而且它保证了一定的代码质量。
脚手架核心价值
将研发过程:
- 自动化:项目重复代码拷贝/git操作/发布上线操作
- 标准化:项目创建/git flow/发布流程/回滚流程
- 数据化:研发过程系统化、数据化,使得研发过程可量化
问题:jenkins、travis等自动化构建工具已经比较成熟了,为什么还需要自研脚手架?
- 不满足需求:jenkins、travis通常在git hooks中触发,需要在服务端执行,无法覆盖研发人员本地的功能,如:创建项目自动化、本地git操作自动化等
- 定制复杂:jenkins、travis定制过程需要开发插件,其过程较为复杂,需要使用Java语言,对前端同学不够友好