You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
The text was updated successfully, but these errors were encountered:
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.
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:
npm run build-ok1 && node app-ok1.js
npm run build-ok2 && node app-ok2.js
npm run build-ko && node app-ko.js
--> it failsnpm run build-ko-with-fix && node app-ko-with-fix
--> it applies the regex I provide and the app works perfectlyThe error when failing is:
I came up with this solution after realizing that when the variable
basedir
is 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
The text was updated successfully, but these errors were encountered: