electron-forge does not work with yarn workspaces

Created on 22 May 2019  ยท  22Comments  ยท  Source: electron-userland/electron-forge

  • [x] I have read the contribution documentation for this project.
  • [x] I agree to follow the code of conduct that this project follows, as appropriate.
  • [x] I have searched the issue tracker for an issue that matches the one I want to file, without success.

Since I use Yarn workspaces electron-forge complains about missing dependencies which are installed through yarn in parent folder. My directory structure is as following:

omnicrom/
โ”œโ”€ node_modules/
โ”‚   โ”œโ”€โ”€.bin/
โ”‚   โ”œโ”€โ”€ electron-forge
โ”‚   โ”œโ”€โ”€ electron
โ”‚   โ””โ”€โ”€ ...
โ”œโ”€ .../
โ””โ”€ packages/
   โ””โ”€ app/
      โ”œโ”€โ”€ .../
      โ”œโ”€โ”€ node_modules/
      โ”‚  โ””โ”€โ”€.bin/
      โ””โ”€โ”€ src/
Console Output (with stack)
WARNING: DEBUG environment variable detected.  Progress indicators will be sent over electron-forge:lifecycle
  electron-forge:lifecycle Process Started: Checking your system +0ms
  electron-forge:lifecycle Process Succeeded: Checking your system +517ms
  electron-forge:runtime-config setting key: verbose to value: false +0ms
WARNING: DEBUG environment variable detected.  Progress indicators will be sent over electron-forge:lifecycle
  electron-forge:lifecycle Process Started: Locating Application +0ms
  electron-forge:project-resolver searching for project in: D:\projects\crm\omnicrom\packages\app +0ms
  electron-forge:project-resolver electron-forge compatible package.json found in D:\projects\crm\omnicrom\packages\app\package.json +7ms
  electron-forge:lifecycle Process Succeeded: Locating Application +10ms
  electron-forge:util Could not read package.json for moduleName=electron-prebuilt-compile [Error: ENOENT: no such file or directory, open 'D:\projects\crm\omnicrom\packages\app\node_modules\electron-prebuilt-compile\package.json'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'D:\\projects\\crm\\omnicrom\\packages\\app\\node_modules\\electron-prebuilt-compile\\package.json'
} +0ms
  electron-forge:util Could not read package.json for moduleName=electron [Error: ENOENT: no such file or directory, open 'D:\projects\crm\omnicrom\packages\app\node_modules\electron\package.json']
{
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'D:\\projects\\crm\\omnicrom\\packages\\app\\node_modules\\electron\\package.json'
} +4ms
  electron-forge:util Could not read package.json for moduleName=electron-prebuilt [Error: ENOENT: no such file or directory, open 'D:\projects\crm\omnicrom\packages\app\node_modules\electron-prebuilt\package.json'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'D:\\projects\\crm\\omnicrom\\packages\\app\\node_modules\\electron-prebuilt\\package.json'
} +2ms
  electron-forge:util getElectronVersion failed to determine Electron version: projectDir=D:\projects\crm\omnicrom\packages\app, result=null +1ms

An unhandled rejection has occurred inside Forge:
Could not determine Electron version. Make sure that 'npm install' (or 'yarn') has been run before invoking electron-forge.
Error: Could not determine Electron version. Make sure that 'npm install' (or 'yarn') has been run before invoking electron-forge.
    at D:\projects\crm\omnicrom\node_modules\electron-forge\dist\util\rebuild.js:26:13
    at Generator.next ()
    at Generator.tryCatcher (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\util.js:16:23)
    at PromiseSpawn._promiseFulfilled (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\generators.js:97:49)
    at D:\projects\crm\omnicrom\node_modules\bluebird\js\release\generators.js:201:15
    at D:\projects\crm\omnicrom\node_modules\electron-forge\dist\util\rebuild.js:63:17
    at D:\projects\crm\omnicrom\node_modules\electron-forge\dist\api\start.js:105:33
    at Generator.next ()
    at Generator.tryCatcher (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\util.js:16:23)
    at PromiseSpawn._promiseFulfilled (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\generators.js:97:49)
    at Promise._settlePromise (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\promise.js:574:26)
    at Promise._settlePromise0 (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\promise.js:614:10)
    at Promise._settlePromises (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\promise.js:694:18)
    at _drainQueueStep (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\async.js:138:12)
    at _drainQueue (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\async.js:131:9)
    at Async._drainQueues (D:\projects\crm\omnicrom\node_modules\bluebird\js\release\async.js:147:5)

What command line arguments are you passing?

none.

What does your config.forge data in package.json look like?


config.forge settings

"config": {
"forge": {
"make_targets": {
"win32": [
"squirrel"
],
"darwin": [
"zip"
],
"linux": [
"deb",
"rpm"
]
},
"electronPackagerConfig": {
"packageManager": "yarn"
},
"electronWinstallerConfig": {
"name": "omnicrom"
},
"electronInstallerDebian": {},
"electronInstallerRedhat": {},
"github_repository": {
"owner": "",
"name": ""
},
"windowsStoreConfig": {
"packageName": "",
"name": "omnicrom"
}
}
}

To recreate this issue simply create a new project with electron-forge and then wrap it into a yarn workspace. to do this you refer to this guide: https://yarnpkg.com/en/docs/workspaces
You could also recreate my directory structure and use the following root package.json contents:

{
  "name": "myrootpackage",
  "version": "1.0.0",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

Bug

Most helpful comment

Had the same problem. Fixed this by moving electron package from ./node_modules to ./packages/app/node_modules using yarn workspaces.noihoist

All 22 comments

Can you try Electron Forge v6? (That version is more likely to get a fix for this.)

Yeah, that's probably not going to work either. Yarn workspaces function differently than lerna (and bolt, which Forge uses) in that there's only one node_modules folder instead of one per package. I think what needs to happen is that if there's no node_modules folder in the app directory and the package manager that Forge detects is yarn, it needs to search for a yarn.lock and use that directory to find the Electron module.

Can you try Electron Forge v6? (That version is more likely to get a fix for this.)

This doesn't work either as you pointed out already.

Yarn workspaces function differently than lerna

I don't know about bolt, but lerna supports yarn workspaces so that could create the same issue once one tries to enable them.

I think what needs to happen is that if there's no node_modules folder in the app directory and the package manager that Forge detects is yarn, it needs to search for a yarn.lock and use that directory to find the Electron module.

yarn.lock is generated in each yarn workspace folder.
it woul be mroe reliable to test if node_modules is empty besides the .bin folder and walk the directories up until it finds a folder with package.json which has private:true and contains the node_modules folder with all dependencies

lerna supports yarn workspaces so that could create the same issue once one tries to enable them.

I ran lerna init / lerna create to get the default behavior. It doesn't really matter here if it "supports" yarn workspaces if we're going to be adding support for it anyway.

yarn.lock is generated in each yarn workspace folder.

That's not what I'm seeing in my tests. yarn.lock only exists in the top-level of the monorepo.

Yarn: 1.16.0, Linux

That's not what I'm seeing in my tests. yarn.lock only exists in the top-level of the monorepo.

Alright that was my mistake, shame on me. I left the lock file after migration to a monorepo.

we're going to be adding support for it anyway.

That's great to hear! Let me know if I can help in these tasks.

So I have a fix for this particular issue, but I can guarantee that this will not work out-of-the-box once you get to the package phase. I've made several comments on this topic in https://github.com/electron-userland/electron-packager/issues/774. TL;DR: you'll need to add a Packager afterCopy hook to run yarn install --production in the app directory.

Had the same problem. Fixed this by moving electron package from ./node_modules to ./packages/app/node_modules using yarn workspaces.noihoist

Thanks for the suggestion!
I will try this when I get back to my project.

symlinking the node_modules folder worked for me
ln -s ../node_modules electron_app/node_modules

Not sure about the build and everything through

This was fixed in Electron Forge v6.

Mmmh, I am using 6.0.0-beta.50

It bugged with my simple symlink in the end, I used @alxmiron 's solution with noihoist. It is working well

"workspaces": {
    "packages": [
      "app",
      "server"
    ],
    "nohoist": [
      "**/electron**"
    ]
  },

Is this yarn 1 or 2?

yarn --version                           
1.22.0

I am using the typescript template https://www.electronforge.io/templates/typescript-template. I think it is webpack that is causing problem. I am having problems with other modules when loaded by webpack.

I can make a reproduction repository if it is useful for you

I can make a reproduction repository if it is useful for you

It would be helpful to have a minimal testcase, yes.

I was using typescript-webpack template, my bad.

Here is a reproduction repository:
https://github.com/abumalick/electron-forge-workspace-bug

Feel free to tell me if you need any other information

I ended up adding

"nohoist": [
      "**"
    ]

I tried to add express package and I get a lot of problems with the workspaces

@abumalick has correct testcase - I also get an error "electron package not found" there, unless I add the following props to my-new-app/package.json:

"private": true,
"workspaces": {
  "nohoist": [
    "electron",
    "electron/**",
    "electron-squirrel-startup",
    "electron-squirrel-startup/**",
    "@electron-forge",
    "@electron-forge/**"
  ]
},

NOTE: "private": true is important

Using "nohoist" is more of a workaround than a real solution. ๐Ÿ™

Yeah using nohoist isn't viable in monorepos that contain more than one app.

what ends up happening is the install time ballons, the diskspace taken ballons.

The only long term viable solution is to change whatever logic it is that makes assumptions about where the electron package is.

i mean... just use the normal node resolver.

This is a huge problem in react-native too.

Thanks for the hints about nohoist ๐Ÿ™‚

In the latest version of Yarn Berry (2.4.1?), nohoist has been deprecated in favor of nmHoistingLimits. See Replace nohoist by nmHoistingLimits for more details.

In our case, this meant removing nohoist and putting the following line into our .yarnrc.yml file:

nmHoistingLimits: workspaces

Note that that line goes in .yarnrc.yml, not package.json (although there's supposed to be a way to specify nmHoistingLimits via package.json, too).

After this, everything worked ๐Ÿ™‚

Was this page helpful?
0 / 5 - 0 ratings