You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:45:01