一、脚手架实现原理
回答以下3个问题,就基本掌握了脚手架的实现原理。
1.1 问题一
Question: 为什么全局安装 @vue/cli
后添加的命令为 **vue**
?
npm install -g @vue/cli
Answer:
- 通过
which vue
命令查看实际文件路径。
进入命令所在的文件目录
cd /Users/bgl/.nvm/versions/node/v12.14.0/bin
,通过ll
命令发现vue
命令实际上是一个软链接,指向../lib/node_modules/@vue/cli/bin/vue.js
。但这样的一个绑定关系是在哪里指定的呢?进入
node/v12.14.0/lib/node_modules/@vue/cli
目录,在 package.json 中有个 bin 字段。这个字段配置的就是操作系统在安装完成之后软链接的名称以及指向的实际文件。
bin A lot of packages have one or more executable files that they’d like to install into the PATH. npm makes this pretty easy (in fact, it uses this feature to install the “npm” executable.)
To use this, supply a
**bin**
field in your package.json which is a map of command name to local file name. On install, npm will symlink that file intoprefix/bin
for global installs, or./node_modules/.bin/
for local installs.
1.2 问题二
Question: 全局安装 @vue/cli
时发生了什么?
npm install -g @vue/cli
Answer:
- npm 将这个包下载到全局的
node_modules
目录下。 - 然后解析
package.json
文件,当看到有bin
字段配置时,会在 node 安装主目录的 bin 目录下,创建一个软链接。
1.3 问题三
Question: 执行 vue
命令时发生了什么?vue
命令通过软链接指向一个JS 文件,正常情况下对于JS文件的执行需要通过node来运行,但我们为什么可以直接通过 vue
命令来执行这个JS文件 ?
Answer:
- 操作系统会根据
which vue
命令下的路径,找到vue
命令,然后执行该文件。相当于在环境变量中查找该指令(echo $PATH
),若找不到,则报错并跳转至end,如下图所示。
- 通过软链接找到真实要执行的文件,会发现该文件第一行有如下一段代码:
**#!/usr/bin/env node**
。这句话其实告诉操作系统,在调用这个文件的时候,在我们的环境变量中去查找 node 这个命令,并用该命令去执行,等同于运行/usr/bin/env node xxx.js
(注:/usr/bin/env
是个可执行的 Shell 命令,运行该命令会输出环境变量)。
1.4 衍生知识
知识点一:如何创建一条命令,如命令test
(命令test
对应文件 test.js 的执行)
- 手动创建一个
test.js
文件,并在文件起始处添加如下一行:#!/usr/bin/env node
。 - 查找环境变量
echo $PATH
,找到 node 命令的bin
目录,并进入该目录下cd ~/.nvm/versions/node/v12.14.0/bin/
。 - 在 node 的
bin
目录下创建一个软链接**ln**`` -s /Users/bgl/test/test/js test
。
此时就可以在任意地方直接运行 test
命令。
知识点2:下面两种写法的区别?
#!/usr/bin/env node
#!/usr/bin/node
第一种是在环境变量/usr/bin/env
中查找 node 命令。第二种是直接执行 /usr/bin/
目录下的 node 命令,本质上是把 node 命令存放的目录固化了,但每个人的电脑环境变量配置可能不一样,第二种方式运行时可能会出错。故第一种方式更好些,因为是让环境变量去找 node 命令。
二、脚手架原理进阶
掌握上述内容后,还可以继续尝试回答以下 2 个问题。
2.1 进阶问题一
Question: 为什么说脚手架本质是操作系统的客户端?它和我们在PC上安装的应用/软件有什么区别?
Answer:
脚手架的执行是依靠 node 命令,node 是操作系统的一个客户端。而运行的 vue.js
仅仅是 node 运行时的参数,即将文件读取成字符串后作为参数注入到 node 当中,与运行 node -e "console.log('hello world')"
这条命令无本质差异。
它和我们在PC上安装的应用/软件本质上没有区别。
2.2 进阶问题二
Q: 如何为 node
脚手架创建别名?
A: 可通过软链接嵌套的方式来创建别名,如利用ln
命令。
ln(英文全拼:link files)命令是一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接。
必要参数:
- -b 删除,覆盖以前建立的链接
- -n 把符号链接视为一般目录
- -s 软链接(符号链接)