如何在TypeScript中通过ts-node使用Rapier物理引擎?
Rapier物理引擎动态导入在ts-node环境下报MODULE_NOT_FOUND错误
问题背景
我基于Rust编写的Rapier物理引擎JS绑定,封装了一层名为com.hydroper.matter的便捷调用层,目的是将动态模块的生命周期与JS程序的静态生命周期绑定。官方入门的动态加载方式为:
import('@dimforge/rapier2d').then(RAPIER => { // 业务逻辑 });
封装层核心代码如下:
import * as rapierTypings from "@dimforge/rapier2d/rapier"; import Vector from "../math/Vector"; import { RigidBodyType } from "../RigidBody"; const Rapier = { rapier: undefined as (typeof import("@dimforge/rapier2d/rapier") | undefined), get(): typeof import("@dimforge/rapier2d/rapier") { if (Rapier.rapier === undefined) { throw new Error("com.hydroper.matter must be preloaded before use; do so through the asynchronous load() method."); } return Rapier.rapier; }, // 其他省略代码 };
同时在index.ts中实现了异步加载方法:
export async function load(): Promise<void> { if (Rapier.rapier !== undefined) { return; } Rapier.rapier = await import("@dimforge/rapier2d"); }
但在TypeScript + Node.js环境下用ts-node运行终端应用时,抛出模块找不到的错误,错误指向await import("@dimforge/rapier2d")这一行:
Error: Cannot find module '@dimforge/rapier2d' Require stack: - /fooProject/matter/ts/index.ts - /fooProject/fooProject-server/ts/car/Car.ts - /fooProject/fooProject-server/ts/Peer.ts - /fooProject/fooProject-server/ts/index.ts - /fooProject/fooProject-server/bin/fooProject-server at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1077:15) at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (/fooProject/fooProject-server/node_modules/@cspotcode/source-map-support/source-map-support.js:811:30) at Function.Module._load (node:internal/modules/cjs/loader:922:27) at Module.require (node:internal/modules/cjs/loader:1143:19) at require (node:internal/modules/cjs/helpers:110:18) at /fooProject/matter/ts/index.ts:47:21 { code: 'MODULE_NOT_FOUND', requireStack: [ '/fooProject/matter/ts/index.ts', '/fooProject/fooProject-server/ts/car/Car.ts', '/fooProject/fooProject-server/ts/Peer.ts', '/fooProject/fooProject-server/ts/index.ts', '/fooProject/fooProject-server/bin/fooProject-server' ] }
解决方案
1. 确认依赖安装正确性
- 检查
com.hydroper.matter的package.json,确保@dimforge/rapier2d已被添加为生产依赖(而非开发依赖),若未安装则执行:npm install @dimforge/rapier2d - 如果终端应用
fooProject-server通过本地路径引用com.hydroper.matter,可临时在fooProject-server目录也安装一次@dimforge/rapier2d,验证是否为依赖传递问题。
2. 修正动态导入路径
注意到类型导入用的是@dimforge/rapier2d/rapier,但动态导入用的是@dimforge/rapier2d,两者路径不匹配。Rapier的JS绑定实际导出入口通常是@dimforge/rapier2d/rapier,修改动态导入语句:
Rapier.rapier = await import("@dimforge/rapier2d/rapier");
3. 调整ts-node与TypeScript配置
ts-node处理ES模块动态导入时可能存在兼容性问题,尝试以下配置:
- 在项目的
tsconfig.json中设置:{ "module": "ESNext", "moduleResolution": "NodeNext", "target": "ES2020" } - 运行ts-node时添加
--esm参数,强制启用ES模块模式:ts-node --esm ./fooProject-server/ts/index.ts
4. 排查本地包链接问题
如果com.hydroper.matter是通过npm link本地引用的,可能导致依赖解析异常:
- 在
com.hydroper.matter目录执行npm link,再到fooProject-server目录执行npm link com.hydroper.matter,重新建立链接 - 或改用相对路径直接引用本地包,避免link带来的依赖查找问题
内容的提问来源于stack exchange,提问作者Hydroper
相关产品推荐
相关产品推荐

