From 6444fb5b063db02cfb9308949ae2cf2b18ccd2df Mon Sep 17 00:00:00 2001 From: "Tom (plebeius.eth)" Date: Tue, 1 Apr 2025 00:29:25 +0200 Subject: [PATCH] fix(electron): migrate Electron files to CommonJS for cross-platform compatibility fixes conflicts between ES Modules used by Vite and CommonJS modules needed by Electron in packaged applications --- electron/{log.js => log.cjs} | 9 +-- electron/{main.js => main.cjs} | 60 ++++++++++++------- .../{proxy-server.js => proxy-server.cjs} | 7 ++- electron/{start-ipfs.js => start-ipfs.cjs} | 28 +++++---- ...t-plebbit-rpc.js => start-plebbit-rpc.cjs} | 40 +++++++++---- package.json | 2 +- 6 files changed, 95 insertions(+), 51 deletions(-) rename electron/{log.js => log.cjs} (88%) rename electron/{main.js => main.cjs} (90%) rename electron/{proxy-server.js => proxy-server.cjs} (91%) rename electron/{start-ipfs.js => start-ipfs.cjs} (88%) rename electron/{start-plebbit-rpc.js => start-plebbit-rpc.cjs} (62%) diff --git a/electron/log.js b/electron/log.cjs similarity index 88% rename from electron/log.js rename to electron/log.cjs index 72404d26..7aa3258b 100755 --- a/electron/log.js +++ b/electron/log.cjs @@ -1,9 +1,10 @@ // require this file to log to file in case there's a crash -import util from 'util'; -import fs from 'fs-extra'; -import path from 'path'; -import EnvPaths from 'env-paths'; +// Convert all external module imports to CommonJS require +const util = require('util'); +const fs = require('fs-extra'); +const path = require('path'); +const EnvPaths = require('env-paths'); const envPaths = EnvPaths('plebbit', { suffix: false }); // previous version created a file instead of folder diff --git a/electron/main.js b/electron/main.cjs similarity index 90% rename from electron/main.js rename to electron/main.cjs index 18cd96c2..95573dd8 100755 --- a/electron/main.js +++ b/electron/main.cjs @@ -1,28 +1,44 @@ -import './log.js'; -import { app, BrowserWindow, Menu, MenuItem, Tray, shell, dialog, nativeTheme, ipcMain } from 'electron'; -import fs from 'fs'; -import path from 'path'; -import { fileURLToPath } from 'url'; -import EnvPaths from 'env-paths'; -import startIpfs from './start-ipfs.js'; -import './start-plebbit-rpc.js'; -import { URL } from 'node:url'; -import contextMenu from 'electron-context-menu'; -import packageJson from '../package.json' with { type: 'json' }; -import FormData from 'form-data'; -import fetch from 'node-fetch'; -import { createReadStream } from 'fs'; +// Import log.cjs +require('./log.cjs'); -const __filename = fileURLToPath(import.meta.url); -const dirname = path.dirname(__filename); +// Import Electron components using CommonJS require +const { app, BrowserWindow, Menu, MenuItem, Tray, shell, dialog, nativeTheme, ipcMain } = require('electron'); + +// Import Node.js built-ins using CommonJS +const path = require('path'); +const fs = require('fs'); +const { URL, fileURLToPath } = require('url'); +const util = require('util'); +const EnvPaths = require('env-paths'); +const FormData = require('form-data'); +const fetch = require('node-fetch'); +const contextMenu = require('electron-context-menu'); + +// Import local modules using CommonJS +require('./start-ipfs.cjs'); +require('./start-plebbit-rpc.cjs'); + +// Load package.json using CommonJS +const packageJson = require('../package.json'); + +// Set ELECTRON_IS_DEV for other modules to use +process.env.ELECTRON_IS_DEV = app.isPackaged ? '0' : '1'; + +// Since we're in CommonJS, we can't use import.meta.url +// We'll use __dirname instead which is available in CommonJS +const dirname = __dirname; let startIpfsError; +const startIpfs = require('./start-ipfs.cjs'); startIpfs.onError = (error) => { // only show error once or it spams the user const alreadyShownIpfsError = !!startIpfsError; startIpfsError = error; - if (!alreadyShownIpfsError && error.message) { - dialog.showErrorBox('IPFS warning', error.message); + if (!alreadyShownIpfsError && mainWindow && !mainWindow.isDestroyed()) { + mainWindow.webContents.send('notification', { + title: 'Error Starting IPFS', + body: error?.message || error?.toString?.() || error + }); } }; @@ -342,10 +358,10 @@ ipcMain.handle('plugin:file-uploader:pickAndUploadMedia', async (event) => { // Create form data for upload const formData = new FormData(); formData.append('reqtype', 'fileupload'); - formData.append('fileToUpload', createReadStream(filePath)); + formData.append('fileToUpload', require('fs').createReadStream(filePath)); // Upload to catbox.moe - const response = await fetch('https://catbox.moe/user/api.php', { + const response = await require('node-fetch')('https://catbox.moe/user/api.php', { method: 'POST', body: formData, }); @@ -380,7 +396,7 @@ ipcMain.handle('plugin:file-uploader:uploadMedia', async (event, fileData) => { } // Upload to catbox.moe - const response = await fetch('https://catbox.moe/user/api.php', { + const response = await require('node-fetch')('https://catbox.moe/user/api.php', { method: 'POST', body: formData, }); @@ -414,7 +430,7 @@ ipcMain.handle('plugin:file-uploader:pickMedia', async (event) => { const fileName = path.basename(filePath); // Read the file as base64 - const fileBuffer = fs.readFileSync(filePath); + const fileBuffer = require('fs').readFileSync(filePath); const base64Data = fileBuffer.toString('base64'); // Determine mime type from extension diff --git a/electron/proxy-server.js b/electron/proxy-server.cjs similarity index 91% rename from electron/proxy-server.js rename to electron/proxy-server.cjs index b6aa8d6f..9ae20b87 100755 --- a/electron/proxy-server.js +++ b/electron/proxy-server.cjs @@ -1,7 +1,8 @@ // use this proxy server to debug ipfs api requests made by electron -import http from 'http'; -import httpProxy from 'http-proxy'; +// Convert external module imports to CommonJS require() +const http = require('http'); +const httpProxy = require('http-proxy'); // start proxy const proxy = httpProxy.createProxyServer({}); @@ -49,4 +50,4 @@ const start = ({ proxyPort, targetPort } = {}) => { console.log(`proxy server listening on port ${proxyPort}`); }; -export default { start }; +module.exports = { start }; diff --git a/electron/start-ipfs.js b/electron/start-ipfs.cjs similarity index 88% rename from electron/start-ipfs.js rename to electron/start-ipfs.cjs index af6d56cb..07757975 100755 --- a/electron/start-ipfs.js +++ b/electron/start-ipfs.cjs @@ -1,13 +1,19 @@ -import isDev from 'electron-is-dev'; -import path from 'path'; -import { spawn } from 'child_process'; -import fs from 'fs-extra'; -import ps from 'node:process'; -import proxyServer from './proxy-server.js'; -import tcpPortUsed from 'tcp-port-used'; -import EnvPaths from 'env-paths'; -import { fileURLToPath } from 'url'; -const dirname = path.join(path.dirname(fileURLToPath(import.meta.url))); +const path = require('path'); +const { spawn } = require('child_process'); +const fs = require('fs-extra'); +const ps = require('node:process'); +const tcpPortUsed = require('tcp-port-used'); +const EnvPaths = require('env-paths'); + +// Import local modules using CommonJS +const proxyServer = require('./proxy-server.cjs'); + +// Instead of using electron-is-dev, use app.isPackaged +// (we already made this change in main.js) +const isDev = process.env.ELECTRON_IS_DEV === '1'; + +// Use __dirname directly instead of fileURLToPath(import.meta.url) +const dirname = __dirname; const envPaths = EnvPaths('plebbit', { suffix: false }); // use this custom function instead of spawnSync for better logging @@ -116,7 +122,7 @@ const startIpfs = async () => { }; const DefaultExport = {}; -export default DefaultExport; +module.exports = DefaultExport; const startIpfsAutoRestart = async () => { let pendingStart = false; diff --git a/electron/start-plebbit-rpc.js b/electron/start-plebbit-rpc.cjs similarity index 62% rename from electron/start-plebbit-rpc.js rename to electron/start-plebbit-rpc.cjs index f34199ef..ebf22c1d 100755 --- a/electron/start-plebbit-rpc.js +++ b/electron/start-plebbit-rpc.cjs @@ -1,12 +1,13 @@ -import tcpPortUsed from 'tcp-port-used'; -import EnvPaths from 'env-paths'; -import { randomBytes } from 'crypto'; -import fs from 'fs-extra'; -import PlebbitRpc from '@plebbit/plebbit-js/dist/node/rpc/src/index.js'; -import path from 'path'; -import { fileURLToPath } from 'url'; -import isDev from 'electron-is-dev'; -const dirname = path.join(path.dirname(fileURLToPath(import.meta.url))); +const tcpPortUsed = require('tcp-port-used'); +const EnvPaths = require('env-paths'); +const { randomBytes } = require('crypto'); +const fs = require('fs-extra'); +const path = require('path'); + +// Instead of using electron-is-dev, use process.env.ELECTRON_IS_DEV +const isDev = process.env.ELECTRON_IS_DEV === '1'; + +const dirname = __dirname; const envPaths = EnvPaths('plebbit', { suffix: false }); // PLEB, always run plebbit rpc on this port so all clients can use it @@ -39,7 +40,26 @@ const startPlebbitRpcAutoRestart = async () => { try { const started = await tcpPortUsed.check(port, '127.0.0.1'); if (!started) { - const plebbitWebSocketServer = await PlebbitRpc.PlebbitWsServer({ port, plebbitOptions: defaultPlebbitOptions, authKey: plebbitRpcAuthKey }); + // Dynamically import PlebbitRpc + const PlebbitRpcModule = await import('@plebbit/plebbit-js/dist/node/rpc/src/index.js'); + + // Try both ways of accessing the function - either directly or through default export + const PlebbitWsServer = PlebbitRpcModule.PlebbitWsServer || + (PlebbitRpcModule.default && PlebbitRpcModule.default.PlebbitWsServer); + + if (!PlebbitWsServer) { + console.error('Cannot find PlebbitWsServer in the imported module:', Object.keys(PlebbitRpcModule)); + if (PlebbitRpcModule.default) { + console.error('Default export keys:', Object.keys(PlebbitRpcModule.default)); + } + throw new Error('PlebbitWsServer function not found in the imported module'); + } + + const plebbitWebSocketServer = await PlebbitWsServer({ + port, + plebbitOptions: defaultPlebbitOptions, + authKey: plebbitRpcAuthKey + }); plebbitWebSocketServer.on('error', (e) => console.log('plebbit rpc error', e)); console.log(`plebbit rpc: listening on ws://localhost:${port} (local connections only)`); diff --git a/package.json b/package.json index a1b27702..94f17a1d 100755 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "vite-plugin-pwa": "0.21.1", "wait-on": "7.0.1" }, - "main": "electron/main.js", + "main": "electron/main.cjs", "build": { "appId": "seedit.desktop", "productName": "seedit",