feat(electron): ship dd-trace-electron package with reduced dependencies#8948
Conversation
🎉 All green!🧪 All tests passed 🔄 Datadog auto-retried 1 job - 1 passed on retry 🎯 Code Coverage (details) 🔗 Commit SHA: 54ca533 | Docs | Datadog PR Page | Give us feedback! |
Overall package sizeSelf size: 6.71 MB Dependency sizes| name | version | self size | total size | |------|---------|-----------|------------| | import-in-the-middle | 3.3.1 | 122.62 kB | 437.94 kB | | opentracing | 0.14.7 | 194.81 kB | 194.81 kB | | dc-polyfill | 0.1.11 | 25.74 kB | 25.74 kB |🤖 This report was automatically generated by heaviest-objects-in-the-universe |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #8948 +/- ##
==========================================
+ Coverage 96.55% 96.57% +0.01%
==========================================
Files 918 921 +3
Lines 121410 121633 +223
Branches 20900 21190 +290
==========================================
+ Hits 117229 117464 +235
+ Misses 4181 4169 -12
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
BenchmarksBenchmark execution time: 2026-07-10 19:32:29 Comparing candidate commit 54ca533 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 2314 metrics, 44 unstable metrics.
|
…ackage.electron.json Adds scripts/generate-electron-package.js to automatically generate a version of package.json with excluded optional dependencies for the dd-trace-electron package variant. Supports --check flag for CI validation. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…itignore generated file
…istering Adds Tracer.registerFeature() / NoopProxy.registerNoop() so subsystems can opt into the tracer without being hardcoded in proxy.js. OpenFeature uses this via a new register.js that self-registers on require. The Electron entrypoint (index.electron.js) simply omits that require, so OpenFeature and its native dep (@datadog/openfeature-node-server) are absent from the Electron build with no conditional logic in the core. index.js delegates to index.electron.js after calling register.js, keeping both entrypoints in sync with zero duplication. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
OpenFeature is no longer hardcoded in proxy.js so the test now calls registerFeature() explicitly with the mocked modules instead of passing them through proxyquire. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Both index.js and index.electron.js now require ./src/bootstrap directly rather than one depending on the other. index.js remains the only entrypoint that registers OpenFeature. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
bootstrap.js was requiring ./proxy directly, bypassing src/index.js which handles DD_TRACE_ENABLED=false and Jest worker environments by returning the noop proxy instead. This caused global._ddtrace to always be the full Tracer in contexts where it should be the noop. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
The agent test helper clears specific module cache entries before rebuilding the tracer. src/bootstrap.js was not in the eviction list, so after global._ddtrace was deleted the cached bootstrap module still exported the stale (deleted) proxy instance instead of re-running initialization. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…rkflow Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Requiring openfeature/register.js from index.js previously loaded proxy.js as a side-effect (to call Tracer.registerFeature), which transitively loaded datadog-instrumentations/register.js. That module registers logAbortedIntegrations with beforeExitHandlers, but at that point the global symbol was not yet set up by bootstrap.js, so the optional-chaining silently no-oped and the handler was never registered. Introduce a feature-registry module that openfeature/register.js pushes to directly without requiring proxy.js. proxy.js and noop/proxy.js read from it at class-definition time (after the global symbol is set up by bootstrap.js). This keeps all initialization gated on !global._ddtrace. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
269673d to
68e0b28
Compare
Fix broken `needs: publish-latest` reference by renaming to `publish-electron` with `needs: publish`. Drop the v5.x branch guard since the job already only runs when publish succeeds (which itself is gated to release branch pushes via setup). Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1b7dac6977
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
- Pass computed npm dist-tag to electron publish so maintenance branches don't erroneously move the latest tag - Make electron publish idempotent: skip if the version is already on the registry, matching the behaviour of the regular publish step - Exclude oxc-parser from the electron package (native bindings) - Restore @DataDog/libdatadog exclusion; crashtracking is not supported in Electron — wrap its start() in a local try/catch so a missing libdatadog doesn't abort tracer initialization Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
| const ROOT = path.join(__dirname, '..', '..') | ||
| const PACKAGE_JSON = path.join(ROOT, 'package.json') | ||
| const ELECTRON_JSON = path.join(ROOT, 'package.electron.json') | ||
| const BACKUP = path.join(ROOT, 'package.json.bak') |
There was a problem hiding this comment.
Do customers run their application code through bundlers with Electron? And if so does this all work when doing so?
…ies (#8948) * chore(electron): add electron package exclusion config * chore(electron): add electron package generation script and initial package.electron.json Adds scripts/generate-electron-package.js to automatically generate a version of package.json with excluded optional dependencies for the dd-trace-electron package variant. Supports --check flag for CI validation. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * chore(electron): wire electron package verify into lint * chore(electron): add electron publish script * docs(electron): document Dependabot behavior for package.electron.json * chore(electron): move generation to publish time, add release jobs, gitignore generated file * feat(electron): add Electron entrypoint and make OpenFeature self-registering Adds Tracer.registerFeature() / NoopProxy.registerNoop() so subsystems can opt into the tracer without being hardcoded in proxy.js. OpenFeature uses this via a new register.js that self-registers on require. The Electron entrypoint (index.electron.js) simply omits that require, so OpenFeature and its native dep (@datadog/openfeature-node-server) are absent from the Electron build with no conditional logic in the core. index.js delegates to index.electron.js after calling register.js, keeping both entrypoints in sync with zero duplication. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * test(proxy): adapt spec to OpenFeature self-registration OpenFeature is no longer hardcoded in proxy.js so the test now calls registerFeature() explicitly with the mocked modules instead of passing them through proxyquire. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * refactor(electron): extract bootstrap into shared module Both index.js and index.electron.js now require ./src/bootstrap directly rather than one depending on the other. index.js remains the only entrypoint that registers OpenFeature. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * fix(electron): use src/index.js in bootstrap to respect DD_TRACE_ENABLED bootstrap.js was requiring ./proxy directly, bypassing src/index.js which handles DD_TRACE_ENABLED=false and Jest worker environments by returning the noop proxy instead. This caused global._ddtrace to always be the full Tracer in contexts where it should be the noop. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * test(plugins): evict src/bootstrap from require cache on tracer rebuild The agent test helper clears specific module cache entries before rebuilding the tracer. src/bootstrap.js was not in the eviction list, so after global._ddtrace was deleted the cached bootstrap module still exported the stale (deleted) proxy instance instead of re-running initialization. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * chore: add CODEOWNERS entries for electron entrypoints and release workflow Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * fix(electron): fix abort.integration telemetry missing with OpenFeature Requiring openfeature/register.js from index.js previously loaded proxy.js as a side-effect (to call Tracer.registerFeature), which transitively loaded datadog-instrumentations/register.js. That module registers logAbortedIntegrations with beforeExitHandlers, but at that point the global symbol was not yet set up by bootstrap.js, so the optional-chaining silently no-oped and the handler was never registered. Introduce a feature-registry module that openfeature/register.js pushes to directly without requiring proxy.js. proxy.js and noop/proxy.js read from it at class-definition time (after the global symbol is set up by bootstrap.js). This keeps all initialization gated on !global._ddtrace. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * chore: add CODEOWNERS entries for bootstrap and feature-registry Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * ci(electron): refactor release jobs for electron package Fix broken `needs: publish-latest` reference by renaming to `publish-electron` with `needs: publish`. Drop the v5.x branch guard since the job already only runs when publish succeeds (which itself is gated to release branch pushes via setup). Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * fix(electron): address Codex review findings - Pass computed npm dist-tag to electron publish so maintenance branches don't erroneously move the latest tag - Make electron publish idempotent: skip if the version is already on the registry, matching the behaviour of the regular publish step - Exclude oxc-parser from the electron package (native bindings) - Restore @DataDog/libdatadog exclusion; crashtracking is not supported in Electron — wrap its start() in a local try/catch so a missing libdatadog doesn't abort tracer initialization Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --------- Co-authored-by: Claude Sonnet 4.6 <[email protected]>
…ies (#8948) * chore(electron): add electron package exclusion config * chore(electron): add electron package generation script and initial package.electron.json Adds scripts/generate-electron-package.js to automatically generate a version of package.json with excluded optional dependencies for the dd-trace-electron package variant. Supports --check flag for CI validation. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * chore(electron): wire electron package verify into lint * chore(electron): add electron publish script * docs(electron): document Dependabot behavior for package.electron.json * chore(electron): move generation to publish time, add release jobs, gitignore generated file * feat(electron): add Electron entrypoint and make OpenFeature self-registering Adds Tracer.registerFeature() / NoopProxy.registerNoop() so subsystems can opt into the tracer without being hardcoded in proxy.js. OpenFeature uses this via a new register.js that self-registers on require. The Electron entrypoint (index.electron.js) simply omits that require, so OpenFeature and its native dep (@datadog/openfeature-node-server) are absent from the Electron build with no conditional logic in the core. index.js delegates to index.electron.js after calling register.js, keeping both entrypoints in sync with zero duplication. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * test(proxy): adapt spec to OpenFeature self-registration OpenFeature is no longer hardcoded in proxy.js so the test now calls registerFeature() explicitly with the mocked modules instead of passing them through proxyquire. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * refactor(electron): extract bootstrap into shared module Both index.js and index.electron.js now require ./src/bootstrap directly rather than one depending on the other. index.js remains the only entrypoint that registers OpenFeature. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * fix(electron): use src/index.js in bootstrap to respect DD_TRACE_ENABLED bootstrap.js was requiring ./proxy directly, bypassing src/index.js which handles DD_TRACE_ENABLED=false and Jest worker environments by returning the noop proxy instead. This caused global._ddtrace to always be the full Tracer in contexts where it should be the noop. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * test(plugins): evict src/bootstrap from require cache on tracer rebuild The agent test helper clears specific module cache entries before rebuilding the tracer. src/bootstrap.js was not in the eviction list, so after global._ddtrace was deleted the cached bootstrap module still exported the stale (deleted) proxy instance instead of re-running initialization. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * chore: add CODEOWNERS entries for electron entrypoints and release workflow Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * fix(electron): fix abort.integration telemetry missing with OpenFeature Requiring openfeature/register.js from index.js previously loaded proxy.js as a side-effect (to call Tracer.registerFeature), which transitively loaded datadog-instrumentations/register.js. That module registers logAbortedIntegrations with beforeExitHandlers, but at that point the global symbol was not yet set up by bootstrap.js, so the optional-chaining silently no-oped and the handler was never registered. Introduce a feature-registry module that openfeature/register.js pushes to directly without requiring proxy.js. proxy.js and noop/proxy.js read from it at class-definition time (after the global symbol is set up by bootstrap.js). This keeps all initialization gated on !global._ddtrace. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * chore: add CODEOWNERS entries for bootstrap and feature-registry Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * ci(electron): refactor release jobs for electron package Fix broken `needs: publish-latest` reference by renaming to `publish-electron` with `needs: publish`. Drop the v5.x branch guard since the job already only runs when publish succeeds (which itself is gated to release branch pushes via setup). Co-Authored-By: Claude Sonnet 4.6 <[email protected]> * fix(electron): address Codex review findings - Pass computed npm dist-tag to electron publish so maintenance branches don't erroneously move the latest tag - Make electron publish idempotent: skip if the version is already on the registry, matching the behaviour of the regular publish step - Exclude oxc-parser from the electron package (native bindings) - Restore @DataDog/libdatadog exclusion; crashtracking is not supported in Electron — wrap its start() in a local try/catch so a missing libdatadog doesn't abort tracer initialization Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --------- Co-authored-by: Claude Sonnet 4.6 <[email protected]>
What does this PR do?
Adds the infrastructure to publish a separate
dd-trace-electronnpm package alongside the existingdd-tracepackage. Both packages ship identical source code — only thepackage.jsondependencies differ.scripts/electron-package-excludes.json— human-maintained list of optional dependencies to strip from the Electron build (native binaries not compatible with Electron)scripts/generate-electron-package.js— generatespackage.electron.jsonfrompackage.jsonminus the exclusion list; supports--checkmodescripts/release/publish-electron.js— swapspackage.json↔package.electron.jsonat publish time, runsnpm publish, then restores (mirrors the existingswap-v5-types.jspattern)publish-electron-latestandpublish-electron-devcall the publish script after their regular counterpartspackages/dd-trace/src/bootstrap.js— shared tracer initialization extracted so both entrypoints can require it without depending on each otherpackages/dd-trace/index.electron.jsand rootindex.electron.js— Electron entrypoints that omit OpenFeature registrationTracer.registerFeature/NoopProxy.registerNoop, so the Electron entrypoint cleanly excludes it by simply not requiringsrc/openfeature/register.jsMotivation
Electron apps cannot load native Node.js addons (
.nodefiles) the same way server apps can, and several ofdd-trace's optional dependencies are native binaries (profiler, AppSec WAF, IAST taint tracking, etc.). Shipping a dedicateddd-trace-electronpackage lets Electron users get tracing without fighting optional dependency install failures.Additional Notes
package.electron.jsonis gitignored — it is generated at publish time bypublish-electron.js, never committedpackage.json