nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
66.9k stars 7.55k forks source link

IOC resolve can't import from index.ts, but it's COPY index2.ts is ok. #825

Closed muyu66 closed 6 years ago

muyu66 commented 6 years ago

[x] Bug report

If code is:

import { UserDao } from './daos'; // only use daos/index.ts to export

@Injectable()
export class UserService extends BaseService {

constructor(
    private readonly dao:UserDao,
) {
    super();
}

It throw a error:

[ExceptionHandler] Nest can't resolve dependencies of the UserService (?). Please verify whether [0] argument is available in the current context.

Now we adjust code:

import { UserDao } from './daos/user.dao';

Then everything is right. It's amazing.

File /daos/index.ts

export { UserDao } from './user.dao';

Version

"@nestjs/common": "^5.0.1",
"@nestjs/core": "^5.0.1",
"typescript": "^2.9.2"

I think it's bug, IOC resolve can't import from index.ts

adrien2p commented 6 years ago

hey @muyu66 could you show us your module definition ?

muyu66 commented 6 years ago

@adrien2p I try to build minimized sample program, but i am fail. I am not able to reply this mistake in new Project.

When code "import { UserDao } from './daos/index'", it throw Error. When code "import { UserDao } from './daos/index2'", it is just normal, index2.ts is index.ts's COPY

Under these circumstances, I think my module definition is not related to this

adrien2p commented 6 years ago

what are your compiler options in your tsconfig.json file ? even if your specify './daos/index' that doesn't work ?

BrunnerLivio commented 6 years ago

I also experienced some really strange behaviour like @muyu66 described. Seems like a bug with the module resolution to me. Do not know if it is a bug of TS or Nest though.

muyu66 commented 6 years ago

@adrien2p

This is my tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "noImplicitAny": false,
        "removeComments": false,
        "outDir": "build",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "pretty": true,
        "strictNullChecks": true
    },
    "include": [
        "src/**/*"
    ]
}

Yes, i try "./dao/index" and "./dao"

muyu66 commented 6 years ago

Let us continue to observe whether there are more examples. I cannot unilaterally reproduce

muyu66 commented 6 years ago

@adrien2p @BrunnerLivio I often run into such problems and then found examples of stable recurring today. I wrote a minimum project (fork from typescript-starter).

This problem can be reproduced by "npm run dev"

Project is in: (branch is resolve) https://github.com/muyu66/typescript-starter/tree/resolve

BrunnerLivio commented 6 years ago

@muyu66 Yup also able to reproduce it.

muyu66 commented 6 years ago

I don't understand the internal ioc implementation mechanism of Nestjs, I try to read its source code, still can't understand.

I am currently using a solution to circular dependencies to temporarily circumvent this problem. Just use @Inject(forwardRef(() => TestService)), it's can be resolved temporarily.

adrien2p commented 6 years ago

I reproduce will investigate a bit

muyu66 commented 6 years ago

Thinks, this error is very important to me because I can remove a lot of "forwardRef".

adrien2p commented 6 years ago

@muyu66 The thing is that actually the index.ts export Test1Service but this one import Test2Service from index.ts which is not exported yet. The only way to avoid that is to import the class from ./test2 or by reversing the order of the exportation in index.ts

export * from './test2';
export * from './test1';

Tell me if i wasn't clear enough :)

BrunnerLivio commented 6 years ago

@adrien2p That makes sense. Seems to be a general TypeScript issue? Strange I’ve never ran into this problem before, until I’ve used NestJS..

But are you sure this is the problem? I know for example import sorter for VSCode which sort the imports alphabetically and ignores the dependency of each import. That would break the application, but it still seems to work?

muyu66 commented 6 years ago

@BrunnerLivio This problem has been bothering me for a long time. My typescript is 2.9.2, Nestjs Core is 5.0.1

muyu66 commented 6 years ago

@adrien2p I can understand what you mean, but I didn't modify the code as you suggested, because my project is too big to make this adjustment.

adrien2p commented 6 years ago

@BrunnerLivio i think but maybe it is another thing, the fact is i never had this issue because a never import from an index file since i am in the same directory, alway from another directory.

muyu66 commented 6 years ago

The advantage of import from index.ts this is that when I need to change the file name, or file path, I don't need to change all the files that reference it. I just need to modify index.ts.

adrien2p commented 6 years ago

Yes i completely understand i do it as well. Just not in the same directory ^^ Maybe some one else will find a better way to fix that.

And if you change the path, it will not be in this index file anymore but in another one.

muyu66 commented 6 years ago

@kamilmysliwiec i want to get your help

muyu66 commented 6 years ago

I think of a better way to circumvent this problem. Is to create a hard linux link (ln) to the index.ts, then it's ok that import index_symbolic.ts from test.module.ts

Branch is in resolve-ok, it's passed

kamilmysliwiec commented 6 years ago

Honestly, it sounds like a module resolution issue, instead of anything strictly related to Nest. I saw a bunch of similar issues regarding Angular and I don't think there is a well-known solution available already.

muyu66 commented 6 years ago

it's sad

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.