五分钟了解 Node.js Shebang

本文最初发布于 Medium 网站,经原作者授权由 InfoQ 中文站翻译并分享。
$ node yourfile.js
$ ./yourfile.js
仅当你对该文件有执行权限(例如,可以使用 chmod u+x yourfile.js 设置)并设置了正确的“Shebang”时,此方法才有效。
#!/absolute/path/to/the/interpreter [optional params]
#!/usr/bin/node
只有 Shebang 在文件的第一行时,Node.js 才会高兴地将其忽略为注释(即使它前面有空行或 //comment 行也不会起作用)。浏览器也会将其忽略(Chrome74+,FF67+)。
https://github.com/tc39/proposal-hashbang
多数人在 /usr/bin/node 上都有一个 Node.js 二进制文件或符号链接。如果 Node.js 不在 /usr/bin/node 上,操作系统就会抱怨了。例如 bash 会说 bad interpreter: No such file or directory script won’t execute。但有没有办法告诉操作系统使用 Node.js 运行脚本,而不用在乎它安装在哪里呢?
#!node
是没用的,因为 Shebang 需要绝对路径。
env 主要用于在修改后的环境中运行命令。这里的重点是“命令”,因为 env 几乎总是位于 /usr/bin/env,而“命令”可以是 PATH 上的任何内容。
如果我们不是写 /usr/bin/node 而是写 /usr/bin/env node,我们就会告诉 OS 运行 env,而 env 将运行 node,最后 node 将依次执行脚本。
#!/usr/bin/env node
但是,env 还可以使用其他一些技巧。
将 -S 选项传递给 env 会使它解析之后发生的一切,从而打开一扇新的大门:将参数传递给命令。
#!/usr/bin/env -S node --experimental-module
#!/usr/bin/env -S node -r ./my/other/file.js
#!/usr/bin/env -S node --inspect
请注意,如果你运行诸如 nodeyourfile.js 之类的脚本,Node.js 将不会尝试解析 Shebang 中的参数,而只会忽略它。内核在运行文件之前使用 Shebang 来确定如何运行它。
#!/usr/bin/env -S NODE_ENV=production node
#!/usr/bin/env -S NODE_OPTIONS=--experimental-modules node
#!/usr/bin/env -S -i node
#!/usr/bin/env -S - node
#!/usr/bin/env -S -u=DEBUG - node
如果用户以 DEBUG=* ./yourfile.js 运行脚本,他们将看不到任何调试信息,但你还是可以用 DEBUG=* node ./yourfile.js 运行脚本,从而看到 DEBUG 输出。
有时你想锁定用于运行脚本的 node 版本。在 NPM@3 之前,我们可以使用 engineStrict,但是该功能已移除,现在我们只能在 package.json 中设置 engines,它可能位于脚本旁边也可能不在,取决于 engine-strictconfig 配置标志的设置。
https://docs.npmjs.com/files/package.json#engines
#!/usr/bin/env -S npx node@6
这可能会在运行脚本后尝试下载请求的 Node 版本(因此,如果 NPX 缓存中不存在所请求版本的 Node,则无法在没有互联网连接的情况下运行)。
提示:你可以使用 process.version 检查节点版本。
#!/usr/bin/env ts-node
并让它作为 TypeScript 程序运行文件。在这些示例中,文件都可以使用.js 扩展名或你喜欢的其他任何文件类型,甚至可以没有扩展!
https://medium.com/@alexewerlof/node-Shebang-e1d4b02f731d