-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[v8] Update for ESM monkeypatch + ESM file structure #10046
Comments
To validate our package.json setup, we'll need to add https://www.npmjs.com/package/@arethetypeswrong/cli as a validation check in CI. |
I don't think we'll need to worry about |
There is also usage of |
We'll still need something to add breadcrumbs right? Or does that work? |
Related GH issue: nodejs/node#49440 |
For this we hook into the otel instrumentation and add breadcrumbs from there - see the http integration in node-experimental! |
Turns out |
package.json https://nodejs.org/api/packages.html#exports The history suggests conditional exports was added even later but I guess it will still fallback to |
One thing we might need to consider is our usage of Can we somehow get rid of this dependency? Chances are that this problem is limited to Vite as #10042 shows. However, while we can change the respective vite config setting in Astro for our users, it's not as easy in other frameworks. I'd vote we look at this once we made the other changes to check if it's actually still a problem by then. Maybe it was just a by-product of us using older package.json properties or the generic file extensions. |
It's on my todo list. The latest version is fully typescript so I think I started a PR to vendor it. EDIT Ah I remembered what the issue was, they appear to have dropped support for older node versions: |
Will this work with bundling? Since register accepts a So the following code: import { register } from "node:module";
const hookScript = Buffer.from(`
export async function initialize() {
console.log("initialize");
}
export async function resolve(specifier, context, nextResolve) {
console.log("resolve", specifier, context);
return nextResolve(specifier);
}
export async function load(url, context, nextLoad) {
console.log("load", url, context);
return nextLoad(url);
}
`);
register(
new URL(`data:application/javascript;base64,${hookScript.toString("base64")}`),
import.meta.url
);
const inspect = await import("node:inspector/promises"); Outputs:
|
I have to test it out, but luckily the opt-out is just asking folks to use |
Closes #9199 This PR vendors the `https-proxy-agent` code and in the process updates to v7.0.0. `https-proxy-agent` is our last remaining cjs-only dependency so this is required for #10046. This removes the following dependencies: - `https-proxy-agent@5.0.1` - `agent-base@6.0.2` - `debug@4.3.4` - `ms@2.1.2` The vendored code has been modified to use the Sentry logger rather than `debug`. Initially, rather than modify the vendored code substantially just to pass our tight lint rules, I've disabled a few of the less important lints that would make it particularly tricky to pull in upstream bug fixes: ```ts /* eslint-disable @typescript-eslint/explicit-member-accessibility */ /* eslint-disable @typescript-eslint/member-ordering */ /* eslint-disable jsdoc/require-jsdoc */ ``` ## Min supported Node version `https-proxy-agent` has a `@types/node@14.18.45` dev dependency but apart from adding an import for `URL`, I can't find anything that would stop it working on older versions of node and there is nothing in the changelogs that would suggest the min supported version has changed. --------- Co-authored-by: Abhijeet Prasad <aprasad@sentry.io>
I'd recommend publint too as it currently finds error that arethetypeswrong does not find: https://publint.dev/@sentry/node |
We don't need to concern ourselves with bundling issues for now. If users bundle their code, libraries will not be loaded via the import hook anyway! I was initially left confused over how After experimenting and consulting the docs I can conclude that there is no way to have import hooks work fully without passing a command line argument to node. As per the ESM spec, imports are resolved and loaded before any code is executed. The node.js docs say the import hook registration should be via the
So calling If we add a package export for node --import @sentry/node/register app.js |
I'm going to close this issue. We now have 3 follow up areas:
Opened #11067 to track ESM support for Remix SDK.
Opened #11066 to track ESM support for serverless SDKs.
Overall we've identified some issues with OpenTelemetry instrumentation with ESM (even more problematic when bundling). We created #11070 to track these issues to follow up. |
We’re going to be adding proper support for ESM in the Sentry repo.
Requirement:
require
in ESM bundles at all.mjs
file extension.cjs
file extensionTasks
@sentry/aws-serverless
and@sentry/google-cloud-serverless
ESM compat #11066Read below for some justification and information
Module Customization Hooks for Monkey Patching
For ESM bundles on server-side, we’ll require a minimum Node version of
18.6.0
or20.6.0
or higher. Otherwise we’ll support CJS bundles for Node 14+ generally. This is because we want access to Node customization hooks, which allows us to add monkeypatching for esm modules programatically (doesn't require command-lineloader
).We can take some inspiration here from https://github.com/DataDog/import-in-the-middle
Registering hooks to affect an import still needs to happen before the import is resolved, so there are ordering issues, but I think we can work around this by recommending that
Sentry.init
is called as soon as possible, and encouragingSentry.addIntegration
patterns for integrations that require objects from different libraries (like express withapp
).The modules we need register via
register
API:Nodenode:http
andnode:https
(diagnostics channels only works well Node 16+, so we need to maintain this for Node 14@remix-run/server-runtime
and- monkeypatchreact-router-dom
GoogleCloudGrpc
integrationrequire('google-gax')
GoogleCloudHttp
integration withrequire('@google-cloud/common')
AWSServices
integration withrequire('aws-sdk/global')
We need to re-evaluate if we need monkeypatching for the database integrations now that we have OpenTelemetry.Change File Structure
We’ll need to move our file structure to the following:
Shameless promo: Watch my talk if you want more details about this.
We also should change all node standard library imports to import from
node:X
.Make
dynamicRequire
/loadModule
work with ESM importThis exists to trick webpack, but we use it all over the codebase. We need to add an esm compatible way.
One thing we can do is introduce an async
dynamicRequire
that simulatesawait import
, and then build time replace the functionality ofdynamicRequire
to useimport
orrequire
under the hood?packages/node/src/integrations/anr/index.ts
- to conditionally importworker_threads
. This is just because of Node 12 support, we’ll remove this import entirelypackages/node/src/integrations/local-variables/local-variables-async.ts
- to conditionally importnode:inspector/promises
.packages/utils/src/time.ts
- this needs to be refactored entirely. We still want an isomorphic solution because we need date-time helpers that work across core/browser/node and all other packages, but what should happen is that we look for theglobalThis.performance
instead of relying onperf_hooks
. This means that if the global performance API is not available we will fall back to plain[Date.now](http://Date.now)
and similar helpers (basically only Node 14 for us). We also need to add a smarter timeOrigin calculation that reset’s itself to help alleviate issues with drifting monotonic clock. See Provide a supported way to get anchored clock times open-telemetry/opentelemetry-js#3279 (comment)The text was updated successfully, but these errors were encountered: