question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Adding the esbuild executor to an express preset workspace breaks the serve target

See original GitHub issue

Current Behavior

Using nx 15, starting with the express preset in a new workspace, adding esbuild to the existing express application breaks the serve target as it is unable to find the built module.

Expected Behavior

Running the serve target builds the application in watch mode and runs the application. (In this case I expect the server to start)

Steps to Reproduce

npx create-nx-workspace --preset=express
yarn add -D @nrwl/esbuild
nx g esbuild-project myapp --skipValidation

// This works fine:
nx build myapp

// This fails to find the generated module:
nx serve myapp

An example of the situation after running the above commands can be found here: https://github.com/b-smets/nx-express-esbuild-reproduce

Failure Logs

Error: Cannot find module 'dist/apps/myapp/main.js'
Require stack:
- /Users/bsmets/git/smos/myrepo/node_modules/@nrwl/js/src/executors/node/node-with-require-overrides.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
    at Function.Module._load (internal/modules/cjs/loader.js:746:27)
    at Function.Module._load (/Users/bsmets/git/smos/myrepo/packages/js/src/executors/node/node-with-require-overrides.ts:16:27)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:101:18)
    at Object.<anonymous> (/Users/bsmets/git/smos/myrepo/packages/js/src/executors/node/node-with-require-overrides.ts:20:1)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:12)
[ watch ] build succeeded, watching for changes...

I already did some digging and noticed that the require in @nrwl/js/src/executors/node/node-with-require-overrides.js is getting a relative path 'dist/apps/myapp/main.js` whereas using the original webpack build results in an absolute path. I saw that the webpack executor is resolving the output files against the root context (https://github.com/nrwl/nx/blob/master/packages/webpack/src/executors/webpack/webpack.impl.ts#L201) whereas the esbuild executor does not. Is this an oversight or did I miss a configuration anywhere?

Environment


   Node : 14.19.3
   OS   : darwin x64
   yarn : 1.22.19
   
   nx : 15.0.0
   @nrwl/angular : Not Found
   @nrwl/cypress : Not Found
   @nrwl/detox : Not Found
   @nrwl/devkit : 15.0.0
   @nrwl/esbuild : 15.0.0
   @nrwl/eslint-plugin-nx : 15.0.0
   @nrwl/expo : Not Found
   @nrwl/express : 15.0.0
   @nrwl/jest : 15.0.0
   @nrwl/js : 15.0.0
   @nrwl/linter : 15.0.0
   @nrwl/nest : Not Found
   @nrwl/next : Not Found
   @nrwl/node : 15.0.0
   @nrwl/nx-cloud : Not Found
   @nrwl/nx-plugin : Not Found
   @nrwl/react : Not Found
   @nrwl/react-native : Not Found
   @nrwl/rollup : Not Found
   @nrwl/schematics : Not Found
   @nrwl/storybook : Not Found
   @nrwl/web : Not Found
   @nrwl/webpack : 15.0.0
   @nrwl/workspace : 15.0.0
   typescript : 4.8.4
   ---------------------------------------
   Local workspace plugins:
   ---------------------------------------
   Community plugins:```

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:3
  • Comments:6

github_iconTop GitHub Comments

1reaction
b-smetscommented, Oct 25, 2022

I did some more investigating and I found out that this is caused by a mix of the esbuild executor output and @nrwl/js:node executor. Switching to the @nrwl/node:node executor does not help as it just forwards to the previous one.

The problem is as I described in the first post in this thread: esbuild emits an outputfile path relative to the root of the repo whereas webpack results in a resolved absolute path. When invoking the @nrwl/js:node executor, @nrwl/js/src/executors/node/node-with-require-overrides.ts will perform a require of the output file, but since this is a relative path, the required module is resolved to the current directory which is typically something like <root>/node_modules/@nrwl/js/src/executors/node/ leading to the “cannot find module” error. The webpack executor outputting an absolute path works fine as a require of an absolute path ignores the current directory.

I tried overriding the current directory but unfortunately this does not seem possible through the options of the @nrwl/js:node executor. Snippet of packages/js/src/executors/node/node.impl.ts:

  const subProcess = fork(
    joinPathFragments(__dirname, 'node-with-require-overrides'),
    options.args,
    {
      execArgv,
      stdio: 'inherit',
      env: {
        ...process.env,
        NX_FILE_TO_RUN: event.outfile,
        NX_MAPPINGS: JSON.stringify(mappings),
      },
      // no way to specify the cwd option :(
    }
  );

I think there are two possible solutions:

  • Let the esbuild executor emit a path resolved to the root, similar to how webpack handles its output file. I assume this is a breaking change so this may be difficult.
  • Allow overriding the cwd through the options of the @nrwl/js:node executor. This solution is less ideal but only enhances the api instead of breaking it.

I am willing to create a pull request to do either one of these fixes if you tell me which one you prefer.

There is also still the issue that esbuild by default emits ESM. While this can be overriden to output CJS instead, ESM seems to be the future of the Javascript ecosystem. However, ESM modules cannot be require’d but instead should be imported. This will also require a change to the @nrwl/js:node executor but I guess that is a separate ticket.

0reactions
mcblumcommented, Nov 23, 2022

We’re also seeing this error within our Nx workspace. A fix would definitely be appreciated!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Adding the esbuild executor to an express preset workspace ...
Using nx 15, starting with the express preset in a new workspace, adding esbuild to the existing express application breaks the serve target...
Read more >
@nrwl/esbuild:esbuild | Nx
Bundle a package for different platforms. Note: declaration (*.d.ts) file are not currently generated. Options can be configured in project.json when defining ...
Read more >
@nrwl/next: Versions | Openbase
Revert "feat(js): add srcRootForCompilationRoot option to tsc executor ... core: add back target defaults for all new workspaces (#11936) (caec117) ...
Read more >
How to build angular cli application with esbuild
$ npm install esbuild --save-dev added 1 package (...) Then we need build script. As we are not yet doing complete ...
Read more >
@types/storybook__addon-knobs | Yarn - Package Manager
... Addon-docs: Fix ArgsTable sorting when using of={Component} (#14669); Server: Fix string escaping in CSF compiler (#14615) ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found