事情是这样的,直接开讲 面试官:npmrunxxx的时候,发生了什么?讲得越详细越好。 我(心想,简单啊):首先,DNS解析,将域名解析成IP地址,然后 TCP连接,TCP三次握手。。。 面试官:停停,我问的不是从URL输入到页面展现到底发生什么?,是npmrunxxx的时候,发生了什么。 我(尴尬,条件反射地以为是问的八股文):emmmm,我记得npmrunxxx的时候,首先会去项目的package。json文件里找scripts里找对应的xxx,然后执行xxx的命令,例如启动vue项目npmrunserve的时候,实际上就是执行了vuecliserviceserve这条命令。(好险,幸好这点常识我还是懂的) package。json文件{name:h5,version:1。0。7,private:true,scripts:{serve:vuecliserviceserve},} 面试官:嗯,不错,那为什么不直接执行vuecliserviceserve而要执行npmrunserve呢? 我(支支吾吾):emm,因为npmrunserve比较简短,比较好写。 面试官:你再想想。 我(啊?不对吗,对哦,我想起来了):因为直接执行vuecliserviceserve,会报错,因为操作系统中没有存在vuecliservice这一条指令 面试官:哦,对对对,不错不错,哟西哟西! 我(嘿嘿,稳了,这次我要30k):嘻嘻! 面试官:那既然vuecliservice这条指令不存在操作系统中,为什么执行npmrunserve的时候,也就是相当于执行了vuecliserviceserve,为什么这样它就能成功,而且不报指令不存在的错误呢? 我(啊?要不你还是把我鲨了吧,不想再勉强作回答):不好意思,这个我还没了解过。 面试官:emmm,好吧,没关系,我们做下一道算法题吧:。。。。 。。。。 后面无关此次文章的内容,就省略过了。 面试官:好的,此处面试到此结束,我们会在一周内回复您的面试结果 哔哔哔。。。(电话挂断) 唉。看来是凉了 为什么执行npmrunserve的时候,这样它就能成功,而且不报指令不存在的错误呢? 我赶紧问问了大佬朋友这一过程到底是发生了什么 经过一番讨论,终于找到了答案。 不服输的我,赶紧回拨了面试官的电话号码。 我:喂,面试官,您好,我已经找到答案了,可以麻烦您再听一下吗? 面试官:嗯,可以啊,请讲。 我:我们在安装依赖的时候,是通过npmixxx来执行的,例如npmivuecliservice,npm在安装这个依赖的时候,就会nodemodules。bin目录中创建好vuecliservice为名的几个可执行文件了。 。bin目录,这个目录不是任何一个npm包。目录下的文件,表示这是一个个软链接,打开文件可以看到文件顶部写着!binsh,表示这是一个脚本。 由此我们可以知道,当使用npmrunserve执行vuecliserviceserve时,虽然没有安装vuecliservice的全局命令,但是npm会到。nodemodules。bin中找到vuecliservice文件作为脚本来执行,则相当于执行了。nodemodules。binvuecliserviceserve(最后的serve作为参数传入)。 面试官:可以啊,真不错,但是我还想继续问问,你说。bin目录下的文件表示软连接,那这个bin目录下的那些软连接文件是哪里来的呢?它又是怎么知道这条软连接是执行哪里的呢? 我(窃喜,这个我们刚刚也讨论了):我们可以直接在新建的vue项目里面搜索vuecliservice 可以看到,它存在项目最外层的packagelock。json文件中 从packagelock。json中可知,当我们npmi整个新建的vue项目的时候,npm将binvuecliservice。js作为bin声明了。 所以在npminstall时,npm读到该配置后,就将该文件软链接到。nodemodules。bin目录下,而npm还会自动把nodemodules。bin加入PATH,这样就可以直接作为命令运行依赖程序和开发依赖程序,不用全局安装了。 假如我们在安装包时,使用npminstallgxxx来安装,那么会将其中的bin文件加入到全局,比如createreactapp和vuecli,在全局安装后,就可以直接使用如vuecliprojectName这样的命令来创建项目了。 面试官:搜噶,也就是说,npmi的时候,npm就帮我们把这种软连接配置好了,其实这种软连接相当于一种映射,执行npmrunxxx的时候,就会到nodemodulesbin中找对应的映射文件,然后再找到相应的js文件来执行。 我(疯狂点头):嗯嗯,是的,就是这样 面试官:我有点好奇。刚刚看到在nodemodulesbin中有三个vuecliservice文件。为什么会有三个文件呢? 我:如果我们在cmd里运行的时候,windows一般是调用了vuecliservice。cmd,这个文件,这是windows下的批处理脚本:ECHOoffGOTOstart:finddp0SETdp0dp0EXITb:startSETLOCALCALL:finddp0IFEXISTdp0ode。exe(SETprogdp0ode。exe)ELSE(SETprognodeSETPATHEXTPATHEXT:;。JS;;)endLocalgotoundefined2NULtitleCOMSPECprogdp0。。vuecliservicebinvuecliservice。js 所以当我们运行vuecliserviceserve这条命令的时候,就相当于运行nodemodules。binvuecliservice。cmdserve。 然后这个脚本会使用node去运行vuecliservice。js这个js文件 由于node中可以使用一系列系统相关的api,所以在这个js中可以做很多事情,例如读取并分析运行这条命令的目录下的文件,根据模板生成文件等。unix系默认的可执行文件,必须输入完整文件名vuecliservicewindowscmd中默认的可执行文件,当我们不添加后缀名时,自动根据pathext查找文件vuecliservice。cmdWindowsPowerShell中可执行文件,可以跨平台vuecliservice。ps1 面试官:原来如此,不错嘛小伙子,短短时间内就掌握清楚了,看来学习能力很强,不错不错,我很看好你,我会催hr尽快回复你的。先这样了,拜拜 我(欣喜若狂,功夫不负有心人啊):好啊,好啊,拜拜 哔哔哔。。。(电话挂断) 过了三十分钟。。。。 今天是个好日子,心想的事儿都能成,今天是个好日子,打开了家门咱迎春风。。。(手机铃声响起)。 我:喂,您好。 hr:您好,我是xxx公司的hr,根据你面试的优秀表现,恭喜你获得了我司的offer,经过我最大的努力,我给你争取到了最大的薪资,薪资是月薪3500,您看满意吗? 我:。。。。 哔哔哔。。。。(电话挂断) tmd,c 总结运行npmrunxxx的时候,npm会先在当前目录的nodemodules。bin查找要执行的程序,如果找到则运行;没有找到则从全局的nodemodules。bin中查找,npmigxxx就是安装到到全局目录;如果全局目录还是没找到,那么就从path环境变量中查找有没有其他同名的可执行程序。参考文章 https:blog。51cto。comu150775334531157 https:juejin。cnpost6971723285138505765 原文地址: https:www。cnblogs。comsunnyluckyp16054660。html