Skip to content

feat(core-utils): add subpath exports for individual modules#4315

Open
erickzhao wants to merge 2 commits into
nextfrom
claude/core-utils-subpath-exports-jzoms3
Open

feat(core-utils): add subpath exports for individual modules#4315
erickzhao wants to merge 2 commits into
nextfrom
claude/core-utils-subpath-exports-jzoms3

Conversation

@erickzhao

Copy link
Copy Markdown
Member
  • I have read the contribution documentation for this project.
  • I agree to follow the code of conduct that this project follows, as appropriate.
  • The changes are appropriately documented (if applicable).
  • The changes have sufficient test coverage (if applicable).
  • The testsuite passes successfully on my local machine (if applicable).

Summarize your changes:

@electron-forge/core-utils currently declares "exports": "./dist/index.js", so the only way to consume it is through the barrel — which evaluates every module and their transitive dependencies (semver, debug, graceful-fs, @malept/cross-spawn-promise, ~40ms per fresh Node process) even when a consumer only needs a tiny helper like pathExists or resolveWorkingDir.

Commit 1 replaces the single-string exports with an explicit exports map: "." still points at the barrel (fully backwards compatible), and each public source module gains its own subpath (/author-name, /electron-version, /fs, /install-dependencies, /package-manager, /rebuild, /resolve-working-dir). The list is deliberately explicit rather than a "./*" wildcard so find-up and remote-rebuild stay internal (ERR_PACKAGE_PATH_NOT_EXPORTED) and new modules only become public API by being listed. Types resolve from the sibling .d.ts files under node16 module resolution; the typings field is kept for the root entry. The dist layout is unchanged, so rebuild.ts's cp.fork of remote-rebuild.js is unaffected, and @electron/rebuild still only appears as a value import in the compiled remote-rebuild.js.

Commit 2 migrates light consumers (makers, templates, publisher-snapcraft, plugin-vite, plugin-webpack, create-electron-app, CLI entry points) to subpath imports. api/core keeps importing the barrel since it uses the heavy modules anyway. Spec files that vi.mock'd the barrel now mock the specific submodule their subject imports, since vitest intercepts by module specifier.

This also unblocks #4210: its proposed restart.ts event-emitter module can ship as a leaf subpath that Vite config files load in build worker subprocesses without pulling in the whole barrel per worker.

Verified locally: yarn build (tsgo + tools/test-dist) passes, the full fast vitest project passes (408 tests), every listed subpath resolves at runtime from a consumer package, and the root barrel import is unchanged.


Generated by Claude Code

claude added 2 commits July 9, 2026 23:21
Replace the single-string exports field with an explicit exports map.
The root "." entry keeps pointing at the barrel for backwards
compatibility; each public source module gains its own subpath so
consumers can import just the helpers they need without evaluating the
whole barrel (and its transitive semver/debug/graceful-fs/cross-spawn
imports) at load time.

The list is deliberately explicit rather than a "./*" wildcard:
find-up and remote-rebuild are internal and stay unexported, and new
modules become public API only by being added here. Types resolve from
the sibling .d.ts files under node16 module resolution, so no types
conditions are needed; the typings field stays for the root entry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dfTZ7AecGYkxBjQ8DGT54
Migrate consumers that only use light helpers (fs, author-name,
package-manager, install-dependencies, resolve-working-dir) off the
core-utils barrel and onto the new subpath exports, so loading a small
helper no longer evaluates every core-utils module and its transitive
dependencies.

api/core keeps importing the barrel: it uses the heavy modules
(rebuild, electron-version) anyway, so splitting its imports would not
change what gets loaded.

Spec files that vi.mock'd the core-utils barrel now mock the specific
submodule their subject imports, since vitest intercepts by module
specifier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dfTZ7AecGYkxBjQ8DGT54
@erickzhao erickzhao requested a review from a team as a code owner July 9, 2026 23:28
@github-actions github-actions Bot added the next label Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants