導讀:興許所有程序員都有命名困難癥,在考慮變量、常量、方法、類、文件等命名時,總會千方百計嘗試一些語義化的方式去實現。
曾經有那么一段時間,一些node初學的同學遇到了同樣的問題:Hello World 跑不動!
原文首發于個人博客:這事要從node node.js說起
0. 謎之 Hello World問題的起源非常簡單,當我們在編寫一個入門程序時,就會迅速想起那句膾炙人口的語句:
console.log("Hello World");
于是乎,順手保存為node.js,緊接著嘗試以node node.js來運行該示例程序。毫無疑問,在cmd環境下,會遇到如下的報錯:
(PS:實際上無論是Mac、Linux用戶,亦或是WIndows中使用Powershell或其他終端環境的同學都無法與此問題完美邂逅)
1. 初步分析此時此刻,心中一陣失落,居然連入門的示例程序都無法運行,不禁一陣瞎想:是否該放棄node.js了?
言歸正傳,細心的同學會發現,報錯的源頭來自Windows Script Host,下簡稱WSH,我們不難查到它是 Windows 操作系統腳本語言程序(script,即:腳本)的運行環境。
2. 執行了什么?簡單分析一下node node.js這條命令,我們會很自然地認定為:執行node.exe程序,參數為node.js。
然而實際上,真正執行的程序卻變成WSH,前面執行的命令node node.js并沒有任何跟調起WSH相關的邏輯,因此為何調起了WSH成為了解謎的關鍵。
順蔓摸瓜,由于WSH正好是執行腳本的服務,而js恰恰又是腳本的一種,不妨假設node.js這個腳本文件就是罪魁禍首。然后創建一個test.js的副本,嘗試執行它:
2.1 執行程序的路徑根據試驗的結果不難猜出node node.js命令實際執行了node.js這個腳本文件,從而調起WSH服務,進而出現上圖的報錯。
順水推舟可確定node node.js等價于. ode.js node.js,即命令執行的文件完整的路徑為:E: est ode.js。
(PS:各位看官切莫介懷""作為路徑分隔符,畢竟在cmd下"/"擔任參數分隔符的要職)
2.2 補全程序的路徑先講講通用的說法,無論是 * nix 、OS/2 、DOS 亦或是 windows,其terminal都可以通過一個特殊的環境變量PATH進行“補全”(關于環境變量的詳細內容本文不作介紹)。
接下來我們通過ping命令先做簡要說明:
2.2.1 定位程序的路徑很明顯,在任何一臺正常的機器上,這條命令執行后都能得到期待的結果。此時我們可以看到該cmd進程下的PATH環境變量中包含C:WINDOWSsystem32,通過對PATH中的元素(文件夾路徑)即可將ping程序的路徑補全為:C:WINDOWSsystem32ping。(在 * nix 系統下依然通用)
2.2.2 補全后綴名(僅windows、dos)由于windows的可執行的概念和 * nix 略有不同,因此在windows平臺下還需要對程序進行后綴名的補全。
其中在 * inx下,只需保證文件的結構符合規范,并且擁有可執行權限,就可以執行;而在windows下,還需要考慮其后綴名及執行方式(實際上是一種打開方式的策略)。
E: est>echo %PATHEXT% .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW;.CPL
最終我們補全的程序路徑為:C:WINDOWSsystem32ping.exe,
2.2.3 特別注意(僅windows、dos)針對于cmd環境,當前目錄也會作為路徑補全的一部分,并且優先級最高。在當前目錄下,我們創建一個ping.bat的腳本,并填充以下內容:
@echo off :: 輸出完整的路徑和文件名及后綴 echo %~dpnx0
執行結果如下圖,原來的ping.exe的動作明顯被覆蓋了。
2.2.4 小結我們也額外地發現windows的默認可執行的后綴名包含.JS,由此可推斷最初的那條node node.js命令最終補全的程序路徑為:E: est ode.js
3 打開方式?從2.2.4的結論中能顯而易見的推導出命令執行的程序為node.js腳本文件,那么它為什么是通過WSH去執行的呢?
答案其實很明顯,有個通俗易懂的概念,叫做打開方式,而windows的打開方式由assoc和ftype確定。
3.1 后綴名與打開方式嘗試性的跑一跑assoc命令,發現其控制著后綴名與打開方式ftype的關系。
assoc | findstr .js
運行結果:
.js=JSFile .json=VisualStudio.json.14.0 .jsonld=VisualStudio.jsonld.14.0 .jsx=VisualStudio.jsx.14.0 .jsxbin=JSXBINFile .jsxinc=JSXINCFile
不難看出.js文件將會通過JSFile這個打開方式去執行。
3.2 打開方式與執行程序類似的,我們也可以運行一下ftype命令,其定義了可執行程序以及調用的參數。
ftype | findstr "JS"
運行結果:
JSEFile=C:WindowsSystem32WScript.exe "%1" %* JSFile=C:WindowsSystem32WScript.exe "%1" %* JSXFile="C:Program Files (x86)AdobeAdobe Utilities - CS6ExtendScript Toolkit CS6ExtendScript Toolkit.exe" -run "%1"
其中最關鍵的信息為JSFile=C:WindowsSystem32WScript.exe "%1" %*,含義是通過WScript.exe執行js腳本,并將原來的參數傳遞過去。
最終node node.js等價于E: est ode.js node.js。
3.3 怎么破?發動想象力吧,別再叫node.js了~
是時候切換到 * inx 或者升級到powershell了~
如果不介意使用絕對路徑的話……
4. 擴展學習操作系統層面通過PATH等環境變量進行資源定位的思路實際上也被廣泛應用在各種場景下,下面也舉兩個常見的栗子說明一下。
4.1 npm 包定位CommonJS 規范中通過require去加載模塊時,通過路徑補全的策略(詳情推薦閱讀《深入淺出Node.js》),可以省略模塊的路徑,后綴名,甚至連/index也能自動補全。
4.2 webpack資源定位嘿,resolve中的extensions、alias等思路是否也如出一轍呢?
5. 總結全文原創·此文為隨走隨記,全文思維略帶感情請勿拍磚。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/84972.html
摘要:現狀最近在寫歡迎的時候,一直為錯誤的棧追蹤而愁。由于送入隊列的是函數,因此在的參數可以放心地使用。其次,這些函數并不是立即在中調用的,而是由專門的隊列處理代碼來調用。 本文的講述都是以 Node.js 環境為例子,而 Node.js 使用的 JavaScript 引擎是 V8,因此理論上 Chrome 也能適用,其它瀏覽器我就不清楚了。 現狀 最近在寫 Rize(歡迎 star) 的時...
摘要:模塊化編程,已經成為一個迫切的需求。隨著網站功能逐漸豐富,網頁中的也變得越來越復雜和臃腫,原有通過標簽來導入一個個的文件這種方式已經不能滿足現在互聯網開發模式,我們需要團隊協作模塊復用單元測試等等一系列復雜的需求。 隨著網站逐漸變成互聯網應用程序,嵌入網頁的Javascript代碼越來越龐大,越來越復雜。網頁越來越像桌面程序,需要一個團隊分工協作、進度管理、單元測試等等......開發...
摘要:你們說能不能就用的開發模式來實現客戶端啊這樣版版版就都有了。有道云筆記可能就是最貼近我們想法的產品,有客戶端,有版。這個項目由發起和維護。 最近一個多月一直在用 AngularJS 做公司的一個項目(還沒有做完),我之前主要是用 PHP 開發服務端的,AngularJS 也是現學現賣,整個過程還是比較有意義的,覺得很有必要寫篇文章記錄一下。 緣起 事情是這樣的……我們團隊的產品是一款 ...
閱讀 2661·2023-04-26 00:42
閱讀 2810·2021-09-24 10:34
閱讀 3823·2021-09-24 09:48
閱讀 4161·2021-09-03 10:28
閱讀 2583·2019-08-30 15:56
閱讀 2777·2019-08-30 15:55
閱讀 3269·2019-08-29 12:46
閱讀 2250·2019-08-28 17:52