RecastJSPlugin, Typescript, ES6

Hello!

If you couldn’t get this setup working, because you were not able to import Recast always getting ‘File is not a module error’, than follow this:

npm i recast-detour

Open node_modules/recast-detour/recast.d.ts and edit the first line

Change declare module Recast to export namespace Recast

After this you can simply:

import * as Recast from 'recast-detour'

You need to import { RecastJSPlugin } from '@babylonjs/core' to get the whole thing working, obviously…

Pass Recast to the plugin this way: const navigationPlugin = new RecastJSPlugin(Recast)

OR JUST

const Recast = require('recast-detour'), but the linter will complain, that you need to change it to an ES6 import. Hopefully you all know how to silence it :smiley: However I prefer not to mix imports and requires, so the industry does, therefore I highly encourage you to use the first longer but much cleaner method.

Enjoy!

EDIT:
https://github.com/Microsoft/TypeScript/issues/13774

R.

4 Likes

awesome, thanks for sharing

1 Like

Ping @Cedric FYI

1 Like

Sorry to revive this post but is this solution still valid today? I’m trying this on my typescript environment and I get the infamous ‘Module not found: Error: Can’t resolve ‘fs’ in ‘…\node_modules\recast-detour’’’. error

No worries. Show us your package.json and your imports.

1 Like

thanks for the help, this is my package.json:

{
  "name": "testapp",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@babylonjs/core": "^4.2.0",
    "@babylonjs/gui": "^4.2.0",
    "@babylonjs/inspector": "^4.2.0",
    "@babylonjs/loaders": "^4.2.0",
    "@chakra-ui/icon": "^2.0.0",
    "@chakra-ui/icons": "^1.1.1",
    "@chakra-ui/react": "^1.7.3",
    "@emotion/react": "^11.7.1",
    "@emotion/styled": "^11.6.0",
    "@testing-library/jest-dom": "^5.16.1",
    "@testing-library/react": "^12.1.2",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.0.3",
    "@types/node": "^16.11.14",
    "@types/react": "^17.0.37",
    "@types/react-dom": "^17.0.11",
    "framer-motion": "^5.5.5",
    "fs": "^0.0.1-security",
    "path": "^0.12.7",
    "react": "^17.0.2",
    "react-babylonjs": "^3.0.31",
    "react-dom": "^17.0.2",
    "react-icons": "^4.3.1",
    "react-scripts": "5.0.0",
    "recast-detour": "^1.5.0",
    "typescript": "^4.5.4",
    "web-vitals": "^2.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

And my imports are:

import { Mesh, MeshBuilder, Nullable, SceneLoader, Tools, Vector3 } from "@babylonjs/core";
import { useState } from "react";
import { Scene } from "react-babylonjs";

import { RecastJSPlugin } from '@babylonjs/core'
import Recast from 'recast-detour'

NGL, this is a though one to crack with BJS 4.2 (depending on which version of webpack you are using) however there is a solution, I am getting closer :smiley: Are you willing to upgrade to BJS 5? It will make this easier.

1 Like

Thanks! if the only way to get this plugin working is to use babylon 5, I’d love to know the solution for sure, but ideally it would be best for me to keep babylon 4.2 :frowning:. I’m currently using react-babylonjs which I believe doesn’t support babylon 5 at the moment :disappointed_relieved:

Ok, no worries. It will work for sure. I’ve used the plugin with 4.2.1 as well, but migrated to 5 a few months ago. I need to know your exact bundler environment. Webpack? Version?

I went through this process 3 times already but I don’t remember the exact steps :joy: it’s so ducking fragile! First time when I switched to bjs 5 and two times I had to adjust it to work with the new beta releases. Ain’t gonna touch it again lol

However you might be interested in a pure js solution based on Yuka ai js library. I wrote 3 navigation examples. You can find them here:

You’ll be interested in the TS version. There is only 1 navigation example at the moment in TS but definitely check the other two JS examples as well. It’s as easy as import the YUKA package and you are good to go.

EDIT:
I just got it working in 4.2.1 like this (not the cleanest solution though):

image

Unzip this file to your src folder:
recast.zip (201.5 KB)

image

image

or it works with the recast-detour npm package as well:
image

Modify the the file recast-detour/recast.d.ts in node_modules:
image

image

The result is the same:

:vulcan_salute:

1 Like

thanks for those instruction, I’ve updated my project to run babylon 4.2.1 and tried the instructions but I still get the 'Module not found: Error: Can’t resolve ‘fs’ in ‘…\node_modules\recast-detour’ error. Can you confirm the way you import recast? my imports currently look like this:

import { RecastJSPlugin } from '@babylonjs/core'
import * as Recast from 'recast-detour'

My webpack version is 5.65.0.

I might have to switch gears and try your library, looks awesome!

I am on phone so just shortly: Did you try the first solution as well? The way I import Recast is on the screenshot.

yep, I’ve tried both ways with the same result :frowning:

Can you send me an empty project set up exactly the way as yours is?

Edit: or you can share your actual project with me

BabylonJS is a peer dep - if it doesn’t work on v5 create an issue on that repo. I did a backwards compat PR on 5 alpha, but not tested lately. Thanks.

edit: just tested on 5.0.0-beta.9 and no issues found.

Thank you @brianzinn, I actually blindly assumed there was no support, I actually haven’t tested on 5.0. If I find any issues i will gladly let you know.

@roland working on packing my files, thanks for your patience.

Sure :+1:

react-babylonjs-recast_ErrorProject.zip (507.5 KB)
This is the minimal project with recast imported on my environment. Hope it’s helpful.

The problem is webpack. Webpack 4 and below included shims for node built in packages, but webpack 5 removed them. Im not sure why recast requires fs because i thought that was done through emscripten which provides its own fs implementation .

Anyway, to restore webpack 4 behavior require this in your webpack config

const NodePolyfillPlugin = require(“node-polyfill-webpack-plugin”) and add the plugin to the plugins array.

If youre using only react scripts, i advise using craco to override the default config

1 Like

Oh you can also just downgrade react scripts to v4 but it’ll stop working in node 17 because of the openssl upgrade and webpack generally being ass

1 Like