◆

WebStorm 通过 ts-node 直接运行 TypeScript 文件

2023-05-16 02:450

写点 TS 小脚本或者验证某个语法行为时,标准流程是 tsc 编译成 JS 再 node 跑,两步不说,还会在目录里留下一堆编译产物。ts-node 解决的就是这个问题——它在 Node 的模块加载环节挂了一个钩子,遇到 .ts 文件时先在内存里编译成 JS 再执行,不落盘,所以能直接 ts-node foo.ts 跑起来。

配到 IDE 里的好处是能用断点调试。命令行跑脚本只能靠 console.log,在 WebStorm 里配好之后可以直接在 TS 源码上打断点、看变量、单步执行,source map 由 ts-node 处理好,断点位置和源码一致。

方法如下

  • 首先全局安装 ts-node, typescript

ts-node 只负责加载和转译,真正的编译工作交给 typescript,所以两个都要装。装全局是为了任何目录下都能用,缺点是版本固定;如果是在具体项目里用,装成项目的 devDependency 更好,版本跟着项目走:

npm install ts-node -g
npm install typescript -g
  • 安装 webstorm 的 Run Configuration for TypeScript 插件

这个插件的作用是给 .ts 文件加上右键运行的入口。没有它的话也能跑,只是要手工建一个 Node.js 运行配置,然后在 Node parameters 里填 -r ts-node/register,比较麻烦。插件把这套配置模板化了。

在 Preferences → Plugins 里搜插件名安装,装完需要重启 IDE 才会注册右键菜单项。

  • 安装完成后,右键 typescript 文件,即可运行,如图所示

下图是右键菜单,多出来的 Run '文件名.ts' 就是插件加的入口。点它会自动创建一个运行配置并立即执行,输出打在下方的 Run 面板里:

WebStorm 中右键 TypeScript 文件后弹出的菜单,包含插件提供的 Run 运行选项

可能出现的报错

我在运行过程中出现了如下报错

下图是报错内容。这类错误的共同特征是提示找不到 ts-node 或者模块解析失败,根源在于插件用的 ts-node 路径和实际安装位置不一致:

WebStorm 运行 TypeScript 文件时的报错信息,提示 ts-node 相关的模块解析失败

可能是 ts-node 的问题

为什么会路径不对:插件默认按一定顺序去找 ts-node——先看项目的 node_modules/.bin,再看全局安装目录。但全局目录的位置取决于你用什么装的 Node。用 nvm、Volta、fnm 这类版本管理工具时,全局包在各自的版本目录下(比如 ~/.nvm/versions/node/v18.x/lib/node_modules),切换 Node 版本路径就变了;Homebrew 装的又在 /opt/homebrew/lib/node_modules。插件猜不准,就报模块找不到。

想确认真实位置,命令行执行 which ts-node 看可执行文件在哪,npm root -g 看全局包目录在哪。

解决方法

思路就是在运行配置里手动把 ts-node 的路径指对,不让插件去猜。

如图所示

编辑运行配置(Run → Edit Configurations),找到 ts-node 路径相关的字段。下图是这个配置界面:

WebStorm 运行配置编辑界面中与 ts-node 路径相关的设置项

更换了 ts-node 包对应的位置即可

把路径改成 which ts-node 查到的实际位置。下图是改完之后的状态,路径指向了正确的安装目录,再运行就正常了:

修改 ts-node 路径为实际安装位置后的运行配置

其他可能的原因

如果改了路径还是不行,按下面几个方向查。

tsconfig.json 的模块配置。ts-node 默认按 CommonJS 执行,如果 tsconfig.json 里 "module": "ESNext" 而 package.json 里没写 "type": "module",会报 Cannot use import statement outside a module。快速绕过的办法是加 --compiler-options '{"module":"CommonJS"}',或者用 ts-node-esm。

类型检查太慢或者报无关的错。ts-node 默认会做完整类型检查,一个大项目里跑单个脚本也要等它检查一遍,还可能因为项目里别处的类型错误而中断。加 --swc 或 --transpile-only 跳过类型检查,只做转译,快很多——调试脚本时类型检查交给 IDE 就够了。

换用 tsx。现在我更常用 tsx 这个包替代 ts-node,它基于 esbuild,启动快、对 ESM 和 CommonJS 的兼容处理更省心,基本不用配。装上之后运行配置里把解释器换成 tsx 即可。Node 22 之后甚至内置了 --experimental-strip-types,简单脚本连工具都不用装。

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEWebStorm 通过 ts-node 直接运行 TypeScript 文件加载中