Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Built apps dont have env variables available. They are available when the app is in development #139

Closed
aravindjaimon opened this issue Feb 9, 2022 · 10 comments

Comments

@aravindjaimon
Copy link

Describe the bug
A clear and concise description of what the bug is.
Our app is running in two environments, production and staging. There is an env file that consists of different variables that need to be loaded. all the env's are available when the app is running in development mode

Expected behavior
A clear and concise description of what you expected to happen.
I am supposed to get the env's in the .env file when I try to get them via process.env

Desktop (please complete the following information):

  • OS: Linux, Macintosh, Windows
  • Nx Electron Version "nx-electron": "^11.3.0",
@bennymeg
Copy link
Owner

In order to include special files into the packaged application, you have to include them in the packager/maker.config.json configuration file at the files field.

@aravindjaimon
Copy link
Author

@bennymeg I added the .env path to maker.config.json but then too its not getting loaded. I was wondering how is it that I am getting all the variables in development mode but not when building the app. and also process.env.NODE_ENV is always development.

@bennymeg
Copy link
Owner

bennymeg commented Mar 6, 2022

Verify that the relative path of the '.env' file to the 'main.js' file inside the '.asar' file and in the unpackaged project are the same.

@aravindjaimon
Copy link
Author

Well, Its not getting shown there. Finally what i did was there was no secrets in the env's I moved them all to environment.ts files for all environment and change them during the building process with fileReplacements in the workspace.json I am not using .env's any more

@ilbertt
Copy link

ilbertt commented Mar 25, 2022

I have the same issue, with a single .env file in the Nx workspace root folder. The app has environment variables if I launch it from serve command but then if I package it the env variables are all undefined.

In order to include special files into the packaged application, you have to include them in the packager/maker.config.json configuration file at the files field.

Also I can't figure out how to do what you say here @bennymeg

@bennymeg
Copy link
Owner

@Luca8991 Only transpiled code files and the assets folder get packaged (in a specific structure).
If you wish to add other file, you have couple of options:

  • Read this document about the topic and update the configuration file.
  • Add the files to the assets folder.

@ilbertt
Copy link

ilbertt commented Mar 29, 2022

@bennymeg I read that document and tried to put the .env file inside the package: it's now inside the package but still not loaded inside process.env object, even after calling import 'dotenv/config' at the start of main.ts. I have doubts that including that file in the asar package, which contains all secrets also for other apps or libs of the Nx repo, would be the best practice.
Don't you think the environment variables from .env file should be loaded by webpack directly in the build? This is done when using serve and should be the same for package and make.

@ilbertt
Copy link

ilbertt commented Mar 29, 2022

@bennymeg I read that document and tried to put the .env file inside the package: it's now inside the package but still not loaded inside process.env object, even after calling import 'dotenv/config' at the start of main.ts. I have doubts that including that file in the asar package, which contains all secrets also for other apps or libs of the Nx repo, would be the best practice.
Don't you think the environment variables from .env file should be loaded by webpack directly in the build? This is done when using serve and should be the same for package and make.

I managed to do it using a custom-webpack config in these steps:

  • installed dotenv-webpack
  • created this custom-webpack.config.js file in the apps/my-electron-app/ folder:
    // custom-webpack.config.js file
    
    // Helper for combining webpack config objects
    const { merge } = require('webpack-merge');
    const Dotenv = require('dotenv-webpack');
    
    module.exports = (config, context) => {
      return merge(config, {
        plugins: [
          new Dotenv()
        ]
      });
    };
  • set the path to this file in the webpackConfig option of my-electron-app's project.json as specified in the build executor schema.

Now the env variables are directly exposed in the webpack bundle, and the cool thing is that the only the variables exposed are the ones explicitly referenced in your code!

Hope this can help also @aravindjaimon

@bennymeg
Copy link
Owner

I have doubts that including that file in the asar package, which contains all secrets also for other apps or libs of the Nx repo, would be the best practice.

If it only contains environment variables it would be considered as bed practice, if it also contains secrets it would be also a bed idea. I most say, even if you use webpack to inject some of the variables into your code you should be careful, because, to my understanding, they will get bundled into your production code.
I think it is better to let the developers decide if they want to do that (like you did) rather then implementing that feature for everybody.

@paustint
Copy link

Adding a comment here for any other folks that may come across this issue - I looked into dotenv-webpack and that didn't seem like a good fit for my project since it would appear to potentially replace valid usages of process.env that I was using.

NX convention is to automatically replace any environment variables that begin with NX_ in any application, even browser applications - documentation: https://nx.dev/guides/environment-variables#environment-variables.

The docs show an example of how to implement this for Angular applications, so I attempted to follow that pattern for electron but the example had a number of issues.

Here is a working example that will replace any environment variables that are accessed using this pattern: process.env.NX_ in your electron application (the node version).

This solution worked better for me since I only wanted to replace a limited number of environment variables and not normal node process environment variables that may be accessed at runtime.

apps/electron-app/project.json

{
...
"targets": {
    "build": {
...
      "options": {
...
        "webpackConfig": "apps/electron/electron-app/webpack.config.js"
      },
...

You can alternatively use webpack-merge as shown in the nx docs if you don't already happen to have @nrwl/react installed.

apps/electron/electron-app/webpack.config.js

const { DefinePlugin } = require('webpack');
const getWebpackConfig = require('@nrwl/react/plugins/webpack');

function getClientEnvironment() {
  // Grab NODE_ENV and NX_* environment variables and prepare them to be
  // injected into the application via DefinePlugin in webpack configuration.
  const NX_APP = /^NX_/i;

  const raw = Object.keys(process.env)
    .filter((key) => NX_APP.test(key))
    .reduce((env, key) => {
      env[key] = process.env[key];
      return env;
    }, {});

  // Stringify all values so we can feed into webpack DefinePlugin
  return {
    'process.env': Object.keys(raw).reduce((env, key) => {
      env[key] = JSON.stringify(raw[key]);
      return env;
    }, {}),
  };
}

module.exports = (config) => {
  config = getWebpackConfig(config);

  config.plugins = config.plugins || [];
  config.plugins.unshift(new DefinePlugin(getClientEnvironment()));

  return config;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants