Reputation: 433
The Rapier physics engine written in Rust is exposed to JavaScript by loading the library into a module dynamically. From Getting started:
import('@dimforge/rapier2d').then(RAPIER => { ... });
I need to use the Rapier module to instantiate vectors from outside code from TypeScript and Node.js with ts-node
. I'm not sure if the properties matter much since it's all dynamically-typed and TypeScript does structural type checks also, but when invoking new rapier.Vector
it could matter.
I created a convenient layer over Rapier's JavaScript bindings (com.hydroper.matter
) which uses this internally, leaving their dynamic module at the static lifetime of the JavaScript program:
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;
},
...
};
Now... ts-node
is reporting the following issue when I run my terminal application that uses Rapier indirectly:
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'
]
}
Relevant code from index.ts
:
export async function load(): Promise<void> {
if (Rapier.rapier !== undefined) {
return;
}
Rapier.rapier = await import("@dimforge/rapier2d");
}
The error is on this import specifically.
Upvotes: 0
Views: 437
Reputation: 1
So I solved this by adding an import map in the html
<script type="importmap">
{
"imports": {
"@dimforge/rapier2d-compat": "https://cdn.skypack.dev/@dimforge/rapier2d-compat"
}
}
</script>
Then in my typescript file
import RAPIER from "@dimforge/rapier2d-compat";
class SetUp {
static async getRapier() {
await ((<any>RAPIER).init());
console.log(`Rapier2D version: ${RAPIER.version()}`);
};
static async init() {
await SetUp.getRapier();
};
}
//Then just call
SetUp.init();
This is for when you are NOT using webpack or such like, which I am not.
Upvotes: 0