Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Built-in dependencies working with --bundle --platform=node sometimes. Suggested regex to work #3888

Open
admartinez-edicom opened this issue Aug 20, 2024 · 1 comment

Comments

@admartinez-edicom
Copy link

I'm trying to use esbuild in order to bundle into a single file our production node code. However we are having some troubles with the built-in modules of node (http, https and fs but I believe it will happen with all of them).

After analyzing the generated bundle I came up with a very silly solution that is applying this regex to the final bundle:
sed 's/moduleName = filename;/moduleName = filename;\\n basedir = \\x27core:\\x27;/g'

While writing this issue we realize that it happens sometimes but I cannot determinate the reason.

I have created a repo with a sample code that behaves similar to my production code.

There are 3 files in this repo and 4 scripts:

  • app-ok1.ts --> starts elastic-apm, it works perfectly after being bundled with esbuild. npm run build-ok1 && node app-ok1.js
  • app-ok2.ts --> starts an express server, it works perfectly after being bundled with esbuild. npm run build-ok2 && node app-ok2.js
  • app-ko.ts --> it has the same code of both files, it fails when running the bundled file. I provide 2 scripts:
    • npm run build-ko && node app-ko.js --> it fails
    • npm run build-ko-with-fix && node app-ko-with-fix --> it applies the regex I provide and the app works perfectly

The error when failing is:

Error: Cannot find module '/home/admartinez/Desktop/esbuild/modules/http.js'
Require stack:
- /home/admartinez/Desktop/esbuild/app-ko.js
at Module._resolveFilename (node:internal/modules/cjs/loader:1140:15)
at Module._load (node:internal/modules/cjs/loader:981:27)
at Module.require (node:internal/modules/cjs/loader:1231:19)
at Module.patchedRequire (/home/admartinez/Desktop/esbuild/app-ko.js:16470:39)
at Hook._require.Module.require (/home/admartinez/Desktop/esbuild/app-ko.js:16438:31)
at require (node:internal/modules/helpers:177:18)
at Instrumentation._patchModule (/home/admartinez/Desktop/esbuild/app-ko.js:22303:23)
at /home/admartinez/Desktop/esbuild/app-ko.js:22243:24
at Module.patchedRequire (/home/admartinez/Desktop/esbuild/app-ko.js:16546:32)
at Hook._require.Module.require (/home/admartinez/Desktop/esbuild/app-ko.js:16438:31)
at require (node:internal/modules/helpers:177:18)
at node_modules/methods/index.js (/home/admartinez/Desktop/esbuild/app-ko.js:61564:16)
at __require (/home/admartinez/Desktop/esbuild/app-ko.js:11:50)
at node_modules/express/lib/router/route.js (/home/admartinez/Desktop/esbuild/app-ko.js:61611:19)
at __require (/home/admartinez/Desktop/esbuild/app-ko.js:11:50)
at node_modules/express/lib/router/index.js (/home/admartinez/Desktop/esbuild/app-ko.js:61734:17)
at __require (/home/admartinez/Desktop/esbuild/app-ko.js:11:50)
at node_modules/express/lib/application.js (/home/admartinez/Desktop/esbuild/app-ko.js:64408:18)
at __require (/home/admartinez/Desktop/esbuild/app-ko.js:11:50)
at node_modules/express/lib/express.js (/home/admartinez/Desktop/esbuild/app-ko.js:66164:17)
at __require (/home/admartinez/Desktop/esbuild/app-ko.js:11:50)
at node_modules/express/index.js (/home/admartinez/Desktop/esbuild/app-ko.js:66230:23)
at __require (/home/admartinez/Desktop/esbuild/app-ko.js:11:50)
at Object. (/home/admartinez/Desktop/esbuild/app-ko.js:66236:30)
at Module._compile (node:internal/modules/cjs/loader:1364:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
at Module.load (node:internal/modules/cjs/loader:1203:32)
at Module._load (node:internal/modules/cjs/loader:1019:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12)
at node:internal/main/run_main_module:28:49 {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/home/admartinez/Desktop/esbuild/app-ko.js' ]
}

I came up with this solution after realizing that when the variable basediris empty, the generated file use the current working directory to resolve modules. So in the "core-module-branch" I set this variable to 'core:'

if (core === true) { if (hasWhitelist === true && modules.includes(filename) === false) { debug("ignoring core module not on whitelist: %s", filename); return exports3; } moduleName = filename; basedir = 'core:'; // new code } else if (hasWhitelist === true && modules.includes(filename)) { const parsedPath = path.parse(filename); moduleName = parsedPath.name; basedir = parsedPath.dir; } else {

Could you please give me any feedback? We try the --target argument with all sorts of value but all of them generate the same code

@hyrious
Copy link

hyrious commented Aug 20, 2024

That error was because elastic-apm-node adds a custom hook to replace some builtin and thrid-party modules. It redirects the require call to modules like http and replace that with the file under itself. This code pattern is not bundle-able since it relies on a real file structure during runtime.

Your ok1 script works because it just doesn't hit those hooks. However, when express imports http, it hits and cannot find a ./modules/http.js relative to the bundled file.

In summary, you'd better not bundle elastic-apm-node with either --external:elastic-apm-node or --packages=external.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants