Cannot find module package.json with Electron + Strapi v4

I’ve been having a similar problem. Been working on it for days. Finally found a solution.
Thought I share:

The problem seems to be (at least in my case) that strapi (and some dependecies) rely on process.cwd(). Packaging the application and starting it changed the current working directory since node has been invoked from a different source.

Usually one would fix that by changing process.cwd() to __dirname when it comes to setting paths.
But since it’s used in different node_modules that doesn’t seem to be an option.

What you can do though is setting the current working directory programmatically:

process.chdir(__dirname);

(you might wanna try...catch that, at least for debugging)

That did the trick for me!

But doing that raised another problem: Strapi wouldn’t recognice any Environmental Variables set in ./.env anymore !

Logging process.env, it was clear that not only the cwd changed but the environment as well.
So… sadly no variables from the .env file here.

I tried copiing the .env file to the same location the executable was, but that didn’t seem to work.

So I thought maybe I could read the .env file line by line and (re)set the variables programmatically.

The .env file should be easily accessible via path.join(process.cwd(), '.env') since cwd has been (re)set.

I used an example of the official node documentation found here.

FULL CODE: (main.js)

const { app, BrowserWindow, dialog } = require('electron')
const path = require("path");
const fs = require('fs');
const readline = require('readline');
const strapi = require('@strapi/strapi');

function createWindow() {

    const win = new BrowserWindow({
        maximizable: true,
        title: "Your title",
        webPreferences: {
            nodeIntegration: true
        },
        show: false
    })
   
    try {
      process.chdir(__dirname);
    }
    catch (err) {
      dialog.showErrorBox('CWD Error', err);
      app.quit();
    }

    prepareAndStart();

    async function prepareAndStart(){

      const rl = readline.createInterface({
        input: fs.createReadStream(path.join(process.cwd(), '.env')),
        crlfDelay: Infinity
      });

      for await (const line of rl) {
        let split = line.split('=');
        let key = split[0];
        let val = split[1];
        process.env[key] = val;
      }

      // console.log(process.env); // debug

      strapi({
        dir: __dirname + '/'
      }).start().then(() => {

          win.loadURL('http://localhost:1337/admin/');

          win.once('ready-to-show', () => {
            win.show()
          } );

      }).catch((err) => {
          dialog.showErrorBox('Startup Error', err);
          app.quit();
      });

    }

    win.on('closed', () => {
        app.quit();
    });

//...

}

I don’t know if this is a safe method or has any unknown consequences (regarding strapi), also it doesn’t make use of electron-is-packaged but for me it did the trick and … maybe it helps anyway.

Or it might help somebody else, landing here in an endless search for a solution ( like I was :wink: ).

EDIT:

  • platform: darwin
  • strapi@4.3.8
  • electron@19.0.16