导读:兴许所有程序员都有命名困难症,在考虑变量、常量、方法、类、文件等命名时,总会千方百计尝试一些语义化的方式去实现。
曾经有那么一段时间,一些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. 总结全文原创·此文为随走随记,全文思维略带感情请勿拍砖。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/84972.html
摘要:现状最近在写欢迎的时候,一直为错误的栈追踪而愁。由于送入队列的是函数,因此在的参数可以放心地使用。其次,这些函数并不是立即在中调用的,而是由专门的队列处理代码来调用。 本文的讲述都是以 Node.js 环境为例子,而 Node.js 使用的 JavaScript 引擎是 V8,因此理论上 Chrome 也能适用,其它浏览器我就不清楚了。 现状 最近在写 Rize(欢迎 star) 的时...
摘要:模块化编程,已经成为一个迫切的需求。随着网站功能逐渐丰富,网页中的也变得越来越复杂和臃肿,原有通过标签来导入一个个的文件这种方式已经不能满足现在互联网开发模式,我们需要团队协作模块复用单元测试等等一系列复杂的需求。 随着网站逐渐变成互联网应用程序,嵌入网页的Javascript代码越来越庞大,越来越复杂。网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等......开发...
摘要:你们说能不能就用的开发模式来实现客户端啊这样版版版就都有了。有道云笔记可能就是最贴近我们想法的产品,有客户端,有版。这个项目由发起和维护。 最近一个多月一直在用 AngularJS 做公司的一个项目(还没有做完),我之前主要是用 PHP 开发服务端的,AngularJS 也是现学现卖,整个过程还是比较有意义的,觉得很有必要写篇文章记录一下。 缘起 事情是这样的……我们团队的产品是一款 ...
阅读 2477·2023-04-26 00:42
阅读 2783·2021-09-24 10:34
阅读 3786·2021-09-24 09:48
阅读 4123·2021-09-03 10:28
阅读 2548·2019-08-30 15:56
阅读 2754·2019-08-30 15:55
阅读 3215·2019-08-29 12:46
阅读 2212·2019-08-28 17:52