Skip to content

Isolate the Electron install from the application's npm config - #150

Open
Ikromjon1998 wants to merge 1 commit into
NativePHP:mainfrom
Ikromjon1998:fix/electron-npmrc-install-scripts
Open

Isolate the Electron install from the application's npm config#150
Ikromjon1998 wants to merge 1 commit into
NativePHP:mainfrom
Ikromjon1998:fix/electron-npmrc-install-scripts

Conversation

@Ikromjon1998

Copy link
Copy Markdown

Closes #145. Takes option 3 as suggested, with the safeguard your comment asked for.

The change

One new file, resources/electron/.npmrc:

ignore-scripts=false
allow-scripts[]=electron
allow-scripts[]=esbuild

A directory-local .npmrc takes precedence over ancestors, so the install here no longer inherits the host application's policy.

On reopening the door

You were right to flag this, so the change deliberately does not set ignore-scripts=false alone.

allow-scripts (npm 11) restricts install scripts to named packages. Only two in this tree need one:

Package Script Why
electron postinstall Downloads the runtime — the actual bug
esbuild postinstall Fetches its platform binary

electron-chromedriver and electron-winstaller also carry install scripts and are deliberately left out: the first is only for driver-based testing, and the second matters to Squirrel targets while electron-builder.mjs builds nsis. They stay blocked, and npm reports them as skipped rather than failing the install.

The net effect is narrower than what this directory had before Laravel began shipping an .npmrc, when every package here could run install-time code. A dependency that starts shipping an install script later is refused by default rather than silently trusted.

I did not use strict-allow-scripts, because it makes any unapproved script a hard install failure — with electron-chromedriver present that fails the install outright.

Verified

Reproduced the original bug and the fix with a parent .npmrc containing ignore-scripts=true, matching the Laravel 12 skeleton:

  • Without this fileelectron's postinstall is skipped, node_modules/electron/dist has no runtime and path.txt is absent, install exits 0.
  • With this file — the postinstall runs; electron-chromedriver remains skipped with a warning and the install still succeeds.

One caveat, and a separate problem

allow-scripts requires npm 11. On older npm the key is ignored and only ignore-scripts applies, i.e. the pre-Laravel-12 behaviour — a graceful degradation rather than a break.

Worth flagging separately: with this fix in place the postinstall runs, but on a clean install the runtime still does not land, because extract-zip resolves yauzl 2.10.0, which stops after the first entry of the Electron archive while install.js exits 0 — leaving a dist/ holding only LICENSES.chromium.html. It reproduces outside NativePHP with nothing but npm i electron, and overrides: { "yauzl": "^3.4.0" } fixes it. I have left that out of this PR since it would mean regenerating resources/electron/package-lock.json. Happy to open it as its own issue or PR — just say which you prefer.

npm reads .npmrc files upward from the working directory, so the host
application's configuration governs the install performed in
resources/electron. Laravel's default skeleton has shipped
ignore-scripts=true since Laravel 12, which skips Electron's postinstall
and leaves node_modules/electron without a runtime binary. The install
exits 0 and creates the directory, so nothing surfaces the problem until
the app is launched and fails on a missing Electron.app.

A directory-local .npmrc takes precedence over ancestors, which keeps
this decision with NativePHP rather than inheriting whatever the
application sets.

Install scripts are not re-enabled wholesale. Laravel adopted
ignore-scripts to reduce exposure to install-time code execution, and
that protection is kept here by allowing only the two packages in this
tree that need a script — electron, which downloads the runtime, and
esbuild, which fetches its platform binary. Everything else in the
dependency graph remains unable to run code at install time, including
packages added to it later. electron-chromedriver and
electron-winstaller are deliberately excluded: the first is only used
for driver-based testing, and the second matters to Squirrel targets
while this config builds nsis.

allow-scripts requires npm 11. On older npm the key is ignored and only
ignore-scripts applies, which is the behaviour this directory had before
Laravel began shipping an .npmrc.

Closes NativePHP#145

@SRWieZ SRWieZ left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, good idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Laravel 12's default .npmrc silently prevents the Electron binary from downloading

3 participants