I have an electron app that I'm packaging with vite using the forge template. I'm having trouble pulling in the ipcRenderer
into the React files as it crashes the app with this error:
Uncaught ReferenceError: __dirname is not defined
at node_modules/electron/index.js (electron.js?v=fee19837:36:30)
at __require (chunk-CEQRFMJQ.js?v=fee19837:11:50)
at electron.js?v=fee19837:54:16
I've tried different approaches to fix this but still no luck:
import.meta.url
:const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
vite.config.js
:export default defineConfig({
plugins: [
commonjs(),
NodeGlobalsPolyfillPlugin({
process: true,
buffer: true,
}),
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
define: {
'process.env': {},
'__dirname': '__dirname', // This is a simple way to inject __dirname
},
});
ipcRenderer
in preload.ts
:contextBridge.exposeInMainWorld('ipcRenderer', ipcRenderer)
browserify
in vite configalias: {
'@': path.resolve(__dirname, './src'),
path: 'path-browserify'
}
None of them work and I still get the same error.
Here is my tsconfig:
{
"compilerOptions": {
"target": "ESNext",
"module": "commonjs",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"noImplicitAny": true,
"sourceMap": true,
"baseUrl": ".",
"outDir": "dist",
"moduleResolution": "node",
"resolveJsonModule": true,
"jsx": "react-jsx",
"paths": {
"*": ["node_modules/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.tsx"],
}
I'm using Electron v30.0.9
When you get this error on an Electron app, it usually means you are trying to use electron
APIs on your renderer process (i.e. your React code). The variable __dirname
is a Node.js global, which require access to the Node.js APIs to be used. And for security reasons, access to Node.js from your renderer is disabled by default.
To solve this issue, you absolutely do not need to change any config, and please do not try to disable security either. Remove any calls to electron
(and Node.js APIs) from your renderer, and use the APIs only via the preload file and IPC.
Make sure to read the IPC tutorial carefully. Doing this:
contextBridge.exposeInMainWorld("ipcRenderer", ipcRenderer);
Is bad practice and not secure.
Furthermore, the only reason why you may need to use:
import { fileURLToPath } from "url";
import path from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Is when your app is ESM and you need __dirname
to configure your BrowserWindow
on the main process.