Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dotenv-webpack in production?

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?

like image 385
sWarren Avatar asked Jan 18 '19 21:01

sWarren


3 Answers

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.

like image 78
alexojegu Avatar answered Sep 22 '22 17:09

alexojegu


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.

like image 39
OLUWATOSIN.A AKINYELE Avatar answered Sep 21 '22 17:09

OLUWATOSIN.A AKINYELE


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.

like image 45
AmerllicA Avatar answered Sep 19 '22 17:09

AmerllicA