Skip to content

Conversation

@donmccurdy
Copy link
Contributor

@donmccurdy donmccurdy commented Dec 9, 2025

For TypeScript projects that have adopted certain newer configurations ("moduleResolution": "nodenext" in tsconfig.json is probably the most common), it's necessary to include .js extensions on import paths within .d.ts files. (Despite the fact that we're referring to other .d.ts files, yeah...). Fortunately, this is backwards-compatible with older TypeScript configurations.

The addition of the package.json#typesVersions fixes a build issue for glTF Transform after I switched over to importing from subpaths like meshoptimizer/decoder, but I'm still trying to figure out why — I don't typically use the "typesVersions" field so this was unexpected to me. Duplicating the .d.ts paths under both exports and typesVersions shouldn't be necessary. Reverted this part.

I'll mark this as a draft until I understand that better. I suspect this is not a common issue for JS/TS projects, so no particular rush on reviewing or publishing a patch. :)

Background:

@donmccurdy donmccurdy changed the title js: Fix imports in .d.ts files for moduleResolution=NodeNext compatibility js: Fix resolution of TypeScript .d.ts definitions Dec 9, 2025
@donmccurdy donmccurdy marked this pull request as draft December 9, 2025 03:37
@zeux
Copy link
Owner

zeux commented Dec 9, 2025

Despite the fact that we're referring to other .d.ts files, yeah...

Amazingly, it looks like the import must be from meshopt_decoder.js despite the fact that this file doesn't exist. Trying to use meshopt_decoder.mjs appears to silently skip the re-export unless --strict is used - perhaps conditional on some specific resolution mode.

@zeux
Copy link
Owner

zeux commented Dec 9, 2025

One more thing I'm confused by, besides typesVersions, is that the version upgrade - before switching to more granular import paths - seems to have built without errors? I don't fully understand how that could happen.

https://github.com/donmccurdy/glTF-Transform/actions/runs/20049818795

@donmccurdy
Copy link
Contributor Author

Very likely conditional on the resolution mode, yes. I'm using "moduleResolution": "nodenext" (which is more strict) in glTF Transform mostly in the hope that it catches future-proofing issues, and/or issues that would affect downstream consumers with different configs.

Before switching to the subpath imports the build passed in CI but raised errors locally in my editor, which uses typescript-language-server:

Module "meshoptimizer" has no exported member MeshoptEncoder. (ts 2305)

Related: donmccurdy/glTF-Transform#1780

@donmccurdy
Copy link
Contributor Author

donmccurdy commented Dec 10, 2025

Testing against a clean TypeScript project and a modern build tool (tried: vite, tsup, pkgroll, tsc), including with "moduleResolution": "nodenext" and I'm having trouble reproducing the errors I'm getting in glTF Transform's build when using subpath imports. My build tool might be out of date at this point. In any case, I don't think the typesVersions addition is actually needed, or it shouldn't be according to microsoft/TypeScript#50794 (comment).

It was my impression that extensions on imports in .d.ts files were needed in NodeNext, but I'm not seeing that issue on a clean project either. So I'll close this until I'm sure I'm seeing an issue, on a build configuration that I'm more sure is correct. Outdated paragraph, I was able to reproduce this part.

@donmccurdy donmccurdy closed this Dec 10, 2025
@donmccurdy donmccurdy reopened this Dec 10, 2025
@donmccurdy
Copy link
Contributor Author

I think what's left in the PR should be ready, for the moduleResolution=NodeNext fix!

@zeux
Copy link
Owner

zeux commented Dec 10, 2025

Yeah the nodenext problem seems straightforward; I had a local test project for TypeScript surface which works as is with moduleResolution=bundler but breaks when moduleResolution is changed to nodenext. Adding the extensions fixes that; in my project, I don't see any other errors (I'm using a mix of meshoptimizer and meshoptimizer/component imports for testing), neither in tsc output nor in the language server.

I can merge this and publish a 1.0.1 with the fix tomorrow.

@zeux
Copy link
Owner

zeux commented Dec 10, 2025

As for typesVersions: I can reproduce the issue when using rollup, which for some reason doesn't resolve the TypeScript module references for individual components. It runs fine when importing meshoptimizer though, and vite seems to work fine with either import path. So perhaps this is specific to or a bug in rollup.

Do I understand it correctly that if I publish 1.0.1 with just the index.d.ts patch, you'll be able to upgrade glTF-Transform by using the meshoptimizer import, and the individual components do not matter as much here / could be resolved separately? I'd like to avoid a 1.0.2 if possible :D

@donmccurdy donmccurdy marked this pull request as ready for review December 10, 2025 12:34
@donmccurdy
Copy link
Contributor Author

I don't expect any further issues with the 'meshoptimizer' root path import after this fix, correct!

For the meshoptimizer/* subpath imports, I think it's probably not Rollup broadly, but the Rollup plugin used to resolve types (if any). In my case that's rollup-plugin-typescript2, used in Microbundle. Based on a couple issues...

... it looks like my build tool doesn't fully support package.json#exports, so I should just be using the root path import instead (or updating the build configuration).

I might try to (1) publish a glTF Transform v4.3 release in the next few weeks, and then follow up with a v4.4 release updating the build to support package.json#exports and updating to meshoptimizer v1.0.0. At that point it should be compatible with the current meshoptimizer v1.0.0 package. If you wanted to wait on publishing v1.0.1 until then, as no one else has reported the moduleResolution=NodeNext compatibility issue yet, that could be a good option too.

@zeux zeux force-pushed the fix/typescript-nodenext-compat branch from 38c18e8 to f1654f7 Compare December 10, 2025 16:44
@zeux
Copy link
Owner

zeux commented Dec 10, 2025

It probably makes sense to publish a fix anyway as someone will run into this sooner or later, and it's easier to do this early so that no branching is necessary to pick up just the relevant fixes. I've bumped the package version here, will merge & publish later.

@zeux zeux merged commit 5710056 into zeux:master Dec 12, 2025
13 checks passed
@zeux
Copy link
Owner

zeux commented Dec 12, 2025

I've published 1.0.1 with these changes; thanks!

@donmccurdy donmccurdy deleted the fix/typescript-nodenext-compat branch December 12, 2025 16:02
@CodyJasonBennett
Copy link

As a sanity check, there are tools that help discover and diagnose configuration since it is very complicated.

For types: https://arethetypeswrong.github.io/?p=meshoptimizer%401.0.1
For NPM/Node config: https://publint.dev/meshoptimizer@1.0.1

Everything looks good here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants