feat: universal target support for electron externals#21184
Conversation
Mirror NodeTargetPlugin's universal-target behavior in ElectronTargetPlugin: accept a default external type and fall back to node-commonjs for require, so electron built-ins use module-import with module output.
Replace source-string assertions with end-to-end execution: run both the module-import (module output) and node-commonjs (require) bundles and assert the externalized electron built-ins resolve to real stub modules at runtime.
Gate the electron externals type on output.environment.module so that electron versions without ESM support fall back to node-commonjs even when output.module is set. Add a configCase covering an electron version without ESM support.
…utput ESM support was added in electron 28, so set the electron target's 'module' capability to v(28) instead of v(11). Warn when 'output.module' is used with an electron version that predates ESM, falling back to node-commonjs externals.
🦋 Changeset detectedLatest commit: 8b2bc26 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
This PR is packaged and the instant preview is available (70a54da). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@70a54da
yarn add -D webpack@https://pkg.pr.new/webpack@70a54da
pnpm add -D webpack@https://pkg.pr.new/webpack@70a54da |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #21184 +/- ##
=======================================
Coverage 92.68% 92.69%
=======================================
Files 587 588 +1
Lines 64011 64024 +13
Branches 17754 17760 +6
=======================================
+ Hits 59328 59345 +17
+ Misses 4683 4679 -4
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:
|
…equire branch The electron-main-no-esm bundle imports 'createRequire' from 'module', which older Node versions cannot link in the vm ESM runner, so gate it behind supportsRequireInModule. Require the electron built-ins in the node-commonjs config so the require (commonjs) externals branch is executed.
Merging this PR will degrade performance by 35.27%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | benchmark "asset-modules-inline", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
317.8 KB | 1,299.2 KB | -75.54% |
| ❌ | Memory | benchmark "side-effects-reexport", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
758.5 KB | 1,197.8 KB | -36.68% |
| ❌ | Memory | benchmark "many-modules-esm", scenario '{"name":"mode-production","mode":"production"}' |
8.1 MB | 11.1 MB | -26.39% |
| ❌ | Memory | benchmark "asset-modules-bytes", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
247.8 KB | 321.5 KB | -22.93% |
| ⚡ | Memory | benchmark "many-modules-commonjs", scenario '{"name":"mode-production","mode":"production"}' |
9.6 MB | 7.5 MB | +29.26% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing claude/electron-externals-universal-target-l2jnjo (8b2bc26) with main (b83041a)
Summary
ElectronTargetPluginalways externalized electron built-in modules asnode-commonjs, so ESM (output.module) builds gotrequire(...)instead ofimport. This mirrorsNodeTargetPlugin's universal-target behavior: built-ins are externalized asmodule-importwhen the output is ESM and the targeted electron version supports ESM (added in electron 28), and fall back tonode-commonjsforrequireand for older electron versions. The electronmoduletarget capability was also corrected fromv(11)tov(28), and a warning is emitted whenoutput.moduletargets an electron version without ESM support.What kind of change does this PR introduce?
feat (plus a small fix to the electron target capability data).
Did you add tests for your changes?
Yes —
test/configCases/target/electron-main-moduleexecutes both themodule-import(module output) andnode-commonjs(require) bundles and asserts the externalized electron built-ins resolve to stub modules at runtime;test/configCases/target/electron-main-no-esmcovers an electron version without ESM (falls back tonode-commonjsand emits the warning).Does this PR introduce a breaking change?
No. Electron 11–27 with
output.modulepreviously emitted ESMimports for built-ins those versions cannot import; it now usesnode-commonjsand warns, which is strictly more correct.If relevant, what needs to be documented once your changes are merged or what have you already documented?
n/a
Use of AI
AI was used: implemented and tested with Claude Code (Anthropic), then reviewed by the author. Electron ESM version facts were verified against the official Electron docs (ESM support added in 28.0.0).
Generated by Claude Code