jsonnull/electron-trpc

ESM Preload Script fails to import `electron-trpc/main`

Closed this issue · 0 comments

Problem

If we write

import { exposeElectronTRPC } from 'electron-trpc/main';

in ESM Preload Script preload.mjs, following error occurs in renderer process:

file:/my/workspace/try-electron-trpc/node_modules/electron-trpc/dist/main.mjs:11
import { ipcMain as ee, contextBridge as re, ipcRenderer as U } from "electron";
         ^^^^^^^
SyntaxError: The requested module 'electron' does not provide an export named 'ipcMain'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:132:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:214:5)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async node:electron/js2c/renderer_init:2:33310
    at async loadESM (node:internal/process/esm_loader:28:7)
(anonymous) @ VM111 renderer_init:2

(NB: Here sandboxing has to be disabled, since sandboxed preload scripts cannot use ESM imports.)

This means we cannot expose IPC following README

Workaround

A workaround is to copy/paste the implementation of exposeElectronTRPC() like this:

// preload.mjs
const ELECTRON_TRPC_CHANNEL = 'electron-trpc';
const electronTRPC = {
  sendMessage: (operation) =>
    ipcRenderer.send(ELECTRON_TRPC_CHANNEL, operation),
  onMessage: (callback) =>
    ipcRenderer.on(ELECTRON_TRPC_CHANNEL, (_event, args) => callback(args)),
};
contextBridge.exposeInMainWorld('electronTRPC', electronTRPC);

(This workaround is almost same as the one described in #116 (comment).)
This works for me, but a downside is I have to care ELECTRON_TRPC_CHANNEL constant would be unchanged in future updates.

Possible solution

How about removing exposeElectronTRPC() from main.mjs and including it in another bundle like preload.mjs?
Then we can write in preload script like import { exposeElectronTRPC } from 'electron-trpc/preload'; without unnecessary reference to ipcMain.
Though I have not tried this yet, I guess this could also solve #180, where an error occurs in main process because main.mjs imports unnecessary contextBridge that comes from exposeElectronTRPC().