Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not work with NPM workspaces #7103

Closed
ghost opened this issue Aug 31, 2022 · 24 comments · Fixed by #8715
Closed

Does not work with NPM workspaces #7103

ghost opened this issue Aug 31, 2022 · 24 comments · Fixed by #8715
Assignees

Comments

@ghost
Copy link

ghost commented Aug 31, 2022

  • Electron-Builder Version: 23.3.3
  • Node Version: v18.3.0
  • Electron Version: 20.1.0

  • Electron Type (current, beta, nightly): current

  • Target: win32 x64

electron builder does not work in npm workspace
it deletes app-builder-bin during "installing production dependencies" and then throws error:

• packaging       platform=win32 arch=x64 electron=20.1.0 appOutDir=dist\win-unpacked
The system cannot find the path specified.
  ⨯ spawn C:\Users\user\dev\test-workspace\node_modules\app-builder-bin\win\x64\app-builder.exe ENOENT

also it deletes more packages from node_modules, so next run throws

'electron-builder' is not recognized as an internal or external command

Reproduction:
npm run build -w a in test-workspace.zip

@paulantoine2
Copy link

paulantoine2 commented Sep 30, 2022

For me, i just get stuck at installing production dependencies but the behavior is the same as above.

However, it's working with electron-builder version 22 !

@radoslavkarlik
Copy link

I am having the same or similar problem and found it started happening with npm 8.5.0 (node 16.14.1) because when I downgrade to 8.3.1 (that came with node 16.14.1) while keeping a higher node version, it works. Npm changelog says something about workspaces but I am not sure if its related.

@Hinaser
Copy link

Hinaser commented Jan 17, 2023

Try to add build option below in your package.json which has main entry for electron app:

{
  "main": "build/electron/main.js",
  ...,
  "build": {
    ...,
    "npmRebuild": false
  }
}

@joshtynjala
Copy link

Confirmed that setting npmRebuild to false works for my project, but I suspect it is not a universal workaround.

It looks like this code is where the installing production dependencies happens:

function installDependencies(appDir: string, options: RebuildOptions): Promise<any> {
const platform = options.platform || process.platform
const arch = options.arch || process.arch
const additionalArgs = options.additionalArgs
log.info({ platform, arch, appDir }, `installing production dependencies`)
let execPath = process.env.npm_execpath || process.env.NPM_CLI_JS
const execArgs = ["install"]
const isYarnBerry = checkYarnBerry()
if (!isYarnBerry) {
if (process.env.NPM_NO_BIN_LINKS === "true") {
execArgs.push("--no-bin-links")
}
execArgs.push("--production")
}
if (!isRunningYarn(execPath)) {
execArgs.push("--prefer-offline")
}
if (execPath == null) {
execPath = getPackageToolPath()
} else if (!isYarnBerry) {
execArgs.unshift(execPath)
execPath = process.env.npm_node_execpath || process.env.NODE_EXE || "node"
}
if (additionalArgs != null) {
execArgs.push(...additionalArgs)
}
return spawn(execPath, execArgs, {
cwd: appDir,
env: getGypEnv(options.frameworkInfo, platform, arch, options.buildFromSource === true),
})
}

It seems to be running node install --production. I'm guessing that this command is deleting dependencies needed by electron-builder, including the mentioned app-builder-bin.

@nanamicat
Copy link

nanamicat commented Feb 21, 2023

Setting npmRebuild to false works for me, but I worry disable rebuild may break native dependencies;

Another problem is when depend on a non-exact electron version like ^23.1.0, it can't find installed electron package and will throw.

It should use require.resolve() or require.resolve.paths() to search packages and not assume in {pwd}/node_modules

@jkroepke
Copy link
Contributor

jkroepke commented Jun 10, 2023

I look into the code and figure out that create an empty node_module directory on the specific project where electron-builds solve my issue here. npm rebuild works fine in my case.

See https://github.com/MuhammedKalkan/OpenLens/blob/c4b099462f9e4cdf405d02993a40e5563278bfd1/.github/workflows/main.yml#L47-L49 for a living example.

electron-builder checks, if there is an node_modules dir on the current dir

for (const fileOrDir of ["node_modules", ".pnp.js"]) {
if (await pathExists(path.join(appDir, fileOrDir))) {
isDependenciesInstalled = true
break
}
}

and if not, it just runs npm install again which may not work in npm workspace scenarios.


An alternative solution is npmRebuild=false and postinstall: "electron-rebuild". This is, what this project is using, however it will not work in cross-compile scenarios.

@github-actions
Copy link
Contributor

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.

@github-actions github-actions bot added the Stale label Aug 10, 2023
@jkroepke
Copy link
Contributor

still an issue

@github-actions github-actions bot removed the Stale label Aug 11, 2023
@BrunoSoaresEngineering
Copy link

Yes, still an issue: having to create an empty 'node_modules' folder on every workspace and having to fix the version of Electron on package.json is very annoying...

@mmaietta
Copy link
Collaborator

Very intereesting.

Is there a proper way to detect if we're in a npm workspace and can discern that dependencies are already installed?

@vincesp
Copy link

vincesp commented Oct 2, 2023

Very intereesting.

Is there a proper way to detect if we're in a npm workspace and can discern that dependencies are already installed?

getElectronVersionFromInstalled(projectDir) is trying to implement its own package resolution algorithm which probably is not a good idea. A better solution could be:

cd ${projectDir}
node -p "require.resolve('electron')"

(…or node -p "import.meta.resolve('electron')" if project is a module.)

@mmaietta
Copy link
Collaborator

mmaietta commented Oct 2, 2023

I'm wondering if I could just copy this implementation.
https://github.com/electron/rebuild/blob/main/src/electron-locator.ts

@vincesp
Copy link

vincesp commented Oct 5, 2023

It is important that the resolve() takes place in the context of the electron project, not in the context of the electron-builder itself.

Copy link
Contributor

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.

@github-actions github-actions bot added the Stale label Dec 22, 2023
@rotu
Copy link
Contributor

rotu commented Dec 22, 2023

not stale

@github-actions github-actions bot removed the Stale label Dec 23, 2023
Copy link
Contributor

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.

@github-actions github-actions bot added the Stale label Feb 21, 2024
@rotu
Copy link
Contributor

rotu commented Feb 21, 2024

still not stale

@github-actions github-actions bot removed the Stale label Feb 22, 2024
Copy link
Contributor

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.

@github-actions github-actions bot added the Stale label Apr 28, 2024
@rotu
Copy link
Contributor

rotu commented Apr 28, 2024

still not stale

@github-actions github-actions bot removed the Stale label Apr 29, 2024
@vincesp
Copy link

vincesp commented Apr 29, 2024

still not stale

1 similar comment
@codebymaribel
Copy link

still not stale

@scottcorgan
Copy link

Yes, still very much a difficult issue

@vincesp
Copy link

vincesp commented Jul 30, 2024

Implementation of getElectronVersionFromInstalled() still needs to be fixed.

@scriptcoded
Copy link

scriptcoded commented Aug 19, 2024

For anyone looking for a workaround, here's the summary.

  1. You need to pin your version of electron (ie. not use a range like ^ or ~). Only this package has to be pinned. Example:
    "dependencies": {
      "electron": "31.4.0",
      "electron-builder": "^24.13.3" // other related packages can still use ranges
    }
  2. You need to have an empty node_modules folder in your package directory, otherwise NPM hangs during install (I have no clue why). An easy way of making sure this is always the case is to use a preinstall script in your package.json for the package which uses electron:
    {
      "scripts": {
        "preinstall": "mkdir -p node_modules"
      }
    }
    And if you need this to work cross-platform (looking at you Windows) you could use something like shx:
    {
      "scripts": {
        "preinstall": "shx mkdir -p node_modules"
      }
    }

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 a pull request may close this issue.