當(dāng)面試官問你運行 npm run xxx
發(fā)生了什么時,你要怎么回答?下面本篇文章給大家分享一次面試經(jīng)歷,看看作者是怎么回答的,希望對大家有所幫助!
事情是這樣的,直接開講
面試官:npm run xxx
的時候,發(fā)生了什么?講的越詳細(xì)越好。
我(心想,簡單啊): 首先,DNS 解析,將域名解析成 IP 地址,然后 TCP 連接,TCP 三次握手…
面試官:停停,我問的不是從URL輸入到頁面展現(xiàn)到底發(fā)生什么?,是npm run xxx
的時候,發(fā)生了什么。
我(尷尬,條件反射地以為是問的八股文):emmmm,我記得 npm run xxx的時候,首先會去項目的package.json文件里找scripts 里找對應(yīng)的xxx,然后執(zhí)行 xxx的命令,例如啟動vue項目 npm run serve的時候,實際上就是執(zhí)行了vue-cli-service serve 這條命令。(好險,幸好這點常識我還是懂的)
package.json文件
{ "name": "h5", "version": "1.0.7", "private": true, "scripts": { "serve": "vue-cli-service serve" }, }
面試官:嗯,不錯,那 為什么 不直接執(zhí)行vue-cli-service serve
而要執(zhí)行npm run serve
呢?
我(支支吾吾):emm,因為 npm run serve
比較簡短,比較好寫。
面試官:你再想想。
我(???不對嗎,對哦,我想起來了): 因為 直接執(zhí)行vue-cli-service serve
,會報錯,因為操作系統(tǒng)中沒有存在vue-cli-service
這一條指令
面試官: 哦,對對對,不錯不錯,喲西喲西!
我(嘿嘿,穩(wěn)了,這次我要30k): 嘻嘻!
面試官:那既然vue-cli-service
這條指令不存在操作系統(tǒng)中,為什么執(zhí)行npm run serve
的時候,也就是相當(dāng)于執(zhí)行了vue-cli-service serve
,為什么這樣它就能成功,而且不報指令不存在的錯誤呢?
我(啊?要不你還是把我鯊了吧,不想再勉強作回答):不好意思,這個我還沒了解過。
面試官:emmm,好吧,沒關(guān)系,我們做下一道算法題吧:….
….
后面無關(guān)此次文章的內(nèi)容,就省略過了。
面試官:好的,此處面試到此結(jié)束,我們會在一周內(nèi)回復(fù)您的面試結(jié)果
嗶嗶嗶…(電話掛斷)
唉??磥硎菦隽?/p>
為什么執(zhí)行npm run serve
的時候,這樣它就能成功,而且不報指令不存在的錯誤呢?
我趕緊問問了大佬朋友這一過程到底是發(fā)生了什么
經(jīng)過一番討論,終于找到了答案。
不服輸?shù)奈遥s緊回?fù)芰嗣嬖嚬俚碾娫捥柎a。
我:喂,面試官,您好,我已經(jīng)找到答案了,可以麻煩您再聽一下嗎?
面試官:嗯,可以啊,請講。
我:我們在安裝依賴的時候,是通過npm i xxx 來執(zhí)行的,例如 npm i @vue/cli-service
,npm 在 安裝這個依賴的時候,就會node_modules/.bin/
目錄中創(chuàng)建 好vue-cli-service
為名的幾個可執(zhí)行文件了。
.bin 目錄,這個目錄不是任何一個 npm 包。目錄下的文件,表示這是一個個軟鏈接,打開文件可以看到文件頂部寫著 #!/bin/sh
,表示這是一個腳本。
由此我們可以知道,當(dāng)使用 npm run serve
執(zhí)行 vue-cli-service serve
時,雖然沒有安裝 vue-cli-service
的全局命令,但是 npm 會到 ./node_modules/.bin
中找到 vue-cli-service
文件作為 腳本來執(zhí)行,則相當(dāng)于執(zhí)行了 ./node_modules/.bin/vue-cli-service serve
(最后的 serve 作為參數(shù)傳入)。
面試官:可以啊,真不錯,但是我還想繼續(xù)問問,你說.bin 目錄下的文件表示軟連接,那這個bin目錄下的那些軟連接文件是哪里來的呢?它又是怎么知道這條軟連接是執(zhí)行哪里的呢?
我(竊喜,這個我們剛剛也討論了):我們可以直接在新建的vue項目里面搜索vue-cli-service
可以看到,它存在項目最外層的package-lock.json文件中
從 package-lock.json 中可知,當(dāng)我們npm i 整個新建的vue項目的時候,npm 將 bin/vue-cli-service.js 作為 bin 聲明了。
所以在 npm install 時,npm 讀到該配置后,就將該文件軟鏈接到 ./node_modules/.bin 目錄下,而 npm 還會自動把node_modules/.bin加入$PATH,這樣就可以直接作為命令運行依賴程序和開發(fā)依賴程序,不用全局安裝了。
假如我們在安裝包時,使用 npm install -g xxx
來安裝,那么會將其中的 bin 文件加入到全局,比如 create-react-app 和 vue-cli ,在全局安裝后,就可以直接使用如 vue-cli projectName 這樣的命令來創(chuàng)建項目了。
面試官:搜噶,也就是說,npm i 的時候,npm 就幫我們把這種軟連接配置好了,其實這種軟連接相當(dāng)于一種映射,執(zhí)行npm run xxx 的時候,就會到 node_modules/bin中找對應(yīng)的映射文件,然后再找到相應(yīng)的js文件來執(zhí)行。
我(瘋狂點頭):嗯嗯,是的,就是這樣
面試官:我有點好奇。剛剛看到在node_modules/bin中 有三個vue-cli-service文件。為什么會有三個文件呢?
我:如果我們在 cmd 里運行的時候,windows 一般是調(diào)用了 vue-cli-service.cmd
,這個文件,這是 windows 下的批處理腳本:
@ECHO off GOTO start :find_dp0 SET dp0=%~dp0 EXIT /b :start SETLOCAL CALL :find_dp0 IF EXIST "%dp0%node.exe" ( SET "_prog=%dp0%node.exe" ) ELSE ( SET "_prog=node" SET PATHEXT=%PATHEXT:;.JS;=;% ) endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%..@vuecli-servicebinvue-cli-service.js" %*
所以當(dāng)我們運行vue-cli-service serve
這條命令的時候,就相當(dāng)于運行 node_modules/.bin/vue-cli-service.cmd serve
。
然后這個腳本會使用 node 去運行 vue-cli-service.js
這個 js 文件
由于 node 中可以使用一系列系統(tǒng)相關(guān)的 api ,所以在這個 js 中可以做很多事情,例如讀取并分析運行這條命令的目錄下的文件,根據(jù)模板生成文件等。
# unix 系默認(rèn)的可執(zhí)行文件,必須輸入完整文件名 vue-cli-service # windows cmd 中默認(rèn)的可執(zhí)行文件,當(dāng)我們不添加后綴名時,自動根據(jù) pathext 查找文件 vue-cli-service.cmd # Windows PowerShell 中可執(zhí)行文件,可以跨平臺 vue-cli-service.ps1
面試官:原來如此,不錯嘛小伙子,短短時間內(nèi)就掌握清楚了,看來學(xué)習(xí)能力很強,不錯不錯,我很看好你,我會催h(yuǎn)r盡快回復(fù)你的。先這樣了,拜拜
我(欣喜若狂,功夫不負(fù)有心人?。汉冒?,好啊,拜拜
嗶嗶嗶…(電話掛斷)
過了三十分鐘….
今天是個好日子,心想的事兒都能成,今天是個好日子,打開了家門咱迎春風(fēng)…(手機鈴聲響起)。
我:喂,您好。
hr:您好,我是xxx公司的hr,根據(jù)你面試的優(yōu)秀表現(xiàn),恭喜你獲得了我司的offer,經(jīng)過我最大的努力,我給你爭取到了最大的薪資,薪資是月薪3500,您看滿意嗎?
我:….
嗶嗶嗶….(電話掛斷)
tmd,c
總結(jié)
-
運行 npm run xxx的時候,npm 會先在當(dāng)前目錄的 node_modules/.bin 查找要執(zhí)行的程序,如果找到則運行;
-
沒有找到則從全局的 node_modules/.bin 中查找,npm i -g xxx就是安裝到到全局目錄;
-
如果全局目錄還是沒找到,那么就從 path 環(huán)境變量中查找有沒有其他同名的可執(zhí)行程序。
原文地址:https://juejin.cn/post/7078924628525056007
作者:陽光是sunny