上一篇文章,已经大致了解脚手架是什么以及脚手架是如何工作的。接下来,稍微深入一下脚手架的工作过程(以vue-cli为例)。首先抛出3个问题:
1.明明全局安装的是@vue/cli,最后执行的命令却是vue?
2.全局安装@vue/cli时发生了什么?
3.执行vue命令时发生了什么,为什么vue指向某个文件,我们却可以直接通过vue命令执行它?
弄清楚这3个问题,基本上对脚手架的原理已经有个大体的认识,文章最后会详解自定义npm命令哦~
首先,第一个问题为什么安装的是@vue/cli,执行的命令是vue,先找到npm文件夹:
这是vue命令的执行文件,打开会发现有这样一行代码:
1 endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\node_modules\vue-cli\bin\vue" %*
这行代码的作用是,将当前命令指向\node_modules\vue-cli\bin\vue,所以即使我们用的命令是vue,最终还是指向@vue/cli内部的文件。
第二个问题,全局安装@vue/cli时发生了什么:
1.下载node_modules
2.在package.json里面配置bin的软链接:
第三个问题,vue命令最终会指向vue-cli内的某个文件,为什么可以执行它:
前面我们已经知道,vue命令执行的时候,会先找到vue文件(AppData\Roaming\npm\vue.cmd)并执行,执行这个vue文件的时候,会发现这是一个软链接,实际指向的是:\node_modules\vue-cli\bin\vue 该路径的vue文件,最后才会执行这个文件。那么问题来了,vue命令指向的这个文件,是如何执行的?前端的同学们都知道,node环境下执行js文件,需要加一个node命令前缀,才可以执行该js文件。那这个地方的文件,是如何执行的呢?我们找到vue-cli\bin\vue文件:
打开会是下面这几行代码:
1 #!/usr/bin/env node 2 3 const program = require('commander') 4 5 program 6 .version(require('../package').version) 7 .usage('<command> [options]') 8 .command('init', 'generate a new project from a template') 9 .command('list', 'list available official templates') 10 .command('build', 'prototype a new project') 11 .command('create', '(for v3 warning only)') 12 13 program.parse(process.argv)
没错,主要就是第一行代码:
1 #!/usr/bin/env node
这行代码的作用,它会在我们的环境变量中找到node命令,并用node命令执行该文件!致此,这三个问题都已经有了答案,现在再来看一下:vue create vue-test这条命令的执行过程:
1.在终端输入:vue create vue-test
2.终端解析出vue命令
3.终端在环境变量中找到vue命令
4.终端根据vue命令链接到实际文件vue
5.终端利用node执行vue文件
6.vue解析command/options
7.vue执行command
8.执行完毕,退出
现在是不是对脚手架的工作原理理解更深刻一点了呢,其中的command将会在以后开发脚手架的时候会单独拿出来讨论。
下面介绍自定义npm指令以及其软链接到其它文件:
首先在npm文件夹下新建一个wang.cmd:
1 @ECHO off 2 GOTO start 3 :find_dp0 4 SET dp0=%~dp0 5 EXIT /b 6 :start 7 SETLOCAL 8 CALL :find_dp0 9 10 IF EXIST "%dp0%\node.exe" ( 11 SET "_prog=%dp0%\node.exe" 12 ) ELSE ( 13 SET "_prog=node" 14 SET PATHEXT=%PATHEXT:;.JS;=;% 15 ) 16 17 endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\node_modules\vue-cli\bin\wang" %*
最终指向到vue-cli\bin\wang:
1 #!/usr/bin/env node 2 3 console.log('wang')
执行wang:
最后:脚踏实地行,海阔天空飞!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端