[英]Why can't my globally installed npm package call ts-node?
好的,我正在尝试创建一个自己使用的CLI工具,基本上它只是解析hcitool的标准输出(有关周围蓝牙设备的报告)。
该工具可以在这里找到: https : //github.com/lu4/hcitool-reader
该工具预计将使用ts-node
运行(ts-node允许即时运行TypeScript代码)。
使用以下命令从本地磁盘全局安装时,我的软件包可以正常工作:
bash> npm i -g /path/to/local/disk/hcitool-reader/repository
可以通过执行以下命令来验证该工具(安装后):
bash> hcitool-reader
但是,如果我删除旧版本并从NPM安装相同的代码:
bash> npm uninstall -g hcitool-reader && npm i -g hcitool-reader
程序包开始引发node.js语法异常,指出打字稿语法错误(这表明ts-node未正确注册)。
bash> hcitool-reader
Trying to register ts-node with tsconfig.json found at:
/home/pi/.config/versions/node/v12.8.0/lib/node_modules/hcitool-reader/tsconfig.json
/home/pi/.config/versions/node/v12.8.0/lib/node_modules/hcitool-reader/src/index.ts:1
import 'reflect-metadata';
^^^^^^^^^^^^^^^^^^
SyntaxError: Unexpected string
at Module._compile (internal/modules/cjs/loader.js:811:22)
at Module._extensions..js (internal/modules/cjs/loader.js:879:10)
at Object.require.extensions.<computed> [as .ts] (/home/pi/.config/versions/node/v12.8.0/lib/node_modules/hcitool-reader/node_modules/ts-node/src/index.ts:465:14)
at Module.load (internal/modules/cjs/loader.js:731:32)
at Function.Module._load (internal/modules/cjs/loader.js:644:12)
at Module.require (internal/modules/cjs/loader.js:771:19)
at require (internal/modules/cjs/helpers.js:68:18)
at Object.<anonymous> (/home/pi/.config/versions/node/v12.8.0/lib/node_modules/hcitool-reader/bootstrap.js:15:20)
at Module._compile (internal/modules/cjs/loader.js:868:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:879:10)
关于此错误的怪异之处是,代码仅在位于NPM的全局软件包文件夹中时才停止工作:
/home/pi/.config/versions/node/v12.8.0/lib/node_modules/hcitool-reader
在所有其他情况下,在所有其他位置,该代码均可正常运行。
问: ts-node怎么了?
编辑在我看来,这是一个ts-node
问题,我在他们的仓库中创建了一个问题 ,等待ts-node
团队的一些意见
这是因为您已经编写了bin/launch.js
脚本来与node
而不是ts-node
一起运行。 脚本的第一行是:
#!/usr/bin/env node
// ^^ launch with node.js
如果要使用ts-node启动它,则应将其更改为:
#!/usr/bin/env ts-node
脚本的第一行是通常所说的sh-bang行(为此有很多不同的拼写)。 它是sh / csh兼容的语法,已被大多数常见的shell语言继承:bash / ksh / tcsh / tcl / node。
严格来说,它不是javascript语法,应该会导致语法错误,但如果它是第一行代码,则node.js会特别容忍它。 它将js文件解释为多语言源(源代码在多种编程语言中有效)。
shell(bash / ksh / tcsh等)假定所有脚本都是用shell自己的语言编写的(bash用于bash,ksh用于ksh等)。 sh-bang语法实际上使您的文件成为有效的Shell脚本源文件。 在所有常见的unix shell中,sh-bang命令的意思是:
评估此字符串,然后将此文件的其余部分作为注释,然后将此文件作为要评估的字符串的最后一个参数传递。
因此,如果文件的第一行是:
#! /usr/bin/env wget https://stackoverflow.com/questions/57600624
该脚本将下载此页面。
/usr/bin/env
部分将运行env
命令,该命令将加载当前的用户环境,然后执行该行的其余部分。 我们运行env
的原因是,默认情况下sh-bang语法不会加载您的用户环境,这意味着您需要传递node
或ts-node
的绝对路径,如果您在其他发行版上运行脚本,则该路径可能会中断(ubuntu与redhat),或者如果您以其他方式安装node
或ts-node
(apt-get与nvm)。 因此,首先调用env
可以确保正确设置了$PATH
环境变量,并且在所有类似Unix / Unix的系统中, 始终将env
安装在/usr/bin
。
NPM并非现在也仍然不是专门设计为节点程序包管理器。 是的,它具有支持node.js的许多有用功能(有些甚至将node_modules甚至硬编码在node.js中),但实际上它并不关心您的软件是用哪种语言编写的。它是OS的软件包管理器,就像apt
和yum
(或Mac用户使用brew
)。 因此,它不具有运行全局可执行文件的特定于节点的支持-它仅取决于您的OS / shell已支持的内容。 在这种情况下,取决于sh-bang线。
安装全局脚本时, npm
不在package.json中使用start
命令。 它直接运行您的脚本。 这是因为它不是特定于节点的程序包管理器,因此它安装的内容可能是Python脚本,shell脚本或以汇编语言编写的二进制可执行文件。 这就是为什么您需要确保您的"bin"
脚本通常可由操作系统执行。
通常,可执行文件意味着如果执行此操作:
./bin/launch.js
然后您的操作系统就可以像系统上的所有其他程序一样执行它: node
, apt-get
, git
等。不正常的情况是:
ts-node ./bin/launch.js
要么:
java -jar ./minecraft.jar
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.