最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - dotenv is not loading properly - Stack Overflow

programmeradmin1浏览0评论

I am having a bit of trouble with the dotenv module. Within my project, I am utilizing an API which requires a API key. Thus, upon utilizing : require('dotenv').config() at the top of my file and requesting const API_KEY = process.env.API_KEY to grab the value from my .env file, I continuously get an "undefined" value when I console.log my environment variable. So far, here are my leads:

  • I have tried hard coding the relative path to my .env file using require('dotenv').config(path:'./../../.env') which did not work for me
  • the dependency "dotenv" is installed properly
  • I have checked my API to make sure I copied it correctly
  • when I console.log(require('dotenv').config()), I get an error message env variable stating that "fs.readFileSync is not a function"; I have absolutely no clue what this means... every google search I have done on this error has made me more confused

For reference here is the code I am trying to reference the .env variable in:

overview.js

import React from 'react';
import './overview.css';
import { RecentSearches } from '../Recent Searches/recentSearches';
import { Hourly } from '../Hourly/hourly';
import { Fiveday } from '../5 Day Forecast/fiveday';

require('dotenv').config();
console.log(require('dotenv').config());

export function Overview() {

    // this callback function receives the searched city entered from recentSearches and applies it to fetchForecast
    const getSearch = async (searchedCity) => {
        fetchForecast(searchedCity);
    }; 

    const fetchForecast = async (city) => {
        const api_key = process.env.API_KEY;
        console.log(api_key);
        // const api_key = '2220f5a5d83243938f764759211310';
        var BASE_URL = `.json?key=${api_key}&q=${city}&days=3&aqi=no&alerts=no`;
    
        const response = await fetch(BASE_URL);
        const data = await response.json();
        console.log(data);

        // collects all of the current weather info for your search
        const currentTempInfo = {
            city: data.location.name, 
            state: data.location.region, 
            epochDate: data.location.localtime_epoch, 
            message: data.current.condition.text, 
            wicon: data.current.condition.icon, 
            currentTemp: data.current.temp_f,
            currentHighTemp: data.forecast.forecastday[0].day.maxtemp_f,
            currentLowTemp: data.forecast.forecastday[0].day.mintemp_f,
            feelsLike: data.current.feelslike_f,
            humidity: data.current.humidity,
            rainLevel: data.current.precip_in,
            // hourlyTemps is an array, starts from midnight(index 0) and goes every hour until 11 pm(index 23)
            hourlyTemps: data.forecast.forecastday[0].hour.map((entry) => {
                let epochTime, temp;
                [epochTime, temp] = [entry.time_epoch, entry.temp_f];
                return [epochTime, temp];
            })
        };

        // console.log(currentTempInfo);
    
        const daycardInfo = [];
        // this for loop triggers and creates an array with all necessary values for the 
        function daycardForLoop() {
            for (let x=0; x < 3; x++) {
                const fcDayDates = data.forecast.forecastday[x].date_epoch;
                const dayInfo = data.forecast.forecastday[x].day; 
                const dayValues = {
                    dates: fcDayDates, 
                    message: dayInfo.condition.text, 
                    wicon: dayInfo.condition.icon, 
                    maxTemp: dayInfo.maxtemp_f, 
                    minTemp: dayInfo.mintemp_f, 
                    avgTemp: dayInfo.avgtemp_f
                };
                // pushes dayValues object into daycardInfor array
                daycardInfo.push(dayValues);
            };
        }; 
        
        daycardForLoop();
    
        // this updates the state with the forecast for the city entered
        const newData = {
            currentTempInfo: currentTempInfo,
            daycardInfo: daycardInfo
        };

        // this spits out the newly created forecast object
        return newData;
    };

    return (
        <div>
            <div className='jumbotron' id='heading-title'>
                <h1>Wele to <strong>Weathered</strong>!</h1>
                <h3>A Simple Weather Dashboard </h3>
            </div>

            <div className='container-fluid' id='homepage-skeleton'>
                <div className='d-flex' id='center-page'>
                    <RecentSearches getSearch={getSearch}/>
        
                    <Hourly />
                </div>
            </div>

            <Fiveday />        
        </div>
    )
};


I am having a bit of trouble with the dotenv module. Within my project, I am utilizing an API which requires a API key. Thus, upon utilizing : require('dotenv').config() at the top of my file and requesting const API_KEY = process.env.API_KEY to grab the value from my .env file, I continuously get an "undefined" value when I console.log my environment variable. So far, here are my leads:

  • I have tried hard coding the relative path to my .env file using require('dotenv').config(path:'./../../.env') which did not work for me
  • the dependency "dotenv" is installed properly
  • I have checked my API to make sure I copied it correctly
  • when I console.log(require('dotenv').config()), I get an error message env variable stating that "fs.readFileSync is not a function"; I have absolutely no clue what this means... every google search I have done on this error has made me more confused

For reference here is the code I am trying to reference the .env variable in:

overview.js

import React from 'react';
import './overview.css';
import { RecentSearches } from '../Recent Searches/recentSearches';
import { Hourly } from '../Hourly/hourly';
import { Fiveday } from '../5 Day Forecast/fiveday';

require('dotenv').config();
console.log(require('dotenv').config());

export function Overview() {

    // this callback function receives the searched city entered from recentSearches and applies it to fetchForecast
    const getSearch = async (searchedCity) => {
        fetchForecast(searchedCity);
    }; 

    const fetchForecast = async (city) => {
        const api_key = process.env.API_KEY;
        console.log(api_key);
        // const api_key = '2220f5a5d83243938f764759211310';
        var BASE_URL = `http://api.weatherapi./v1/forecast.json?key=${api_key}&q=${city}&days=3&aqi=no&alerts=no`;
    
        const response = await fetch(BASE_URL);
        const data = await response.json();
        console.log(data);

        // collects all of the current weather info for your search
        const currentTempInfo = {
            city: data.location.name, 
            state: data.location.region, 
            epochDate: data.location.localtime_epoch, 
            message: data.current.condition.text, 
            wicon: data.current.condition.icon, 
            currentTemp: data.current.temp_f,
            currentHighTemp: data.forecast.forecastday[0].day.maxtemp_f,
            currentLowTemp: data.forecast.forecastday[0].day.mintemp_f,
            feelsLike: data.current.feelslike_f,
            humidity: data.current.humidity,
            rainLevel: data.current.precip_in,
            // hourlyTemps is an array, starts from midnight(index 0) and goes every hour until 11 pm(index 23)
            hourlyTemps: data.forecast.forecastday[0].hour.map((entry) => {
                let epochTime, temp;
                [epochTime, temp] = [entry.time_epoch, entry.temp_f];
                return [epochTime, temp];
            })
        };

        // console.log(currentTempInfo);
    
        const daycardInfo = [];
        // this for loop triggers and creates an array with all necessary values for the 
        function daycardForLoop() {
            for (let x=0; x < 3; x++) {
                const fcDayDates = data.forecast.forecastday[x].date_epoch;
                const dayInfo = data.forecast.forecastday[x].day; 
                const dayValues = {
                    dates: fcDayDates, 
                    message: dayInfo.condition.text, 
                    wicon: dayInfo.condition.icon, 
                    maxTemp: dayInfo.maxtemp_f, 
                    minTemp: dayInfo.mintemp_f, 
                    avgTemp: dayInfo.avgtemp_f
                };
                // pushes dayValues object into daycardInfor array
                daycardInfo.push(dayValues);
            };
        }; 
        
        daycardForLoop();
    
        // this updates the state with the forecast for the city entered
        const newData = {
            currentTempInfo: currentTempInfo,
            daycardInfo: daycardInfo
        };

        // this spits out the newly created forecast object
        return newData;
    };

    return (
        <div>
            <div className='jumbotron' id='heading-title'>
                <h1>Wele to <strong>Weathered</strong>!</h1>
                <h3>A Simple Weather Dashboard </h3>
            </div>

            <div className='container-fluid' id='homepage-skeleton'>
                <div className='d-flex' id='center-page'>
                    <RecentSearches getSearch={getSearch}/>
        
                    <Hourly />
                </div>
            </div>

            <Fiveday />        
        </div>
    )
};


Share Improve this question edited Jan 19, 2022 at 8:08 jonrsharpe 122k30 gold badges267 silver badges474 bronze badges asked Jan 19, 2022 at 8:06 Gian Paulo ZamoraGian Paulo Zamora 831 gold badge3 silver badges6 bronze badges 2
  • 2 You can't use dotenv on the client, because it has no access to environment variables (in general it's not even going to be running on the same machine where they're set) and the API it uses (fs.readFileSync) is part of Node and not available in the browser. It's unclear how your app is set up, but if you're using Webpack you could use the DefinePlugin to inject those values at build time, I wrote about this in: github./textbook/starter-kit/wiki/… – jonrsharpe Commented Jan 19, 2022 at 8:10
  • dotenv is a Node.js (server-side) module. You can't use it in a browser. Node has fs (FileSystem), a browser doesn't. – Jeremy Thille Commented Jan 19, 2022 at 8:26
Add a ment  | 

3 Answers 3

Reset to default 3

In case you are using create-react-app (CRA), you don't need dotenv.

create-react-app has a nice guide explaining multiples ways to use environment variables (one choice is to use a .env file in your root directory). The variables must start with REACT_APP_.

Warning: do not build your project with any secrets as environment variables (like API keys), you will also see this warning in the guide. They will be exposed to anyone accesing your React application.

@aLittleSalty has the right answer for your case. The error you are seeing is because dotenv is supposed to be used in a node server/backend, and the browser has no access to the filesystem.

But, if you are using node for a server/backend and you stumble on this question, my answer applies to you.

The .env file path is by default path.resolve(process.cwd(), '.env'). cwd is the current working directory: this means that dotenv looks for the file in the directory from which the code is run.

If you want to specify the relative path, this is what you should use:

const path = require('path');
console.log(require('dotenv').config({path: path.resolve(__dirname, '../../.env')}));

dotenv docs: https://www.npmjs./package/dotenv#user-content-path

You have to import dotenv in your webpack configiguration and then use DefinePlugin to pass the variables to your React app.

const webpack = require('webpack');
const dotenv = require('dotenv');

module.exports = () => {
  // Here you need to call config method of dotenv package 
  const env = dotenv.config().parsed;


  return {
    plugins: [
     new DefinePlugin({
        'process.env': JSON.stringify(env)
     })      
    ]
};
发布评论

评论列表(0)

  1. 暂无评论