繁体   English   中英

为什么我全局安装的npm软件包不能调用ts-node?

[英]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-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语法不会加载您的用户环境,这意味着您需要传递nodets-node的绝对路径,如果您在其他发行版上运行脚本,则该路径可能会中断(ubuntu与redhat),或者如果您以其他方式安装nodets-node (apt-get与nvm)。 因此,首先调用env可以确保正确设置了$PATH环境变量,并且在所有类似Unix / Unix的系统中, 始终env安装在/usr/bin

NPM不是节点程序包管理器!

NPM并非现在也仍然不是专门设计为节点程序包管理器。 是的,它具有支持node.js的许多有用功能(有些甚至将node_modules甚至硬编码在node.js中),但实际上它并不关心您的软件是用哪种语言编写的。它是OS的软件包管理器,就像aptyum (或Mac用户使用brew )。 因此,它不具有运行全局可执行文件的特定于节点的支持-它仅取决于您的OS / shell已支持的内容。 在这种情况下,取决于sh-bang线。

安装全局脚本时, npm不在package.json中使用start命令。 它直接运行您的脚本。 这是因为它不是特定于节点的程序包管理器,因此它安装的内容可能是Python脚本,shell脚本或以汇编语言编写的二进制可执行文件。 这就是为什么您需要确保您的"bin"脚本通常可由操作系统执行。

通常,可执行文件意味着如果执行此操作:

./bin/launch.js

然后您的操作系统就可以像系统上的所有其他程序一样执行它: nodeapt-getgit等。不正常的情况是:

ts-node ./bin/launch.js

要么:

java -jar ./minecraft.jar

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM