17

The Node.js environment in Windows can be set before the server is started, like this:

set NODE_ENV=production 

That NODE_ENV parameter can be used in Node.js or electron by process.env.NODE_ENV.

But when I build electron using electron-builder, like this:

electron-builder build --windows

How do I set the environmental variables?


Update:

May be I cannot pass a fixed environment variable to an executable by electron-builder.

Maybe you can only manually load an environment file, modify it when you package it, or preset the parameters to the dev state. When there is no state, it is production.

icc97
  • 11,395
  • 8
  • 76
  • 90
Finn
  • 1,323
  • 5
  • 24
  • 46
  • Similar question that has a useful answer: https://stackoverflow.com/questions/72656933/put-env-file-while-building-in-electron-packed-app/76404441 – icc97 Jun 22 '23 at 21:08

3 Answers3

8

If you want an environment variable to be set on runtime you can either set them manually or use other tools like dotenv https://www.npmjs.com/package/dotenv

But the easiest way is to set them at runtime when running the binaries. You can use either a batch script (If windows) for example:

setlocal
set NODE_ENV=production
.\your-binaries.exe
endlocal

Note: setlocal prevents the variable leaking any further.

The one-liner version could be set NODE_ENV=production && .\binaries.exe

Under linux works the same way: set variable then run.

Sigma Octantis
  • 903
  • 1
  • 8
  • 25
  • What does “CLI usage” mean? I created a `electron-builder.env` file in the current dir and input `NODE_ENV=production`, and builder electron, It's not work. I try to working in `electron .` to start and test show `console.log(process.env.NODE_ENV)`, It's undefined. – Finn Jan 17 '19 at 02:00
  • @AlbertChen CLI ( https://en.wikipedia.org/wiki/Command-line_interface ) means that this file is read by the command `electron-builder` at runtime, `electron` will not read it. – Sigma Octantis Jan 17 '19 at 07:40
  • I was try to build electron by `electron-builder` command , like this: `electron-builder build --windows`, but it's not work. I need other parameter for the command? – Finn Jan 17 '19 at 07:45
  • @AlbertChen Try to put it in the root of source files, like in this repository that is used as example in the docs https://github.com/motdotla/dotenv-expand/tree/master/test (See `.env`) – Sigma Octantis Jan 17 '19 at 07:48
  • 1
    I was put `electron-builder.env` file in root of source files(same as `package.json` path or `electron-builder.json` path). – Finn Jan 17 '19 at 07:53
  • @AlbertChen Wait, you want the variable to be defined at runtime in the built binaries? Because if it's that, the answer has nothing to do with electron-builder. – Sigma Octantis Jan 17 '19 at 08:22
  • 1
    runtime?built binarie? I went the `env` variable is working in release Setup(.exe) file by `electron-builder` builder. – Finn Jan 17 '19 at 08:30
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/186836/discussion-between-sigmasoldier-and-albert-chen). – Sigma Octantis Jan 17 '19 at 08:31
  • 6
    It's stated in directly in the documentation. Create a `electron-builder.env` file and put the variables inside. The `electron-builder.env` file should reside in the root of the folder, i.e. same folder as where `package.json` is, or where `electron-builder.json` is (if you are using it). When you package the app using the command line interface, meaning run `electron-builder` to package the files rather than using it as a library. However, it does NOT work. If any one gets it to working, please do comment. – oyalhi Dec 06 '19 at 16:42
  • Because this answer got edited there's some interesting information that was lost but relevant. The answer initially quotes *"Env file `electron-builder.env` in the current dir (example). Supported only for CLI usage."* (which is from [electron builder docs](https://www.electron.build/configuration/configuration#environment-variables-from-file)). The CLI usage is confusing - what they mean is that you have to use the CLI when running electron builder to include the `electron-builder.env` file. – icc97 Jun 21 '23 at 08:57
6

I'm posting this in the hopes that it helps other people in my situation. I have three environments (development, staging, and production), and I wanted my Electron main process to be aware of which environment it was running on.

Now, for development it's quite easy to expose an environment variable to Electron inline using the CLI:

export NODE_ENV=development && electron desktop/main.js

Then, Electron's main process can access this environment variable like so:

const isDev = process.env.NODE_ENV === 'development';

However, being able to distinguish between the staging and production environments was slightly trickier. My staging and production environments are both packaged and deployed using electron-builder, with package.json scripts like so:

"desktop-build": "webpack --config config/webpack/webpack.prod.js && electron-builder --config config/electron.config.js",
"desktop-build-staging": "webpack --config config/webpack/webpack.staging.js && electron-builder --config config/electron.config.js",

NOTE: The webpack configs above expose configs to the renderer process (website), but not the main process.

So my solution to expose the environment to the Electron main process for staging and production was as follows:

  1. Set NODE_ENV=staging or NODE_ENV=production to electron-builder via command line invocation:

    # Production
    export NODE_ENV=production && webpack --config config/webpack/webpack.prod.js && electron-builder --config config/electron.config.js
    
    # Staging
    export NODE_ENV=staging && webpack --config config/webpack/webpack.staging.js && electron-builder --config config/electron.config.js
    
  2. In my electron.config.js file (configs for electron-builder) use the extraMetadata parameter (docs) to inject a variable into my package.json:

    extraMetadata: {
        isProduction: Boolean(process.env.NODE_ENV === 'production'),
    },
    
  3. Then you can access that from your Electron main process:

    // This variable is injected into package.json by electron-builder via the extraMetadata field (specified in electron.config.js)
    const {isProduction} = Boolean(require('./package.json'));
    
Rory Abraham
  • 116
  • 1
  • 4
  • Part 1. of this answer will not work. When the main process runs, on a separate machine from where it was built, it will different environment variables. Especially in this case it will not have the `NODE_ENV` var. The *environment* variables are specified by the environment where the application is running, not when it is built. – icc97 Jun 21 '23 at 15:30
1

I solved this through dotenv and electron-builders' extraResources

Firstly create a .env file at the root of your project next to the package.json.

MY_VAR=foo

In the package.json include

  "build": {
    "extraResources": [
      ".env"
    ],
    ...
  }

In your main.js you need to use the path option for dotenv. Hat tip to this answer for pointing me towards dotenv.

When in dev mode, before the app is packaged, then dotenv will pick up the .env in the root. However when packaged you have to specify the path to where extraResources puts it which is in process.resourcesPath. You can use app.isPackaged to tell whether we are in dev mode or in the packaged application.

require('dotenv').config({
    path: app.isPackaged
        ? path.join(process.resourcesPath, '.env')
        : path.resolve(process.cwd(), '.env'),
})

// now process.env includes all the values from the `.env` file.
const foo = process.env.MY_VAR

Note: Just by having the .env in the root, electron-builder picked up the process.env vars within my application, but it seems that main.js is a special case that has to be handled differently.

icc97
  • 11,395
  • 8
  • 76
  • 90