nrwl / nx

Smart Monorepos · Fast CI
https://nx.dev
MIT License
23.29k stars 2.32k forks source link

node-apps: unable to import custom paths from tsconfig.json #902

Closed xmlking closed 5 years ago

xmlking commented 5 years ago

I have following setup for my node-app when I run ng serve api i am getting Module not found error

tsconfig.json

    "paths": {
      "@env-api/*": [
        "apps/api/src/environments/*"
      ],
}

config.service.ts

import { environment } from '@env-api/environment';

ERROR

ERROR in ./apps/api/src/config/config.service.ts
Module not found: Error: Can't resolve '@env-api/environment' in '/.../ngx-starter-kit/apps/api/src/config'

similar setup works for angular webapps

samtsai commented 5 years ago

What does your tsconfig.app.json file look like in your node-app?

xmlking commented 5 years ago

tsconfig.app.json for node-app

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/apps/api",
    "module": "commonjs",
    "target": "es6",
    "types": ["node"]
  },
  "exclude": ["**/*.spec.ts"],
  "include": ["**/*.ts"]
}
FrozenPandaz commented 5 years ago

This is an odd error message:

Module not found: Error: Can't resolve '@env-api/environment' in '/.../ngx-starter-kit/apps/api/src/config'

Can you please provide a repro so we can look deeper?

xmlking commented 5 years ago

I have to change "apps/api/src/environments/*" to "apps/api/src/environments/environment.ts" to make it work. but wonder how it is working for webapps!

https://github.com/xmlking/ngx-starter-kit/blob/develop/tsconfig.json

      "@env-api/environment": [
        "apps/api/src/environments/environment.ts"
      ],
xmlking commented 5 years ago

I am also trying to make e2e tests work for API, but getting following error with ng test api-e2e may be related issue!

  ● Test suite failed to run

    Cannot find module '@env-api/environment' from 'config.service.ts'

      1 | import { Injectable } from '@nestjs/common';
    > 2 | import { environment } from '@env-api/environment';
        | ^
      3 | 
      4 | // tslint:disable-next-line
      5 | const packageJson = require('../../../../package.json');

      at Resolver.resolveModule (../../node_modules/jest-resolve/build/index.js:221:17)
      at Object.<anonymous> (../api/src/config/config.service.ts:2:1)
skydever commented 5 years ago

hi @xmlking

Had the time to have a quick look and came to this, maybe it is useful for you.

When you use a * in the paths entry of a tsconfig file the module resolution would be like this:

The example tsconfig.json would look like:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": [
        "*",
        "generated/*"
      ]
    }
  }
}

This tells the compiler for any module import that matches the pattern * (i.e. all values), to look in two locations:

I think this is why the change to apps/api/src/environments/environment.ts was required (only 1 * in your config entry that can't be replaced with a <moduleName>). Usually you reference an index.ts and export all the stuff there.

About the e2e issue, I think this line is the key here, does not seem ideal ... I think the source is not included via the tsconfig.e2e.json? But I would rethink that setup, I think you can get rid of // @ts-ignore ...

skydever commented 5 years ago

... just saw that you had 2 *, so maybe it was not that concerning the 1st error ...

jmcdo29 commented 5 years ago

@xmlking Did you ever figure out why this was happening? I'm trying to move an existing project into an nx workspace and I've come to the same issue. Angular web apps work, nestjs server apps do not.

xmlking commented 5 years ago

@jmcdo29 not yet found the cause , but you might find some workarounds from my repo.

xmlking commented 5 years ago

@FrozenPandaz apps/angularApp --> libs/shared works with paths in tsconfig.json same logic for apps/nestjsApp --> libs/shared didn't work. are we missing some config in nodejs builders ?

jbjhjm commented 5 years ago

@jmcdo29 @xmlking fix is coming soon. I experienced the same issue. The reason for this is angular builder implements a different path resolution library than the nx builder which is used for non-angular projects & libraries. @FrozenPandaz has a fix in the makings (thx!) and it looks like all tests have passed and it's going to be merged soon! :)

konstantinschuette commented 3 years ago

I would guess that this is fixed by now. But I still experience this bug. Adding this to the root tsconfig.base.json works fine:

"compilerOptions": {
    "paths": {
      "@env-api/environment": ["apps/client/src/environments/environment.ts"]
    }
  }

But not if you add it to a specific app.

Found my mistake: The paths in the main tsconfig get overwritten by the one in the app. I want to extend the paths. Is this possible?

jbjhjm commented 3 years ago

@konstantinschuette no, this is still a limitation of tsconfig, unfortunately. As soon as you define a child paths list in a child file, it will discard the inherited paths. I think there was a larger discussion somewhere in the typescript repo issues. But can't find it right now.

To make it short: Typescript devs say it is working as intended, there are no plans to add this feature so we likely have to live with this limitation.

I can guess that you are looking for a solution to use the same import path pointing to different file based on the selected project. To make that work, I ended up adding a custom/partial webpack config which resolves a "magic" configuration import. Also this magic path must not be imported into a ts file (as unknown to tsconfig). Use a js file to require the magic path and reexport using the js module. In tsconfig, add a path pointing to the js file. Good luck!

david-j-davis commented 2 years ago

@konstantinschuette @jbjhjm this is kind of unreal to me that inside of Nx such a small thing like this is catastrophic for moving forward with global libs, right? This is crazy. I feel like the least the Nx team could do is let everyone know this is a limitation and provide a workaround.

jbjhjm commented 2 years ago

@david-j-davis I'm not sure what limitation you are talking about exactly. I'm not aware of any major issues atm, provided you are specifying all paths within tsconfig.base.json. I agree that it would be cool to be able to add additional paths or even override them per app. But that's something that is not supported by typescript devs. And I don't feel like nrwl should invest the time needed to implement a custom solution maintain it. There's enough other stuff to do.

As mentioned, if you need magically changing per-app paths, use @angular-builders/custom-webpack and add a custom path resolution webpack plugin to the apps.

github-actions[bot] commented 1 year ago

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.