Electron / Node / TS / Vue Gotchas
A handful of things I tripped on while building UpgradeE.
published Apr 20, 2017 tags
#javascript
#electron
#node
~/posts/electron-pit $ cat post.md
Electron
- When you reach into the main process via
remoteto grab a global, you can’t pass a custom object. If you force it,prototypemethods are dropped and any “private” boundary is gone. - Setting an
iconwon’t accept aNativeImageor a raw path — you have to build a Path object. - If a Menu doesn’t include copy/paste items, copy/paste sometimes stops working entirely.
- On macOS, the first parent menu in a Menu is forced to the app name.
- Packaging: on Windows the icon file has to be at least 256×256 and can’t be naively converted; the easy fix is to re-save it through the built-in Paint app.
- macOS packages dmg only; Windows packages msi and exe.
- When Electron exits it doesn’t kill the Node processes it started. Stash the pids and clean up on exit.
const platform = process.platform;
function killTask() {
try {
if (platform === "win32") {
for (let pid of pids) {
childProcess.exec(`taskkill /pid ${pid} /T /F`);
}
pids = [];
} else {
for (let pid of pids) {
process.kill(pid);
}
pids = [];
}
} catch (e) {
showInfo("pid not found");
}
clearInterval(timerId);
}
Node
- In TypeScript, calling
requireor some library globals directly fails the compiler. The workaround isdeclare:
declare function require(name: string);
declare var Vue: any;
- Arrow-function
thisbehavior is confusing. (Rewritten on 2017-12-27.)
What this really does: when a Function is invoked, it implicitly
calls Function.call(<this>). With a normal function X, JS binds
this to the current execution context — some class, or the global.
Take this:
function a() {
this.d = 1;
function b() {
this.f = 2;
function c() {
this.g = 3;
}
}
}
When c is a regular function, this inside it is its own execution
context (the b layer), so this snippet is equivalent to:
function a() {
this.d = 1;
function b() {
this.f = 2;
function c() {
b.g = 3;
}
}
}
Make c an arrow function and the picture shifts:
function a() {
this.d = 1;
function b() {
this.f = 2;
let c = () => {
this.g = 3;
};
}
}
Now c’s this is the same as b’s this — meaning this.g = 3
sets g on the a layer, not on c’s own object.
- TypeScript won’t let you assign to a non-existent key with
obj.key, butobj["key"]lets the string assignment slide past the type checker.
Vue
- Inside a component, pass callbacks as wrapper functions, not as bare
method references — otherwise
thisends up somewhere unhelpful.
API
- LoL’s API occasionally returns a wrong 404.
- The current-game API sometimes returns an incorrect timestamp; validate the time first and fall back to the real game time when it’s off.