【问题标题】:dotenv is not loading properlydotenv 未正确加载
【发布时间】:2022-01-19 16:50:30
【问题描述】:

我在使用 dotenv 模块时遇到了一些问题。在我的项目中,我正在使用一个需要 API 密钥的 API。因此,在使用时: require('dotenv').config() 在我的文件顶部并请求 const API_KEY = process.env.API_KEY 从我的 .env 文件中获取值,当我 console.log 我的环境变量时,我不断地得到一个“未定义”的值。到目前为止,这是我的线索:

  • 我已尝试使用 require('dotenv').config(path:'./../../.env') 对我的 .env 文件的相对路径进行硬编码,但这对我不起作用
  • 正确安装了依赖项“dotenv”
  • 我检查了我的 API 以确保我正确复制了它
  • 当我 console.log(require('dotenv').config()) 时,我收到一条错误消息 env 变量指出“fs.readFileSync 不是函数”;我完全不知道这意味着什么......我对这个错误所做的每一次谷歌搜索都让我更加困惑

这里的参考是我试图在中引用 .env 变量的代码:

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.com/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>Welcome 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>
    )
};


【问题讨论】:

  • 您不能在客户端上使用 dotenv,因为它无法访问环境变量(通常它甚至不会在设置它们的同一台机器上运行)和它的 API uses (fs.readFileSync) 是 Node 的一部分,在浏览器中不可用。目前还不清楚您的应用程序是如何设置的,但如果您使用 Webpack,您可以使用 DefinePlugin 在构建时注入这些值,我在以下位置写过:github.com/textbook/starter-kit/wiki/…
  • dotenv 是一个 Node.js(服务器端)模块。您不能在浏览器中使用它。节点有fs(文件系统),浏览器没有。

标签: javascript reactjs dotenv


【解决方案1】:

如果您使用的是 create-react-app (CRA),则不需要 dotenv。

create-react-app 有一个很好的 guide 解释使用环境变量的多种方法(一种选择是使用根目录中的 .env 文件)。变量必须以REACT_APP_ 开头。

警告:不要使用任何机密作为环境变量(如 API 密钥)构建您的项目,您还将在指南中看到此警告。它们将暴露给任何访问您的 React 应用程序的人。

【讨论】:

    【解决方案2】:

    您必须在 webpack 配置中导入 dotenv,然后使用 DefinePlugin 将变量传递给您的 React 应用。

    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)
         })      
        ]
    };
    

    【讨论】:

    • OP 使用 Webpack 吗?
    • 是的,正确的。打包器作为 webpack
    【解决方案3】:

    @aLittleSalty 为您的案例提供了正确答案。您看到的错误是因为 dotenv 应该在节点服务器/后端中使用,并且浏览器无法访问文件系统。

    但是,如果您使用节点作为服务器/后端并且您偶然发现了这个问题,那么我的答案适用于您。

    .env 文件路径默认为path.resolve(process.cwd(), '.env')cwd 是当前工作目录:这意味着 dotenv 在运行代码的目录中查找文件。

    如果你想指定相对路径,这是你应该使用的:

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

    dotenv 文档:https://www.npmjs.com/package/dotenv#user-content-path

    【讨论】:

      猜你喜欢
      • 2017-07-06
      • 1970-01-01
      • 2019-04-24
      • 2018-06-05
      • 2019-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多