-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ConfigService Injection Issue in Nx/NestJS Library #29136
Comments
The issue seems to be related to the SWC compiler. In the webpack.config.js, changing the compiler option from swc to tsc resolves the problem: ...
NxAppWebpackPlugin({
target: 'node',
compiler: 'tsc', // Switched from 'swc' to 'tsc' and the issue is gone
...
}), |
Hi, thanks for reporting this issue. Can you provide a small repro highlighting the issue? NestJS has a specific requirement for monorepos, it could be that we missed something for |
Here’s a small repro along with the NxAppWebpackPlugin configuration I’m using: const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin');
const { join } = require('node:path');
module.exports = {
output: {
path: join(__dirname, '../../dist/apps/testing'),
},
plugins: [
new NxAppWebpackPlugin({
target: 'node',
compiler: 'tsc',
main: './src/main.ts',
tsConfig: './tsconfig.app.json',
assets: ['./src/assets'],
optimization: false,
outputHashing: 'none',
generatePackageJson: false,
progress: false,
}),
],
}; project.json: "targets": {
"build": {
"executor": "@nx/webpack:webpack",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"outputPath": "dist/apps/testing",
"webpackConfig": "apps/testing/webpack.config.cjs",
"main": "apps/testing/src/main.ts",
"tsConfig": "apps/testing/tsconfig.app.json",
"assets": ["apps/testing/src/assets"],
"inspect": true
},
"configurations": {
"development": {},
"production": {}
}
},
"serve": {
"executor": "@nx/js:node",
"defaultConfiguration": "development",
"dependsOn": [
"build",
{
"dependencies": true,
"target": "build"
}
],
"options": {
"buildTarget": "testing:build",
"runBuildTargetDependencies": true
},
"configurations": {
"development": {
"buildTarget": "testing:build:development"
},
"production": {
"buildTarget": "testing:build:production"
}
}
}
} |
Same problem, with rspack. project.json {
"name": "auth",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "{projectRoot}/src",
"projectType": "application",
"tags": [],
"targets": {
"build": {
"executor": "@nx/rspack:rspack",
"cache": true,
"options": {
"target": "node",
"outputPath": "{workspaceRoot}/build/apps/auth",
"outputHashing": "none",
"main": "{projectRoot}/src/main.ts",
"tsConfig": "{projectRoot}/tsconfig.app.json",
"rspackConfig": "{projectRoot}/rspack.config.ts",
"assets": [],
"generatePackageJson": true
}
}
}
} rspack.config.ts import { composePlugins, withNx } from '@nx/rspack';
export default composePlugins(withNx()); tsconfig.app.json {
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"types": [
"node"
],
"emitDecoratorMetadata": true,
"target": "es2021"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"src/**/*.spec.ts",
"src/**/*.test.ts"
]
} Points:
Part of code: // ...
import { ConfigService } from '@nestjs/config';
@Injectable()
export class OpenIdService implements OnModuleInit, OnModuleDestroy {
protected readonly logger = new Logger(OpenIdService.name);
constructor(configService: ConfigService<EnvironmentVariables>) {
this.logger.log('[OpenIdService constructor:configService]', configService);
// ...
}
// ...
} Error: [Nest] 99352 - 01/10/2025, 2:05:21 PM LOG [NestFactory] Starting Nest application...
[Nest] 99352 - 01/10/2025, 2:05:21 PM LOG [OpenIdService] [OpenIdService constructor:configService]
[Nest] 99352 - 01/10/2025, 2:05:21 PM LOG [OpenIdService] undefined
[Nest] 99352 - 01/10/2025, 2:05:21 PM LOG [OpenIdService] [OpenIdService constructor:configService]
[Nest] 99352 - 01/10/2025, 2:05:21 PM LOG [OpenIdService] undefined
[Nest] 99352 - 01/10/2025, 2:05:21 PM ERROR [ExceptionHandler] Cannot read properties of undefined (reading 'get')
TypeError: Cannot read properties of undefined (reading 'get')
at new OpenIdService (.../build/apps/auth/webpack:/auth/src/open-id/open-id.service.ts:50:49)
at Injector.instantiateClass (.../node_modules/@nestjs/core/injector/injector.js:373:19)
at callback (.../node_modules/@nestjs/core/injector/injector.js:65:45)
at Injector.resolveConstructorParams (.../node_modules/@nestjs/core/injector/injector.js:145:24)
at Injector.loadInstance (.../node_modules/@nestjs/core/injector/injector.js:70:13)
at Injector.loadProvider (.../node_modules/@nestjs/core/injector/injector.js:98:9)
at .../node_modules/@nestjs/core/injector/instance-loader.js:56:13
at async Promise.all (index 3)
at InstanceLoader.createInstancesOfProviders (.../node_modules/@nestjs/core/injector/instance-loader.js:55:9)
at.../node_modules/@nestjs/core/injector/instance-loader.js:40:13 |
It seems due to the module.rules process the typescript wrongly nx/packages/rspack/src/plugins/utils/apply-base-config.ts Lines 396 to 425 in f24a869
according to the rspack official nestjs example, the module rules should be: so, when I add a workaround plugin in my rspack.config.js const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
const rspack = require('@rspack/core');
const { join } = require('path');
module.exports = {
entry: "src/main.ts",
output: {
path: join(__dirname, '../../dist/apps/example'),
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'builtin:swc-loader',
options: {
jsc: {
parser: {
syntax: 'typescript',
decorators: true,
},
transform: {
legacyDecorator: true,
decoratorMetadata: true,
},
},
},
},
},
],
},
optimization: {
minimizer: [
new rspack.SwcJsMinimizerRspackPlugin({
minimizerOptions: {
compress: {
keep_classnames: true,
keep_fnames: true,
},
mangle: {
keep_classnames: true,
keep_fnames: true,
},
},
}),
],
},
plugins: [
new NxAppRspackPlugin({
target: 'node',
tsConfig: 'apps/example/tsconfig.app.json',
main: 'apps/example/src/main.ts',
outputHashing: 'none',
}),
{
apply(compiler) {
compiler.options.module.rules = compiler.options.module.rules.slice(0, 1)
compiler.options.optimization ??= {}
}
}
],
}; The NestJS work correctly. |
same issue w/ NestJS and @nx/rspack after running |
@zvn2060 I just investigated what is generating So I have created a small plugin that fixes the @ndcunningham I hope it will help you to understand the problem and add this to a next fix/release. The original rule: {
"test": {},
"loader": "builtin:swc-loader",
"exclude": {},
"type": "javascript/auto",
"options": {
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true,
"tsx": true
},
"transform": {
"react": {
"runtime": "automatic",
"pragma": "React.createElement",
"pragmaFrag": "React.Fragment",
"throwIfNamespace": true,
"development": false,
"refresh": false,
"useBuiltins": false
}
}
}
}
} As we can see there are no Solution to create a plugin for fixing rule: export const fixBuiltinSwcLoader = (config: Configuration): Configuration => {
config.module.rules = config.module.rules.map((rule) => {
if (typeof rule === 'object' && 'loader' in rule && rule.loader === 'builtin:swc-loader') {
(rule.options as any).jsc.transform.legacyDecorator = true;
(rule.options as any).jsc.transform.decoratorMetadata = true;
}
return rule;
});
return config;
}; rspack.config.ts import { composePlugins, withNx } from '@nx/rspack';
export default composePlugins(
withNx(),
fixBuiltinSwcLoader,
); In this case it still works together with Additionally I have noticed that export const withNodeExternals = ({ fileName }: { fileName: string }) => (config: Configuration): Configuration => {
config.externals = [
nodeExternals({
modulesFromFile: {
fileName,
},
}),
];
return config;
}; The final rspack.config.ts import * as path from 'node:path';
import { composePlugins, withNx } from '@nx/rspack';
import { fixBuiltinSwcLoader, withNodeExternals } from '@shared';
export default composePlugins(
withNx(),
fixBuiltinSwcLoader,
withNodeExternals({
fileName: path.resolve(__dirname, 'package.json'),
}),
); |
Current Behavior
I created a new Nx-based NestJS library and used the ConfigService from @nestjs/config. The ConfigModule is imported in the library, and the ConfigService is injected into one of the services. However, when I use this service in a consuming NestJS app, I encounter the following error:
This indicates that ConfigService is not properly injected, even though ConfigModule has been imported both in the library and as a global module in the app.
Expected Behavior
The ConfigService should be correctly injected into the library service, and configuration values should be accessible without errors.
GitHub Repo
No response
Steps to Reproduce
Nx Report
Failure Logs
Package Manager Version
No response
Operating System
Additional Information
No response
The text was updated successfully, but these errors were encountered: