通过vue create xxx 学习脚手架运行原理

前言

vue create xxx命令为入口,探索脚手架背后的原理。常见经典的面试题:《当我们在终端输入vue create xxx创建项目时,发生了什么?》,要搞清楚这个问题,就需要了解脚手架命令执行的过程。

开始

首先全局安装@vue/cli

cmd 复制代码
npm install @vue/cli -g

创建项目

cmd 复制代码
vue create vue-demo

此时,就会执行对应的命令开始创建项目了,我们将这段语句分为三段

  1. vue代表了主命令
  2. create代表了command子命令,也可以理解为是一个动作
  3. vue-demo代表了command的param,就是对应子命令的参数

说到这里,其实我们npm install @vue/cli -g也是可以按照这个规律去拆解

  1. npm主命令
  2. install子命令
  3. @vue/cli子命令参数
  4. -g这里叫做option,可以理解为配置。它是--global的简写,所以全拼时是两条杠--global,简写是一条杠-g,常见的还有:--help/-h或者--version/-v

那为什么我们在终端输入vue或者npm等命令时,终端可以识别的出来呢?

为什么终端认识vue命令

我们可以通过which命令来找到vue命令(实际这里是注入到了全局环境变量中)执行脚本的位置

cmd 复制代码
which vue

要想知道有什么包注入了环境变量,我们先看一下全局安装了什么包:

cmd 复制代码
npm list -g -deptch -0

以下是我装的全局npm 这些包都可以通过which命令来查看:

所以可以用一句话概括就是:在终端输入vue时,终端去寻找注入的全局环境变量,找到之后,执行其对应所在环境变量的脚本位置。 我这里对应的就是:

cmd 复制代码
/Users/fengxiaodong/.nvm/versions/node/v18.16.0/bin/vue

那有的同学会疑问,为什么全局安装的是@vue/cli,但是却添加的命令是vue呢?这个问题我们留到后面解释。

vue脚本

我们进入vue脚本位置的目录,这里是所有全局npm包的命令目录,都被放在了bin文件夹下 除了vue命令外,还可以看到其他的命令,如上面提到的npmpnpm命令。

cmd 复制代码
lrwxr-xr-x  1 fengxiaodong  staff    39B  1 20 18:21 vue -> ../lib/node_modules/@vue/cli/bin/vue.js

通过上面这条信息,我可以得出以下结论:

  1. vue命令执行的是:../lib/node_modules/@vue/cli/bin/vue.js脚本
  2. 通过软链接的方式执行,因为前面有lrwxr-xr-x标识

回到上层目录中,进一步分析得出:

  1. 我们的npm包都被安装在对应的node版本目录下(v.18.16.0)
  2. bin目录是全局命令所在的文件夹目录
  3. lib目录是全局命令执行的软链接对应的文件的目录(全局包安装的真实位置)

我们通过vscode查看这个目录位置,找到了脚本文件vue.js

最终结论,我们可以用一张图概括:

  1. 在终端输入vue命令
  2. 在环境变量中找到了vue命令
  3. 终端根据vue命令链接到实际文件vue.js
  4. 终端利用node执行vue.js
  5. vue.js解析commandoption
  6. vue.js执行command
  7. 执行完毕,创建项目,退出执行

这里除了上面留下的疑问:为什么全局安装@vue/cli后却添加了vue命令;我们又多了一个疑问:为什么vue命令指向一个js文件,我们却可以直接通过vue去执行它?

为什么全局安装@vue/cli添加的却是vue命令?

前面内容已经介绍过,可以通过vscode打开vue.js,实际就是在node_modules下安装的@vue/cli目录,打开package.json,就可以看到bin的配置

bin字段就是用来指定各个内部命令对应的可执行文件的位置 ,这里写的是vue,对应的文件就是bin/vue.js。所以这就是为什么安装了@vue/cli,却添加的是vue命令的原因,如果我写的是:

json 复制代码
{
    haha: 'bin/vue.js'
}

那么添加的就是haha命令,初始化项目可能就变成了:

cmd 复制代码
haha create xxx

总结一下:当全局安装@vue/cli时,首先会把这个这个npm包下载到当前node版本的lib/node_modules目录下,同时如果配置了bin,那么则会在当前node版本的bin目录下创建一个软链接,指向这个lib目录中配置的文件vue.js,所以这个关系就理清楚了。

为什么vue命令指向一个js文件,却可以通过vue去执行它?

我们都知道,正常运行某个.js文件可以通过node xxx.js执行,利用的就是node解析器的能力,所以理论上应该是node vue.js才对,那为什么可以用的却是vue呢?

我们在终端输入vue,会得到脚手架的信息

这个结果跟直接执行which vue的路径是一样的

所以执行vue命令时,首先去环境变量中找到vue是否被注册;输入一个不存在的命令,则会提示command not found

但我们都知道which vue的路径不是真实的路径,只是一个软链接,真实的脚本文件是:vue.js

进入这个文件,可以发现这段语句(#!/usr/bin/env node),这个的作用是什么呢?

我们正常来说,自己的文件是没办法直接在终端上执行的,例如现在有一个haha.js

随意输入一段代码

执行这个文件,会显示没有权限,因为只有可读

通过chmod 777 haha.js添加可写权限

但是直接执行这个文件,还是无法输出,必须使用node去执行

但是如果在这个文件上方加入了这段代码:#!/usr/bin/env node

我们就可以直接执行文件了

其实这等同于使用 /usr/bin env node ./haha.js

所以这三个方式的执行结果都是一样的

  1. 使用node执行haha.js
  2. haha.js里面写入#!/usr/bin/env node后直接执行
  3. 使用/usr bin/env node执行haha.js

那么/usr/bin/env是什么呢?在终端输入这段语句,得到的是全部的环境变量信息

/usr/bin/env node则表示使用环境变量中node变量,所以上面总结的三种方式实际上都是使用node去执行这个文件

但是目前只能直接执行haha.js,而不是通过haha命令去执行,如果想和直接输入vue一样直接执行vue.js,是如何做到的呢?

我们期望直接输入haha就可以执行haha.js,这个时候就需要去创建软链接了,我们回到当前node版本的bin目录

通过ln -s的方式创建软链接

这样就成功的创建了一个软链接了

我们去到任意目录,输入haha,都可以成功执行vue-demo/haha.js文件了

总结一下:为什么vue命令指向的是vue.js文件,却可以通过vue去执行?原因就是因为,vue命令在bin目录下存在软链接地址,且这个地址的执行文件vue.js中有这段代码:#!/usr/bin/env node,所以在终端输入vue时,是使用环境变量node去执行了vue.js

总结

整篇文章介绍了@vue/cli从安装到执行的背后原理,理解这个背后原理对我们日后写脚手架有很大的帮助,感谢您的阅读。

相关推荐
娃哈哈哈哈呀2 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
真滴book理喻5 小时前
Vue(四)
前端·javascript·vue.js
蜜獾云5 小时前
npm淘宝镜像
前端·npm·node.js
dz88i85 小时前
修改npm镜像源
前端·npm·node.js
不是鱼6 小时前
构建React基础及理解与Vue的区别
前端·vue.js·react.js
开心工作室_kaic7 小时前
springboot476基于vue篮球联盟管理系统(论文+源码)_kaic
前端·javascript·vue.js
川石教育7 小时前
Vue前端开发-缓存优化
前端·javascript·vue.js·缓存·前端框架·vue·数据缓存
搏博7 小时前
使用Vue创建前后端分离项目的过程(前端部分)
前端·javascript·vue.js
isSamle7 小时前
使用Vue+Django开发的旅游路书应用
前端·vue.js·django
ss2738 小时前
基于Springboot + vue实现的汽车资讯网站
vue.js·spring boot·后端