Electron forge make with yarn workspaces

379 views Asked by At

I'm using yarn workspaces to separate code for my electron app. I have 3 workspaces:

  1. server - runs a serialport server in the main thread
  2. gui - browser code
  3. app - defines the configuration for the electron app

The app workspace imports code from the gui and server workspaces. This is causing me all sorts of grief when trying to package my code.

Initially, the app was packaging but was missing all my node_modules (such as complaining it cant find "electron-squirrel-startup"). I read that I can just disable hoisting so that the node_modules folder will include all the modules it needs.

    "nohoist": ["**"]

Since my app imports between workspaces, yarn creates a symbolic link to those projects. It appears electron builder does not like this and does not follow the symbolic link, instead trys to just copy the symbolic link itself:

An unhandled rejection has occurred inside Forge:
Error: EPERM: operation not permitted, symlink 'C:\Users\joeja\projects\roguegeo\packages\server' -> 'C:\Users\joeja\AppData\Local\Temp\electron-packager\win32-x64\RogueGeo App-win32-x64-TeyVhU\resources\app\node_modules\@rg\server'

I've been at this all day, switched from NPM workspaces to yarn. Its just one issue after another and I'm at my wits end on this.

Running my app in development works fine, its just trying to package it thats causing me issues.

I read somewhere that I can add a afterCopy hook to run "yarn install --production", but I havent been able to get that to work. Nor do I think it would fix my current issue, as that would also just use a symbolic link for local workspaces?

How can I use yarn workspaces and build an electron forge app?

1

There are 1 answers

0
Stephen Handley On

Still seeing some other errors on my end, but was able to get around the symlink error and get the package process to output by doing the following in forge.config.ts:

import { promisify } from "util";
import ChildProcess from "child_process";

const exec = promisify(ChildProcess.exec);

function copy({ src, dest }: { src: string, dest: string }) {
  return exec(`cp -r ${src} ${dest}`);
}

const config: ForgeConfig = {
  hooks: {
    packageAfterExtract: async (_config, buildPath) => {
      await copy({
        src: "../common",
        dest: `${buildPath}/Electron.app/Contents/Resources`
      })
    },
    //...
  }
};