I want to build an Electron app with ES6 import syntax so I can re-use modules between my Node.js and browser side JS without code duplication and found Electron is frustratingly behind the times on ES6 syntax support.
I learned about this magical solution only to discover it was no longer maintained.
So Babel to the rescue, or so I thought. Google isn't exactly fruitful on the topic of Babel + Electron tutorials. I also wanted to throw in Nodemon.
Here's my setup:
package.json
{
"name": "infinitum",
"version": "1.0.0",
"description": "",
"main": "compiled.js",
"directories": {
"test": "tests"
},
"scripts": {
"start": " electron .",
"compile": "nodemon --exec babel-node app.js --out-file compiled.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/node": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"electron": "^11.1.0",
"nodemon": "^2.0.6"
}
}
As you're going to see in the following output and debugging logs, the problem here is we're trying to compile the node module to use ES6 syntax, but any Electron app is dependent on the Electron module, which seems to not export in a traditional way, resolving the electron executable path (string) instead of a Node.js module. It's a circular problem.
app.js
import {app, BrowserWindow} from 'electron'
import 'url'
import 'path'
let win
function createWindow() {
win = new BrowserWindow({width: 800, height: 600})
win.loadURL(url.format ({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
}
app.on('ready', createWindow)
.babelrc
{
"presets": [
"@babel/preset-env"
]
}
I'm running:
npm run compile
Which gives the error:
C:\Users\jonat\documents\github\infinitum\app.js:23
_electron.app.on('ready', createWindow);
^
TypeError: Cannot read property 'on' of undefined
at Object.<anonymous> (C:\Users\jonat\documents\github\infinitum\/app.js:16:5)
at Module._compile (internal/modules/cjs/loader.js:1076:30)
at Module._compile (C:\Users\jonat\Documents\GitHub\infinitum\node_modules\pirates\lib\index.js:99:24)
at Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
at Object.newLoader [as .js] (C:\Users\jonat\Documents\GitHub\infinitum\node_modules\pirates\lib\index.js:104:7)
at Module.load (internal/modules/cjs/loader.js:941:32)
at Function.Module._load (internal/modules/cjs/loader.js:782:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at Object.<anonymous> (C:\Users\jonat\Documents\GitHub\infinitum\node_modules\@babel\node\lib\_babel-node.js:172:21)
at Module._compile (internal/modules/cjs/loader.js:1076:30)
So to debug I tried this app.js
:
import electron from 'electron'
console.log("typeof electron:", typeof electron, "\nelectron:", electron)
Output:
typeof electron: string
electron: C:\Users\jonat\documents\github\infinitum\node_modules\electron\dist\electron.exe
And as further clarification, an app.js like this:
import * as name from 'electron'
console.log({ name })
logs:
{
name: {
default: 'C:\\Users\\jonat\\documents\\github\\infinitum\\node_modules\\electron\\dist\\electron.exe'
}
}
I'm realizing this is probably because the "electron ." does something special in the parsing pipeline. But I've definitely heard of Babel being the solution to using ES6 import syntax in Electron, I just cant find an actual guide on doing it. So how can I use Babel with Electron?