-
Notifications
You must be signed in to change notification settings - Fork 423
graphql CLI plugin generates NodeNext-incompatible metadata imports (missing .js extension) #3870
Description
Is there an existing issue for this?
- I have searched the existing issues
Current behavior
When using the Nest CLI GraphQL plugin with module/moduleResolution: "nodenext", generated src/metadata.ts contains extensionless dynamic imports like:
import("./api/auth/auth.types")TypeScript then fails during type-check/build with TS2307 for those generated imports.
nest build (or tsc --noEmit) fails with errors from generated src/metadata.ts:
error TS2307: Cannot find module './api/user/user.types' or its corresponding type declarations.
error TS2307: Cannot find module './api/auth/auth.types' or its corresponding type declarations.
error TS2307: Cannot find module './api/customer/customer.types' or its corresponding type declarations.
Minimum reproduction code
https://gist.github.com/dunak-debug/43c43098e6bba67eeb2c41a34de30211
Steps to reproduce
- Create a Nest app using @nestjs/graphql plugin in nest-cli.json.
- Use TypeScript module + moduleResolution as nodenext.
- Configure GraphQLModule.forRoot({ metadata }) using generated metadata file.
- Run nest build or tsc --noEmit.
Expected behavior
Generated metadata should be compatible with NodeNext.
For example, generated imports should include .js:
import("./api/auth/auth.types.js")so type-check/build succeeds without workarounds.
Package version
13.2.4
Graphql version
graphql: 16.13.0
@nestjs/mercurius: 13.2.4
mercurius: 16.7.0
NestJS version
11.1.14
Node.js version
24.14.0
In which operating systems have you tested?
- macOS
- Windows
- Linux
Other
TypeScript: 5.9.3
pnpm: 10.30.3
I confirmed a local patch changing metadata import emission from:
--- a/dist/plugin/visitors/model-class.visitor.js
+++ b/dist/plugin/visitors/model-class.visitor.js
@@ -27,7 +27,8 @@ class ModelClassVisitor {
const metadataWithImports = [];
Object.keys(this._collectedMetadata).forEach((filePath) => {
const metadata = this._collectedMetadata[filePath];
- const path = filePath.replace(/\.[jt]s$/, '');
+ // Emit explicit .js specifiers so generated metadata.ts is compatible with NodeNext.
+ const path = filePath.replace(/\.[jt]s$/, '.js');
const importExpr = ts.factory.createCallExpression(ts.factory.createToken(ts.SyntaxKind.ImportKeyword), undefined, [ts.factory.createStringLiteral(path)]);
metadataWithImports.push([importExpr, metadata]);
});
resolves the issue in NodeNext projects.