feat(core): add sanitizePackageJson hook#4314
Closed
claude[bot] wants to merge 2 commits into
Closed
Conversation
Packaged apps currently ship the project's full package.json with only config.forge removed. Forge now sanitizes the copied package.json by default, stripping dev-only fields (devDependencies, scripts, workspace and package manager settings, tooling config) while keeping runtime fields. Providing a sanitizePackageJson hook from the Forge config or a plugin replaces the default entirely; the default is exported as defaultSanitizePackageJson so custom hooks can extend it. The sanitize step runs in the packager afterCopy phase, after all packageAfterCopy hooks and before prune. Stripping devDependencies before prune is safe: the prune walker only uses root devDependencies to mark dev-only modules for removal, and unwalked modules are pruned anyway. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HEPrpBevFu6CmqKzeNHmoA
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HEPrpBevFu6CmqKzeNHmoA
Contributor
Author
|
Superseded by the packager-level implementation in electron/packager#1931 — Samuel clarified the hook should live in packager so all consumers benefit. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Samuel Attard · Slack thread
Summarize your changes:
Adds a
sanitizePackageJsonhook with a built-in default that strips dev-only fields from the packaged app's package.json.Before / After
Before: packaged apps ship the developer's entire package.json —
devDependencies,scripts, workspace/package-manager settings, tooling config, and so on — with onlyconfig.forgeremoved. This is the complaint in electron/packager#1184.After: Forge strips dev-only fields by default when writing the copied package.json into the build. A new
sanitizePackageJsonmutating hook (same shape asreadPackageJson) lets users and plugins customize this; providing the hook from the Forge config or any plugin replaces the default entirely. The default implementation is exported from@electron-forge/coreasdefaultSanitizePackageJson, so a custom hook can call it to do "default plus extra" instead.Default-stripped fields:
devDependencies,scripts,workspaces,packageManager,resolutions,overrides,pnpm,private,publishConfig,devEngines,jest,eslintConfig,prettier,browserslist,lint-staged,nano-staged,husky,commitlint,mocha,ava,nyc,c8,tap,xo,standard, plusconfig.forge(configis dropped entirely if empty afterwards, preserving today's behavior). Runtime fields likemain,name,productName,version,type,exports/imports,dependencies,optionalDependencies, andpeerDependenciesare kept.How
packages/utils/types/src/index.ts: addssanitizePackageJsontoForgeMutatingHookSignatures(flows intoForgeHookMap/ForgeMultiHookMap), and addshasHook(hookName)toIForgePluginInterfaceso core can tell whether any plugin registers a given hook.packages/api/core/src/util/sanitize-package-json.ts(new):defaultSanitizePackageJson(the exported default) andsanitizeCopiedPackageJson, which reads the copied package.json, runs user/pluginsanitizePackageJsonhooks viarunMutatingHookwhen any exist (config hook first, then plugin hooks, threading the result) or the default otherwise, and writes the result back with the samewriteJson(..., { spaces: 2 })as before.packages/api/core/src/api/package.ts: the built-inafterCopystep that previously only deletedconfig.forgenow delegates tosanitizeCopiedPackageJson. It keeps its position in the serialafterCopychain: after thepackageAfterCopyForge hooks (so it observes the final package.json that the webpack/vite plugins write into the build — their ownconfig.forgedeletion is untouched and now superseded) and beforepackagerConfig.afterCopyhooks and prune.@electron/packager's prune, which walks the copied app's package.json via galactus/flora-colossus.dependenciesandoptionalDependenciesare deliberately not stripped (the walker needs them). StrippingdevDependenciesis safe: flora-colossus defaults a missingdevDependenciesto{}and only uses root devDependencies to walk modules it then marks as dev (pruned); modules not walked at all are pruned anyway, and modules also reachable via a prod chain are kept either way (depTypeGreaterupgrades dev to prod). So the pruned module set is unchanged.packages/api/core/spec/fast/util/sanitize-package-json.spec.tscovers the default denylist andconfig.forgehandling, user-hook and plugin-hook replacement of the default (default-stripped fields survive), and that the hook's return value is what lands on disk. The existing slow e2e spec now also assertsdevDependencies/scriptsare absent from the packaged app.Note: the slow e2e package spec could not run in the local sandbox (Electron binary download is blocked by the environment's proxy) and relies on CI; the full fast suite, lint, build, and knip pass locally.
Generated by Claude Code