In my API, I have a circular dependency between Account and Profile (one Account has one Profile assigned; one Profile belongs to one Account). This is realized with the TypeORM @OneToOne(...) relationship.
This api should properly build and run.
The ng serve PROJECT command throws circular dependency warnings (see #1649 , #1661) and "refuses" to properly boot. In this context, i noticed the following error on the terminal:
ReferenceError: Cannot access 'Account' before initialization
at Module.Account (...\dist\apps\api\main.js:544:99)
...
If i trace down the stacktrace, i end up in the circular dependency between Account and Profile (as described above).
I manage to solve this issue by adding the following lines to the apps\api\tsconfig.app.json file:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs", // <-- here
"target": "es2017", // <-- here
"types": ["node"]
},
"exclude": ["**/*.spec.ts"],
"include": ["**/*.ts"]
}
The "autogenerated" tsconfig.app.json file when running
ng g @nrwl/nest:app api
omits those lines. In the sample project from nestjs ( https://github.com/nestjs/nest/blob/master/sample/01-cats-app/tsconfig.json ) these lines are required.
I think, we should add those lines by default - this can be done in the nest schematics right? Shall i add a PR for this @FrozenPandaz ?
When running ng serve api it still throws a lot of circular dependency warnings, however, the application successfully "compiles" and can be executed. The issue with the circular dependency was introduced somewhere between 8.2 and 8.4, i guess..
All the best
I can confirm the issue itself and the solution too. Setting options to commonjs/es2017 will still throw warnings but compile successfully.
Hi @jbjhjm!
The reference error you mentioned is usually due to the fact that you are using an injected service before it has been instantiated by the dependency injection mechanism. I would double check the architecture of the feature you are trying to do.
If it is a problem specifically with NestJS, I would recommend you to create an issue in NestJS' repository.
If it can help, usually circular dependencies appear because we want to share an interface (or chunk of code) that has been created in the same component/service it is related to. Extracting this interface (or chunk of code) into its own file will solve the problem.
I will close the issue since you find a workaround that works for you.
Dear @bcabanes ,
i don't think, that the solution provided by me is a "workaround" but rather the proper solution! NestJs requires these 2 properties in the tsconfig.json file - and nrwl/nx is missing those.
I repeat, this is not an architecture problem with my application i am building - you can observe this behaviour with a freshly built nestjs application in nrwl/nx. Shall i provide a repository for you to reproduce the issue? I can provide you with one in the following week!
A repository with the reproduction is always a good idea! 馃憤 Thanks!
i will try and create a reproduction repository!
Dear @bcabanes ,
i am very sorry that it took me so long to create a reproduction repository.. Please find it here: https://github.com/johannesschobel/nx-tsconfig-bug
The commit https://github.com/johannesschobel/nx-tsconfig-bug/commit/218becccaf992b9c404c24c4218e547e53b72395 shows the repository in the "broken" state. I.e., if you run ng serve api it fails to boot. Please note that there are also some Circular Dependency warnings as described in this issue here https://github.com/nrwl/nx/issues/1649 .
However, the NestJs application fails to boot with the mentioned error:
ReferenceError: Cannot access 'Account' before initialization
The next commit ( https://github.com/johannesschobel/nx-tsconfig-bug/commit/6b4994090b504cb0567a2abfbc6b3e7c6134b4e7 ) shows the described fix. If you then run ng serve api again, it still shows the Circular Dependency warnings but the application starts and is fully operational.
Can i submit a PR to nrwl/nest to fix this? Can you advise me where i can fix this? This has to be done in the schematics, right?
All the best and thanks a lot for your time!
@bcabanes and @vsavkin : I would advise to re-open this issue because the problem is actually not solved!
Dear @vsavkin , @FrozenPandaz and @bcabanes
i recently stumbled upon the same issue again, as i started to work on another nrwl/nest project. I vaguely remembered that there was an issue in the tsconfig file somewhere when using the autogenerated stubs. Can you please fix this?
All the best,
Johannes
Same issue here. Thanks @johannesschobel for finding the fix!
Just stumbled upon this issue on new NX project.
@vsavkin , @FrozenPandaz and @bcabanes
This issue was closed thinking issue is with Dependency Injector and bad architecture.
This is not true, this issue is about simple import .. from .. statements.
Imagine using Typeorm, which NestJS natively support and defining bi-directional relation between two tables (two classes).
A imports B, while B imports A.
Just as in example here - https://typeorm.io/#/many-to-one-one-to-many-relations
User imports Post and Post imports User.
Bare Nestjs works out of the box, while created from NX does not.
NX should use same module and target config as NestJs uses.
Please, fix the issue
Thank you
@trubit do you suggest any work around for now?.
I am also facing same issue with typeorm relations.
@nil1990 Solution is mentioned in first post. You need to modify tsconfig.
Any Updates?
The first post solution is breaking my jest global describe function access...
describe('Candidate Files Controller', () => {
^
ReferenceError: describe is not defined
at Object../apps/back/src/candidate/controllers/candidate-files.public.controller.spec.ts (/Users/dist/apps/back/webpack:/apps/back/src/candidate/controllers/candidate-files.public.controller.spec.ts:11:1)
at __webpack_require__ (/Users//dist/apps/back/webpack:/webpack/bootstrap:19:1)
at Object../apps/back/src/candidate/controllers/index.ts (/Users/dist/apps/back/webpack:/apps/back/src/candidate/controllers/index.ts:3:1)
at __webpack_require__ (/Users/dist/apps/back/webpack:/webpack/bootstrap:19:1)
at Object../apps/back/src/candidate/index.ts (/Users/dist/apps/back/webpack:/apps/back/src/candidate/index.ts:3:1)
at __webpack_require__ (/Users/dist/apps/back/webpack:/webpack/bootstrap:19:1)
at Object../apps/back/src/candidate-files/entities/candidate-file.entity.ts (/User/dist/apps/back/webpack:/apps/back/src/candidate-files/entities/candidate-file.entity.ts:29:1)
at __webpack_require__ (/Users/dist/apps/back/webpack:/webpack/bootstrap:19:1)
at Object../apps/back/src/candidate-files/entities/bachelor.entity.ts (/Users/dist/apps/back/webpack:/apps/back/src/candidate-files/entities/bachelor.entity.ts:13:1)
at __webpack_require__ (/Users/dist/apps/back/webpack:/webpack/bootstrap:19:1)
@fstn I can run jest test without any problem. Here are my tsconfigs for reference:
apps/api/tsconfig.spec.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": ["**/*.spec.ts", "**/*.d.ts"]
}
apps/api/tsconfig.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"types": ["node", "jest"],
"emitDecoratorMetadata": true,
"target": "es2017",
"module": "commonjs",
"removeComments": true
},
"include": ["**/*.ts"]
}
apps/api/tsconfig.app.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"exclude": ["**/*.spec.ts"],
"include": ["**/*.ts"]
}
The problem must be on your side.
@fstn I can run jest test without any problem. Here are my tsconfigs for reference:
apps/api/tsconfig.spec.json{ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", "module": "commonjs", "types": ["jest", "node"] }, "include": ["**/*.spec.ts", "**/*.d.ts"] }
apps/api/tsconfig.json{ "extends": "../../tsconfig.json", "compilerOptions": { "types": ["node", "jest"], "emitDecoratorMetadata": true, "target": "es2017", "module": "commonjs", "removeComments": true }, "include": ["**/*.ts"] }
tsconfig.app.json{ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", "types": ["node"] }, "exclude": ["**/*.spec.ts"], "include": ["**/*.ts"] }The problem must be on your side.
Thanks, can you share the extended file? "extends": "../../tsconfig.json",
@fstn
{
"compileOnSave": false,
"compilerOptions": {
"rootDir": ".",
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2015",
"module": "esnext",
"typeRoots": ["node_modules/@types"],
"lib": ["es2017", "dom"],
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"baseUrl": ".",
"paths": {}
},
"exclude": ["node_modules", "tmp"]
}
Most helpful comment
@bcabanes and @vsavkin : I would advise to re-open this issue because the problem is actually not solved!