TL;DR
I believe your error is caused by confusing CommonJS (CJS) and ES modules (ESM). It sounds like you are using CJS exports with ESM imports which is not compatible. The next section is a working Election example and after that is a comparison of CJS and ESM exports (export) and require (import).
Working Solution
Your OP did not include any code so this is my best guess at what the issue was and provides a working solution. Start by setting up the code:
# Clone this repository
git clone https://github.com/electron/electron-quick-start-typescript
# Go into the repository
cd electron-quick-start-typescript
# Install dependencies
npm install
Next create the following file:
// src/otherfile.ts
export const stuff = {
fullOf: 'stuff'
}
export function shareLocation(loc: string): void {
console.log(`I was imported by: ${loc}`);
}
Now open the src/main.ts
file and make the following changes:
// Add import to top of file.
import {stuff, shareLocation} from "./otherfile"
// Add this code to the end of the createWindow() function.
shareLocation('main.ts (main.js)');
Now if you run this example with npm start
you will see I was imported by: main.ts (main.js)
in your terminal.
If you tried to do this with the src/preload.ts
file you will get an error because of sandboxing. To see this, make the following change in src/preload.ts
:
// Add to first line.
import {stuff, shareLocation} from "./otherfile";
// Add after the for loop inside the DOMContentLoaded function.
shareLocation('preload.ts (preload.js)');
Now if run npm start
you will get an error in the electron window (web browser) console. This is because of important security settings within Electron. Make the following change to your src/main.ts
file:
// Modify the webPreferences of the new BrowserWindow.
const mainWindow = new BrowserWindow({
height: 600,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
sandbox: false // <=== ADD THIS LINE
},
width: 800,
});
Your import will work as intended now and you should see I was imported by: preload.ts (preload.js)
in the electron window (web browser) console. Keep in mind this code is insecure! You should use IPC instead of disabling the sandbox.
If you are still getting an error I believe it is because your confusing CommonJS (CJS) and ES modules (ESM). It sounds like you are using CJS exports with ESM imports. See the next section that demos the difference.
CommonJS (CJS) vs ES modules (ESM)
CommonJS (CJS)
CommonJS was the original method for exporting and requiring (importing) modules in Node. It was a standard introduced by Mozilla engineer Kevin Dangoor in 2009. You would write some code in one file like so:
// example.js
function hello() {
console.log('World!');
}
module.exports = hello;
And then require (import) the code into another module/file like so:
// main.js
const hello = require('./example.js');
hello();
Just like ES modules, which is a newer standard, "you can export functions
, var
, let
, const
, and classes
" (MDN Docs). Here is an bigger example that exports two functions using a single export object
:
// example.js
function hello() {
console.log('World!');
}
function foo() {
console.log('Bar!');
}
module.exports = {
hello,
foo
};
We could even change the exported object
to refer to our functions by a different name. We could change the export code to this for example:
module.exports = {
H: hello,
F: foo
};
We would then require (import) this code like so:
// main.js
const {hello, foo} = require('./example.js');
hello();
foo();
// OR with the other export example
const {H, F} = require('./example.js');
H();
F();
ES Module (ESM)
This is the modern approach to including JavaScript code from one file/module into another, and is designed to work in modern browsers. If you were manually writing JavaScript modules for the web you would have to add the type="module"
attribute to the script tag that loads your module.
In your setup, and many others, you have bundlers (webpack for example) of some kind that handle this for you by compiling/transpiling your code for you. This topic is out of scope to this question though, so lets look at an example.
Using ESM our simple example now becomes:
// example.js
function hello() {
console.log('World!');
}
export default hello;
Notice how our export statement has changed. To keep things simple I provide a default
export when exporting a single item. We can also inline the export:
// example.js
export default function hello() {
console.log('World!');
}
And then we import the code into another module/file like so:
// main.js
import hello from "example";
hello();
If you do not want to use default
in your exported module you will have to use a different syntax for importing your code. As Darryl Noakes mentions, that would be Named Exports. Since this is a TypeScript project this includes changing your TypeScript config. This SO answer covers what to do if you want to go this route with this project.
If you export multiple items you do not have to use the default
statement:
// example.js
function hello() {
console.log('World!');
}
function foo() {
console.log('Bar!');
}
export {
hello,
foo
}
And you import the code in a similar fashion to object destructing:
// main.js
import {hello, foo} from "example";
hello();
foo();
For additional help with import
this MDN Doc is a great start as well as this Free Code Camp Article. JavaScript Tutorial has a great tutorial on what object destructing is. This SO Q&A goes more into module imports including why they are not actually using destructing. Thanks again to Darryl Noakes for pointing that out!