1

I have created an app using Create-React-App on the client side and using express in the server side. I have created an .env file for my environment variables where the DB_USER and DB_PASSWORD will be stored.

In the server side, I would like to use a mongoose connection and the .env variables will be the credentials when connecting to the mongodb server.

I'm getting undefined variables in the terminal console when I do process.env.DB_USER. Instead I'm getting my OS environment variables, and NodeJS variables. However, I do see the variables when I do console.log(process.env.DB_USER) in chrome console/client side.

I tried to install dotenv, dotenv-webpack and configure my webpack.config but nothing seem to be working. I have also added REACT_APP_* as prefix to my variables, but still undefined values.

Also when I use dotenv and set this require('dotenv').config() in my index.js file, it complains about an fs dependency??

I just can't get the environment variables to be read in the server folder, ideally it will be nice to have these variables read in the client and server folder. Has anyone encountered this issue before? I'm just learning how to use Create-React-App and webpack. Your help will be appreciated!!!

server.js

//server.js
const express = require('express');
const path = require('path');
const router = require('./routes/routes.js')
const app = express();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const user = process.env.REACT_APP_DBUSER;
const password = process.env.REACT_APP_DBPASSWORD;

//tells express frontend will reside in client folder
app.use(express.static(path.join(__dirname, '../build')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

console.log('node', process.env);
console.log(user);//this is undefined

//connect to mongoDB
mongoose.connect(`mongodb://${user}:${password}@ds141812.mlab.com:41812/note_app_db`, { useNewUrlParser: true });

let conn = mongoose.connection;
conn.on('error', console.error.bind(console, 'connection:'));
conn.once('open', () => {
    console.log('connected to database');
});

//pass in routes from router const
app.use('/',router)

module.exports=app;

webpack.config

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

const config = {
    entry: __dirname + '/client/js/index.jsx',
    output: {
        path: __dirname + '/build',
        filename: 'bundle.js'
    },
    resolve: {
        extensions: ['.js', '.jsx', '.css']
    },
    module: {
        rules: [
        {
            test: /\.jsx?/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            query: {
                presets: ['@babel/preset-env', '@babel/react']
            }
        },
        {
            test: /\.(png|jpg|svg|gif|mp4|mov)$/,
            use: [{
                loader: 'file-loader',
                options: {
                    name: '/assets/[name]-[hash:8].[ext]'
                }
            }]
        },
        {
            test: /\.scss$/,
            loader: 'style-loader!css-loader!sass-loader'
        }
        ]
    },
    devServer: {
        publicPath: '/',
        contentBase: __dirname + '/build',
        port: 5000,
        historyApiFallback: {
            index: 'index.html'
        }
    },
    plugins: [
        new CopyWebpackPlugin([
            { from: './client/index.html', to: './index.html' }
        ]),
        new Dotenv({
            path: './.env',
        }),
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: JSON.stringify("development"),
                REACT_APP_DBUSER: JSON.stringify(process.env.REACT_APP_DBUSER),
                REACT_APP_DBPASSWORD: JSON.stringify(process.env.REACT_APP_DBPASSWORD)
            }
        })
    ]
}


module.exports = config

index.jsx

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
require('dotenv').config({path: '../../.env'});//is this how it supposed to look like???

ReactDOM.render(<App />, document.getElementById('root'));

package.json

{
  "name": "note_app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@babel/core": "^7.1.5",
    "@babel/preset-env": "^7.1.5",
    "@babel/preset-react": "^7.0.0",
    "axios": "^0.18.0",
    "babel-loader": "^8.0.4",
    "body-parser": "^1.18.3",
    "copy-webpack-plugin": "^4.6.0",
    "css-loader": "^1.0.1",
    "dotenv": "^6.1.0",
    "dotenv-webpack": "^1.5.7",
    "env-cmd": "^8.0.2",
    "express": "^4.16.4",
    "file-loader": "^2.0.0",
    "mongoose": "^5.3.11",
    "node-sass": "^4.10.0",
    "nodemon": "^1.18.6",
    "react": "^16.6.1",
    "react-dom": "^16.6.1",
    "react-modal": "^3.6.1",
    "react-router-dom": "^4.3.1",
    "react-scripts": "2.1.1",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "webpack-cli": "^3.1.2"
  },
  "scripts": {
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "webpack": "webpack --mode development",
    "dev": "npm run webpack && nodemon bin/www"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

.env file

REACT_APP_DBUSER="username"
REACT_APP_DBPASSWORD="password"

file structure enter image description here

4
  • I’m client console can u see the values of DB credentials? If so there is something wrong and not good security wise Commented Nov 12, 2018 at 4:45
  • Hi medev21, did you mange to figure this issue out? I have the same problem. Commented Nov 23, 2020 at 22:05
  • @danielblythe I posted the solution below, what worked for me but here what I wrote: "Found the solution, so dotenv is fine and I had uninstall dotenv-webpack. In order for the server.js file to read the environment variables, I just needed to add require('dotenv').config(); in this file. It should be good to go!" Commented Nov 25, 2020 at 15:28
  • Thanks medev21 but I've since realised that the frontend shouldn't have access to the server env variables because (for anyone reading this) the secrets/keys would be baked into the code and becoming a security risk. So I need to make requests from the front-end to the back end where the keys live to solve this issue. Commented Nov 26, 2020 at 9:34

3 Answers 3

3

Found the solution, so dotenv is fine and I had uninstall dotenv-webpack. In order for the server.js file to read the environment variables, I just needed to add require('dotenv').config(); in this file. It should be good to go!

Sign up to request clarification or add additional context in comments.

Comments

0

Replacing my old incorrect answer.

Rather than using that dotenv-webpack package, could you use this package:

https://www.npmjs.com/package/dotenv

In theory, you can remove that new DotEnv from your plugins and then when you call require('dotenv').config(), your webpack.config.js should have access to those env variables, then your webpack define plugin will pick them up and inject them into your code

2 Comments

I have already added the REACT_APP_ to my variables and still the same issue.
I removed new DotEnv and still issue. First I had an issue with the fs dependency so I had to add node: {fs: 'empty'} in webpack.config.js, it ran but still undefined values. Then I added the path in the dotenv, so require('dotenv').config({path: '../../.env'}); but still undefined values.
0

You don't need to install any package just write REACT_APP before your token then you can process.env.REACT_APP_TOKEN_NAME

.env file looks like this

REACT_APP_TOKEN_NAME = fhsahffdsaf-sdfsf-fds

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.