I’m encountering a problem in my Astro project where Vite fails to resolve the scoped package @babylonjs/core during development. While TypeScript successfully recognizes the module, the browser returns the following error:
Uncaught TypeError: Failed to resolve module specifier '@babylonjs/core'
If I switch the import to a relative path like /node_modules/@babylonjs/core, the issue disappears, but this workaround is not ideal for my project setup. I’ve already confirmed that Vite is handling other libraries like P5, D3, and THREE correctly through CDN imports, but I would like to bundle BabylonJS.
I would appreciate any guidance or advice on resolving this issue, particularly from those familiar with using Astro and Vite with scoped packages like @babylonjs/core. I’m also reaching out to the Astro Discord community, but any additional help here would be invaluable.
Also…here is the built in Astro tsconfig, which my file extends. Thanks for taking the time to help!
base.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
// Enable top-level await, and other modern ESM features.
"target": "ESNext",
"module": "ESNext",
// Enable module resolution without file extensions on relative paths, for things like npm package imports.
"moduleResolution": "Bundler",
// Allow importing TypeScript files using their native extension (.ts(x)).
"allowImportingTsExtensions": true,
// Enable JSON imports.
"resolveJsonModule": true,
// Enforce the usage of type-only imports when needed, which helps avoiding bundling issues.
"verbatimModuleSyntax": true,
// Ensure that each file can be transpiled without relying on other imports.
// This is redundant with the previous option, however it ensures that it's on even if someone disable `verbatimModuleSyntax`
"isolatedModules": true,
// Astro directly run TypeScript code, no transpilation needed.
"noEmit": true,
// Report an error when importing a file using a casing different from another import of the same file.
"forceConsistentCasingInFileNames": true,
// Properly support importing CJS modules in ESM
"esModuleInterop": true,
// Skip typechecking libraries and .d.ts files
"skipLibCheck": true,
// Allow JavaScript files to be imported
"allowJs": true,
// Allow JSX files (or files that are internally considered JSX, like Astro files) to be imported inside `.js` and `.ts` files.
"jsx": "preserve"
}
}
strict.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "./base.json",
"compilerOptions": {
// Enable strict mode. This enables a few options at a time, see https://www.typescriptlang.org/tsconfig#strict for a list.
"strict": true
}
}
@RaananW - at the advice of @roland, do you think you could help with this one? It looks like UMD is a different direction than what I’m trying to do, which is use Vite because its part of Astro.
Hi @RaananW thanks for taking a look. I tried again this week, and I still can’t get the Babylon modules to work as scoped packages. It’s up on GitHub pages now though:
I am very confused as to why this entire wrapper is needed. I just pulled the project but couldn’t really understand how to reproduce this.
Babylon does not export the namespace BABYLON (as you write in the types.ts file), nor does it expect you to use the BABYLON namespace. It does expect you to use Babylon as an esm module, importing what you need from where you need it.
I am not entirely familiar with Astro, though it does look quite straight forward. especially if it is built with Vite (and therefore rollup), you shoul dbe able to bundle the @babylonjs/core library into your code without using a CDN or the module loading script you added in the .astro file.
I mean - if you just add this:
import { Engine } from '/node_modules/@babylonjs/core';
console.log(Engine);
To the script tag you added you will see it is working as expected. Not sure why Vite doesn’t recognize it as an npm package, but that must be some configuration issue with Astro (which I haven’t found a solution for yet )
Thanks! You put me back on the right track, it was indeed an Astro-specific issue. Wouldn’t you know it that the thing that works for 99% of Astro users, did not work for my setup.
As it turns out because I’m writing my site with MDX files, the babylon.js sketches are dynamically loaded and specific to each page. Astro’s built-in script handling forces inline scripts when passing variables like filenames or paths, which breaks Vite’s module bundling capabilities. (Scripts and Event Handling | Docs)
As a workaround, Astro makes it easy to use React as middleware, which avoids this limitation , allowing Vite to properly bundle the scripts and modules.
Now it works both in dev mode and in build-preview mode, and the final problem to solve is how to set this thing up so it works both in build mode and also on gh-pages, which have a sub-path issue to deal with.