nrwl / nx

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

Cannot find module after successful build #16884

Closed devklick closed 9 months ago

devklick commented 1 year ago

Current Behavior

I have two libs; one which is intended as an AWS Lambda entry point (my-lambda), and one which is a general library that will contain shared code (my-lib). The former imports the latter.

After building my-lambda and trying to run it, it falls over because it cannot find my-lib when trying to import it.

Error: Cannot find module '@myorg/my-lib' Require stack: /home/user/repos/nx-issue/myorg/dist/packages/libs/my-lambda/src/index.js

How can I get this to work? The only way I've have some success is to bundle with es-build, but this produces a single file with all the code, which I'd rather avoid.

Expected Behavior

I expect the build code to either import successfully via @myorg/my-lib, or maybe to use an absolute path instead.

GitHub Repo

https://github.com/devklick/nx-issue

Steps to Reproduce

1.npx nx generate @nx/js:library my-lambda --unitTestRunner=jest --testEnvironment=node --no-interactive

  1. npx nx generate @nx/js:library my-lib --unitTestRunner=jest --testEnvironment=node --no-interactive
  2. npx nx build my-lambda
  3. node dist/packages/libs/my-lambda/src/index.js

    Error: Cannot find module '@myorg/my-lib'
    Require stack:
    /home/user/repos/nx-issue/myorg/dist/packages/libs/my-lambda/src/index.js

Nx Report

Node   : 18.16.0
   OS     : linux x64
   npm    : 9.6.4
   Hasher : Native

   nx                 : 16.1.1
   @nx/js             : 16.1.1
   @nx/jest           : 16.1.1
   @nx/linter         : 16.1.1
   @nx/workspace      : 16.1.1
   @nx/devkit         : 16.1.1
   @nx/esbuild        : 16.1.1
   @nx/eslint-plugin  : 16.1.1
   @nx/node           : 16.1.1
   @nrwl/tao          : 16.1.1
   typescript         : 5.0.4

Failure Logs

No response

Operating System

Additional Information

I've also tried to create my-lambda as an app rather than a lib (see this ticket for more info on this approach). With this approach, the build output successfully imports my-lib, but there's no exported function for my lambda handler.

sgtsquiggs commented 1 year ago

We're able to reproduce this as well.

sgtsquiggs commented 1 year ago

I can bundle properly:

nx build whatever --bundle
node dist/packages/whatever/main.js
[ ready ] http://localhost:3000

(whatever is a simple express service, importing models from another package)


The graph does not show the dependency on the lib as well:

image
sgtsquiggs commented 1 year ago

I have fixed this on my end I think:

I am using pnpm to create my workspace (pnpm create nx-workspace blah). After generating a package, I need to pnpm init in the package root. I then pnpm add libpackagename@workspace\* and it's now a dependency in the package's package.json. When I build whatever, libpackagename is also built. Same with serve.

Should the generator be creating the package.json for me or is this a hidden step with pnpm workspaces?

devklick commented 1 year ago

Ignore this - it didnt work (I was looking at the wrong build output :cry: )

For my use-case (mentioned in description), I've managed to get something suitable working. TL;DR - we need to use esbuild and specify the outbase option to retain directory structure.

Steps:

1. Generate the library using esbuild as the bundler (this will serve as the lambda handler)

npx nx generate @nx/js:library my-bundled-lib --bundler=esbuild --no-interactive

2. Update this libs package.json and add outbase to esbuildOptions in the build targets options:

"esbuildOptions": {
  "outbase": "src"
},

3. Build the lib

npx nx build my-bundled-lib

The output has resolved all imported names from other libs and they're now relative paths, and the original folder structure is retained due to specifying the outbase option.

I'm gonna leave this bug open as I expect that you shouldnt have to use esbuild for imports to be resolved at build time. I expect using the default bundler (tsc) should do this also.


@sgtsquiggs I cant answer in regards to pnpm workspaces as I've never used them, but package.json files are generated for me whenever I generate an nx lib/app in a standard workspace (which you probably already know).

sgtsquiggs commented 1 year ago

@devklick I am not sure we have the same issue then! They do seem related.

@AgentEnder should I open a new issue with a separate example repo, or do you think these are the same?

rixrix commented 1 year ago

I'm having the same exact issue

node:internal/modules/cjs/loader:1078
  throw err;
  ^

Error: Cannot find module '@datapipe/shared'
Require stack:
>  NX  Falling back to ts-node for local typescript execution. This may be a little slower.
  - To fix this, ensure @swc-node/register and @swc/core have been installed

 >  NX   Report complete - copy this into the issue template

   Node   : 18.14.2
   OS     : darwin arm64
   npm    : 9.5.0
   Hasher : Native

   nx                 : 16.2.1
   @nx/js             : 16.2.1
   @nx/jest           : 16.2.1
   @nx/linter         : 16.2.1
   @nx/workspace      : 16.2.1
   @nx/cypress        : 16.2.1
   @nx/devkit         : 16.2.1
   @nx/esbuild        : 16.2.1
   @nx/eslint-plugin  : 16.2.1
   @nx/next           : 16.2.1
   @nx/node           : 16.2.1
   @nx/react          : 16.2.1
   @nrwl/tao          : 16.2.1
   @nx/web            : 16.2.1
   typescript         : 5.0.4
sgtsquiggs commented 1 year ago

We switched to using preset=ts which is an integrated monorepo for us. Libraries still have a package.json and they function properly. No pnpm workspace. Seems the package based monorepo isn’t compatible with a lot of generators yet, or there are issues underlying.

Regardless, we are happy with this approach.

rixrix commented 1 year ago

@sgtsquiggs can confirm on this, switched to ts works.... I was solely interested in just plain JS/ESM but it seems a bit of a pain. tnx

sgtsquiggs commented 1 year ago

yeah we still cannot import pure esm libraries (js+d.ts) but anything with cjs works fine.

miguel94000 commented 1 year ago

Hi i have a same issue. My build(@nx/esbuild:esbuild) works, but when i run nx serve api with @nx/linter:eslint, i have this error message :

`Error: Cannot find module 'src/app/middlewares/auth' Require stack:

`

github-actions[bot] commented 9 months 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 8 months 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.