I figured it out.
I am seeing this issue where, as it turns out, process environment variables are not actually carried over to the Electron app. Instead you have to request the variables from the remote process.
In the issue it recommends doing something like this:
const electron = window.require('electron');
const remote = electron.remote;
var x = remote.process.env["MY_VAR"];
In config.js
it appears require
is not defined, nor is window.require
, at least when running in the Electron context.
Some of the challenge I’m seeing I think is that the same config.js file is getting used in a Node.js/server context and in an Electron app context. I sort of feel like the Electron app should be requesting the configuration from the /config endpoint of the server rather than doing its own JS parsing, but I’m gathering that’s not actually what’s happening here.
To get this to work, there’s some careful hackery where:
- You need to enable the
nodeIntegration
feature on Electron. This is off for security reasons by default, however I’m not super concerned that someone on my local network will be hacking my Electron-based magic mirror app. Doing this allowswindow.require
to bring in theelectron
module, which you need to read the remote process. - You need to have conditional logic that either uses the current process environment (for the server side) or uses
electron.remote.process
(for the client side).
If you do that, you can get environment variables to work. It will look something like this:
var remote = null;
if (typeof window !== "undefined") {
remote = window.require("electron").remote;
}
var config = {
address: "localhost",
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
language: "en",
timeFormat: 24,
units: "imperial",
electronOptions: {
webPreferences: {
nodeIntegration: true
}
},
modules: [
{
module: "currentweather",
position: "top_right",
config: {
location: "Hillsboro",
locationID: "5731371", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city
appid: "OPENWEATHER_API_KEY"
}
},
{
module: "weatherforecast",
position: "top_right",
header: "Weather Forecast",
config: {
location: "Hillsboro",
locationID: "5731371", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city
appid: "OPENWEATHER_API_KEY"
}
}
]
};
var owApiKey = null;
if (typeof process !== "undefined" && process.env.OPENWEATHER_API_KEY)
{
// process is undefined in the Electron app.
owApiKey = process.env.OPENWEATHER_API_KEY;
}
if (remote && remote.process.env.OPENWEATHER_API_KEY)
{
// remote is null if the Electron nodeIntegration value isn't set to true.
owApiKey = remote.process.env.OPENWEATHER_API_KEY;
}
if (!owApiKey) {
console.log("You must define the OPENWEATHER_API_KEY environment variable for weather support.");
} else {
console.log("Updating modules that require the OPENWEATHER_API_KEY.");
config.modules.forEach(function (mmModule) {
if (mmModule.config && mmModule.config.appid == "OPENWEATHER_API_KEY") {
console.log("- " + mmModule.module);
mmModule.config.appid = owApiKey;
}
});
}
/*************** DO NOT EDIT THE LINE BELOW ***************/
if (typeof module !== "undefined") {
module.exports = config;
}
I will probably refactor that into a little method in here to make it easier to use and clean up some of the redundancy, but that’s what you have to do.