I followed the Electron typescript quick-start code structure. Basically I cloned the repo. It worked fine until I wanted to split my code in multiple .ts files, and import them in the renderer script.
Then I get the Uncaught ReferenceError: exports is not defined. Because of this line on top of the renderer.ts:
import { stuff } from "./otherfile.ts";
After digging for more info, it seems that the reason is the "module": "commonjs" from tsconfig... But if I change that to esnext then Electron will not load the preload script anymore!
Has anyone actually managed to get Electron and typescript fully working? I mean, with being able to use import across multiple files and stuff like that?
file structure:
/dist
/dist/main.js
/dist/preload.js
/dist/renderer.js
/dist/stuff.js
/src
/src/main.ts
/src/preload.ts
/src/renderer.ts
/src/stuff.ts
/index.html
/src/main.ts:
import { ipcMain } from "electron"; // imports work fine in main
...
ipcMain.on(...
/src/preload.ts:
import { contextBridge, ipcRenderer} from "electron"; // imports work fine in preload
contextBridge.exposeInMainWorld("my-api", { ....
/src/renderer.ts
import stuff from "./stuff.ts"; // import fails in renderer (exports is not defined error)
/src/stuff.ts
const stuff = { ... };
export default stuff;
/index.html
<html>
...
<script src="./dist/renderer.js"></script>
</html>
ts.config:
If I manually add var exports = {} in renderer.js after ts compiles the file, then I get a different error "require is not defined"
Sorry, it's not possible the way that boilerplate is configured.
To use import/require inside of the renderer process, you must either lower the default security settings in the latest versions of Electron OR use a transpiler so that the final code the renderer executes will not include import/require.
And in the electron-quick-start-typescript project you'll find this file that confirms that as the issue.
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// No Node.js APIs are available in this process unless
// nodeIntegration is set to true in webPreferences.
// Use preload.js to selectively enable features
// needed in the renderer process.
Node.js APIs include import and require.
Furthermore, when you do access require, if sandbox is enabled then you're actually getting a polyfilled version, not the underlying require - see these notes about preload script sandboxing
Your only other option short of changing boilerplates is to access anything you need via the preload script like window.api.yourFunction instead.
You may wish to use a boilerplate which includes transpilation via Webpack to enable you to use import inside of your renderer process.
I believe both of these boilerplates accommodate it (and I can probably advise you somewhat if you get stuck with one of them)
PS - If you're writing code intended for distribution to others, please do not enable nodeIntegration as it breaks the security model of Electron!
PPS - You can also try "module": "ES2020", which is what we use - but it will not fix your issue of not being able to import/require within the renderer process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With