nrwl / nx

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

Adding nx to a yarn monorepo and generating a nestjs app has multiple issues #7115

Closed raarts closed 2 years ago

raarts commented 3 years ago

Current Behavior

Adding nx to a yarn monorepo and generating a nestjs app does not generate a package.json for that app. Moreover building the generate nest app throws Typescript errors.

Expected Behavior

In a yarn monorepo I expect each package to have its own package.json to be able to track dependencies. Also some stacks need their own node_modules (expo for example)

Steps to Reproduce

I created a minimal yarn workspaces setup:

Clone git@github.com:raarts/nx-after-yarn-workspaces.git Next run:

npx add-nx-to-monorepo
yarn add -W -D @nrwl/nest
npx nx g @nrwl/nest:app ev

Notice there's no package.json in packages/ev

Now run yarn nx build ev This will result in the error log below.

Failure Logs

yarn nx build ev
yarn run v1.22.10
$ /Users/raarts/work/nx-after-yarn-workspaces/node_modules/.bin/nx build ev

> nx run ev:build
Failed to load /Users/raarts/work/nx-after-yarn-workspaces/packages/ev/tsconfig.app.json: Missing baseUrl in compilerOptions
tsconfig-paths-webpack-plugin: Found no baseUrl in tsconfig.json, not applying tsconfig-paths-webpack-plugin
Hash: 89f6585197992a100d78
Built at: 09/23/2021 9:39:26 PM
Entrypoint main = main.js main.js.map
chunk {main} main.js, main.js.map (main) 5.07 KiB [entry] [rendered]

ERROR in /Users/raarts/work/nx-after-yarn-workspaces/packages/ev/tsconfig.app.json
[tsl] ERROR
      TS5052: Option 'emitDecoratorMetadata' cannot be specified without specifying option 'experimentalDecorators'.

ERROR in ./packages/ev/src/main.ts
[tsl] ERROR
      TS5052: Option 'emitDecoratorMetadata' cannot be specified without specifying option 'experimentalDecorators'.

ERROR in ./packages/ev/src/app/app.module.ts
[tsl] ERROR
      TS5052: Option 'emitDecoratorMetadata' cannot be specified without specifying option 'experimentalDecorators'.

ERROR in ./packages/ev/src/app/app.controller.ts
[tsl] ERROR
      TS5052: Option 'emitDecoratorMetadata' cannot be specified without specifying option 'experimentalDecorators'.

ERROR in ./packages/ev/src/app/app.service.ts
[tsl] ERROR
      TS5052: Option 'emitDecoratorMetadata' cannot be specified without specifying option 'experimentalDecorators'.

ERROR in packages/ev/src/app/app.controller.ts:6:14
TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.
    4 |
    5 | @Controller()
  > 6 | export class AppController {
      |              ^^^^^^^^^^^^^
    7 |   constructor(private readonly appService: AppService) {}
    8 |
    9 |   @Get()

ERROR in packages/ev/src/app/app.controller.ts:10:3
TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.
     8 |
     9 |   @Get()
  > 10 |   getData() {
       |   ^^^^^^^
    11 |     return this.appService.getData();
    12 |   }
    13 | }

ERROR in packages/ev/src/app/app.module.ts:11:14
TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.
     9 |   providers: [AppService],
    10 | })
  > 11 | export class AppModule {}
       |              ^^^^^^^^^
    12 |

ERROR in packages/ev/src/app/app.service.ts:4:14
TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.
    2 |
    3 | @Injectable()
  > 4 | export class AppService {
      |              ^^^^^^^^^^
    5 |   getData(): { message: string } {
    6 |     return ({ message: 'Welcome to ev!' });
    7 |   }

———————————————————————————————————————————————

>  NX   ERROR  Running target "ev:build" failed

Environment

  Node : 16.2.0
  OS   : darwin x64
  yarn : 1.22.10

  nx : 12.9.0
  @nrwl/angular : Not Found
  @nrwl/cli : 12.9.0
  @nrwl/cypress : Not Found
  @nrwl/devkit : 12.9.0
  @nrwl/eslint-plugin-nx : 12.9.0
  @nrwl/express : Not Found
  @nrwl/jest : 12.9.0
  @nrwl/linter : 12.9.0
  @nrwl/nest : 12.9.0
  @nrwl/next : Not Found
  @nrwl/node : 12.9.0
  @nrwl/nx-cloud : Not Found
  @nrwl/react : Not Found
  @nrwl/schematics : Not Found
  @nrwl/tao : 12.9.0
  @nrwl/web : Not Found
  @nrwl/workspace : 12.9.0
  @nrwl/storybook : Not Found
  @nrwl/gatsby : Not Found
  typescript : 4.2.4
linbudu599 commented 3 years ago

A tmp solution:

add configurations below to root/tsconfig.base.json:

{
  "compilerOptions": {
    "baseUrl": "./",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  }
}

And it should works correctly (for me at least), npx add-nx-to-monorepo creates incorrect tsconfig.base.json like:

{
  "compilerOptions": {}
}

Also, command yarn nx g @nrwl/nest:app ev creates tsconfig.app.json like:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/out-tsc",
    "module": "commonjs",
    "types": ["node"],
    "emitDecoratorMetadata": true,
    "target": "es2015"
  },
  "exclude": ["**/*.spec.ts"],
  "include": ["**/*.ts"]
}

this seems to be abnormal too, emitDecoratorMetadata should be used with emitDecoratorMetadata together, but as tsconfig.base.json has decorator related rules defined already, I don't think it's necessary to have it it PROJECT/tsconfig.app.json

linbudu599 commented 3 years ago

@vsavkin @FrozenPandaz

raarts commented 3 years ago

I'd like to note that I consider not generating the package.json to be the bigger problem.

ajwootto commented 3 years ago

There's a discussion on the per-project package.json's here: https://github.com/nrwl/nx/issues/1777

One problem when trying to use Nx with yarn workspaces is that the default webpack configs for the Node builder don't account for node_modules folders anywhere except the root when figuring out externals.

If you have a structure in your repo like this:

node_modules/
apps/
  my-app/
    node_modules/
    app.js
    package.json // requires my-lib
libs/
  my-lib/
    node_modules/
    package.json

Yarn workspaces would install certain dependencies of my-lib inside its own node_modules directory. This works when running a regular Node app without webpack because it uses the symlink to my-lib in the root node_modules directory to resolve everything correctly.

However, by default Nx uses tsconfig path aliases to point your apps at your libs. This means that the lib is included in the compiled program, but the node_modules inside the lib's directory are not. They are treated as "externals", but require statements aren't modified to point to the actual location of the dependencies in the lib's node_modules folder. This causes the running program to only look in the root node_modules directory for that package, where it will potentially find a different version of the package.

For this reason I found this section of the docs confusing: https://nx.dev/l/r/guides/lerna-and-nx#misconception-you-have-to-choose-between-nx-and-yarn-workspaceslerna

It seems to imply that Nx doesn't "care" whether you have multiple node_modules folders in your project, which just isn't true for Node applications (though it might be true for frontend projects where there are no externals and everything is bundled together)

dvins commented 2 years ago

Does anyone have any suggestions for resolving this? Working on introducing Nx into a monorepo in conjunction with Yarn Workspaces. We have a variety of NestJS backend microservices that rely upon several common libraries we internally publish as NPM packages.

Using the @nrwl/node:package in the modules and @nrwl/node:build for the microservice generally works without issue when doing an nx build.

However, when using an nx serve we get hit with the "Module not found..." errors.

Interestingly enough, we can delete the subdirectory in the root level node_modules that has the symlinks to the source, and then nx serve works well with full watch/change support into those dependencies.

github-actions[bot] commented 2 years ago

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! 🙏

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.