-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
Support for ESM #106868
Comments
Pinging @elastic/kibana-operations (Team:Operations) |
After just having a chat with @trentm, I think it should be possible to "hack" our implementation of the APM agent to work despite running as ESM (which officially isn't supported by the agent):
I think (besides core modules) that we only care about |
Possibly also the following. (I'm reading through Kibana's current "dependencies" set and comparing to modules for which our APM has some sort of instrumentation.)
|
Getting support for ESM in Kibana is becoming exceedingly important as more and more modules that we rely upon from npm has switched to being ESM only. So we're essentially stuck on older non-maintained versions of many of our dependencies which might contain bugs and security vulnerabilities. @elastic/kibana-operations Is APM the only thing holding us back, or are there other issues? @trentm any updates on the APM front, or is our best best still to "hack" the implementation as you suggested previously? |
I agree with you @watson, we really need to figure out how to at least support using ESM only packages from NPM. |
We are currently investigating ESM support (elastic/apm-agent-nodejs#2343) but this doesn't promise full ESM support for the 8.5 timeframe. So in the near term the best bet is still the "hack", unfortunately. On the "hack": In addition to |
@spalger I would suggest that we create a proof-of-concept that uses the hack @trentm described. The actual hack part of the implementation shouldn't take that much longer compared to the time it takes to do the other required changes. That would give us an idea if this is shippable or if we need to wait for full APM support. One other ask I have is that we afterwards investigate how much work it would take to backport this to I'll happily help with this if it's needed. |
I'm unclear what the "hack" we're talking about is. I agree that whatever we do here will probably need to be backported or re-implemented on 7.17. My knowledge about what is necessary on a technical level is pretty low. I've set the Do you have an idea of what types of changes would be required in the repository besides this APM "hack" which I'm assuming would be mostly invisible to most people working in the repository? |
The "hack" is to:
It is possible this could all be contained to https://github.com/elastic/kibana/blob/main/packages/kbn-apm-config-loader/src/init_apm.ts but I'm not positive. The hack would be to explicitly add the following after the require('http');
require('https');
require('@hapi/hapi');
require('@elastic/elasticsearch');
// ... possibly others like bluebird (ew), handlebars When I played with that hack a while back (notes here: https://gist.github.com/trentm/ceb76cd5b1763811fc6290dd4040819e#another-workaround-user-side-only), I had put this file in a ".cjs" file so that Possibly another path is to get "require" back in an ESM module file (https://nodejs.org/api/module.html#modulecreaterequirefilename), notes here: https://gist.github.com/trentm/ceb76cd5b1763811fc6290dd4040819e#a-user-workaround-use-require-for-your-esm-files |
Thanks for the info @trentm, I'm still unclear on the rules around what can load what when it comes to ESM and commonjs, but that idea of using commonjs to instrument the important modules before they're loaded via ESM makes sense to me. I can imagine that hack might work today and break when we upgrade these services without people really noticing, and possibly in a way that prevents us from using this hack... Have we considered an alternate approach that would allow us to consume ESM-only packages from commonjs... what if we wrote a commonjs wrapper around ESM-only packages, which can async-load the package with One such package I'm thinking of is |
Currently the APM agent hooks into What about having a test file that ensures expected module instrumentations are working:
This might also guard against other ways that APM instrumentation can stop: For example if Kibana updates to a newer version of Hapi or |
Sorry, yeah, my idea was more about sticking with commonjs so that APM continues to work but allowing Kibana to consume ESM-only dependencies until APM is ready to instrument native ESM |
Ah, I understand now. Yah, that works, but perhaps sucks for you having to write those wrappers and training Kibana devs to use the wrapped versions. |
Yeah, we have the ESLint powers to ensure people use the wrappers, but it's certainly not ideal. Though it should be relatively limited to packages which both moved to ESM-only, and have unfixed security issues in the pre-ESM-only versions. |
@trentm It looks like the APM agent now has ESM support: elastic/apm-agent-nodejs#3381 Does that mean that we don't need to do any of the workarounds mentioned above for the APM agent to work if Kibana switches to use ESM directly? Also, I'm not sure if this is relevant for ESM compatibility with the APM agent, but Kibana is currently running Node.js 18 but will soon be upgrading to Node.js 20 (most likely within the next few months) |
@watson The APM agent's ESM support is documented here: https://www.elastic.co/guide/en/apm/agent/nodejs/current/esm.html
Aside: What are the advantages of moving Kibana to using ESM? |
Thanks for the very thorough explanation of the current state!
Every day more and more 3rd party packages we depend on via npm switch to be pure ESM. We can't upgrade to those as long as we don't support ESM. This becomes especially critical once a bug or security issue is only fixed in the ESM-only version of the package. |
Since v12, Node.js has supported ESM. We should investigate the best way to support ESM in the Kibana project.
Our node Babel preset current transpiles down to commonjs. Can we instead use ESM globally?
Does APM support ESM? @watson mentioned there might still be an issue hooking into the loader.
The text was updated successfully, but these errors were encountered: