8

I am trying to use the dotenv-webpack plugin. This works great locally. But fails when I deploy to Heroku.

I have followed advice according to this git issue, but still am having issues.

My webpack config looks like this:

const path = require('path');
const Dotenv = require('dotenv-webpack');

module.exports = {
  context: path.join(__dirname, '/src'),

  entry: {
    javascript: './js/index'
  },

output: {
  filename: 'bundle.js',
  path: path.join(__dirname, '/dist'),
},

resolve: {
  alias: {
    react: path.join(__dirname, 'node_modules', 'react')
  },
  extensions: ['.js', '.jsx'],
},

module: {
  rules: [
  {
    test: /\.jsx?$/,
    exclude: /node_modules/,
    loaders: ['babel-loader'],
  },
  {
    test: /\.html$/,
    loader: 'file?name=[name].[ext]',
  },
 ],
},
plugins: [
  new Dotenv({
    path: path.resolve(__dirname,'.env')
  }),
 ]
};

I am expecting that where the dotenv plugin is written as above, it will resolve my .env file (which is located at the root of the project, along with the webpack.config) upon build time, thus giving my project access to env vars. Instead, the env vars are undefined, in Heroku. I have an env var set in Heroku. The Key is set to something like SECRET_KEY. Value is set to something like 123456. Can anyone give me some insight?

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
sWarren
  • 473
  • 2
  • 4
  • 10
  • 1
    you can set your env vars in the heroku dashboard for production... – SakoBu Jan 18 '19 at 22:10
  • @SakoBu Hey thanks for replying. I did actually. Maybe I am not matching them right? My .env file looks something like: SECRET_KEY=123456 In my Heroku Dashboard I have key set to SECRET_KEY and value set to 123456. Does that make sense? – sWarren Jan 18 '19 at 22:12
  • https://github.com/motdotla/dotenv/issues/126 .env to Prod NOT REcommend on heroku. Set config vars is what they recommend for ENV settings. – Robert Rowntree Jan 19 '19 at 00:19

4 Answers4

11

I don't use Heroku and I have not tried it. But I understand that if you defined the variables at Heroku dashboard, then those variables are system variables, so you need to use the option systemvars: true of "dotenv-webpack".

As declaration (I repeat, I never used Heroku): All this depends on how works the Heroku deploys, if you build the application inside of Heroku (you call to Webpack inside Heroku) then it works but if you send the built application to Heroku (you don't call to Webpack inside of Heroku) then it doesn't work.

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
alexojegu
  • 754
  • 7
  • 21
4

I think you can set up a custom webpack plugin instead.

const path = require('path');
const webpack = require('webpack')
module.exports = {
  entry: './src/index.js',
  mode: 'production',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
  node: {
    fs: 'empty'
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
         'API_KEY': JSON.stringify(process.env.API_KEY)
      }
    })
  ]
};

Like these samples in your webpack.prod.js file.

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
  • 1
    Or you can use `new webpack.EnvironmentPlugin` and pass directly your object with the variables' names – Radu Chiriac Oct 25 '19 at 17:17
  • @OLUWATOSIN.A AKINYELE: For some reason, my `webpack.config.js` is unable to see `process.env.API_KEY` from `.env` file (or any value from this file). Do you know why? To make it work I had to insert the value right there in the line: 'API_KEY': JSON.stringify('my_value_here') – Fabricio Nov 22 '21 at 11:38
3

Actually, this issue comes from the environment values of the Heroku server. because in production mode dotenv call the real environment variable, I mean this:

echo $SECRET_KEY

But it returns undefined, why? because in the production mode the .env file won't be seen. so if you are serious about using the dotenv-webpack plugin you should pass the path for development just like your code:

plugins: [
  new Dotenv({
    path: path.resolve(process.cwd(), '.env'),
  }),
 ],

And for the production, there are two ways:

  1. passing directly in the webpack configuration:
plugins: [
  new webpack.DefinePlugin({
    'process.env': {
      'SECRET_KEY': '123456'
    },
  }),
],
  1. fill the server environment variable. for a simple Linux server I prefer to use export SECRET_KEY=123456, but for Heroku read this article

Hint: In other cases like using Docker or Kubernetes it is needed to use image or cluster configuration file to pass environment variables.

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
  • This is the only thing that worked for me. Once I put the dotenv with process.cwd() that made it run. Thank you! – Igor M May 20 '23 at 21:29
0

Based on the documentation of dotenv, you don't use the config method which reads and parses the content from your .env file.

By the way, since you're dealing with the webpack, I'd suggest using the dotenv-webpack package. The given documentation shows an example of the basic configuration along with some other feasible arguments.

If you're interested in other ways of setting up environment variables specifically in React, I recommend this link well-detailed article.

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
zsgomori
  • 517
  • 5
  • 10
  • 1
    Thanks I actually am using dotenv-webpack. Works locally but not in production for some reason! – sWarren Jan 19 '19 at 00:13
  • Have you tried looking into the logs generated by Heroku? Isn't there any specific detail that could tell more about the error you get? I can't believe that dotenv-webpack doesn't work in production, there should be something that interferes the deployment. – zsgomori Jan 19 '19 at 11:52