【问题标题】:How to load environment variables in React如何在 React 中加载环境变量
【发布时间】:2019-07-24 01:56:07
【问题描述】:

我一直在尝试在 React 中加载环境变量,但我似乎无法弄清楚。我尝试了多种方法:

使用dotenv-webpack 包加载它们

webpack.config.dev.js

const merge = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const template = require('html-webpack-template');
const Dotenv = require('dotenv-webpack');
const baseConfig = require('./webpack.config.base');

module.exports = merge(baseConfig, {
  mode: 'production',
  plugins: [
    new HtmlWebpackPlugin({
      template,
      inject: false,
      appMountId: 'app',
      mobile: true,
      lang: 'es-ES',
      title: 'My App',
      meta: [
        {
          name: 'description',
          content: 'My App',
        },
      ],
    }),
    new Dotenv(),
  ],
});

.env

API_HOST=http://localhost:8000
REACT_APP_API_HOST=http://localhost:8000

直接在package.json 脚本上传递:

"start": "webpack-dev-server --config ./webpack.config.dev.js"

在 webpack 命令上使用 .env

webpack --env.API_HOST=http://localhost:8000

使用webpack.environmentPlugin

const webpack = require('webpack');
const merge = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const template = require('html-webpack-template');
const baseConfig = require('./webpack.config.base');

module.exports = merge(baseConfig, {
  mode: 'development',
  devtool: 'cheap-module-source-map',
  devServer: {
    publicPath: '/',
    contentBase: './dist',
    compress: true,
    stats: 'minimal',
    overlay: true,
    historyApiFallback: true,
    port: 8081,
    hot: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template,
      devServer: 'http://localhost:8081',
      inject: false,
      appMountId: 'app',
      mobile: true,
      lang: 'es-ES',
      title: 'My App',
      meta: [
        {
          name: 'description',
          content: 'React template.',
        },
      ],
    }),
    new webpack.EnvironmentPlugin({
      API_HOST: 'http://localhost:8000',
    }),
  ],
});

这些方法都不起作用,当我尝试在我的 React 代码中访问 process.env 变量时,我得到 undefined 关于我可能做错了什么的任何想法?

【问题讨论】:

    标签: reactjs webpack


    【解决方案1】:

    当我想为 Firebase 项目提供设置但不将它们加载到公共存储库中时,我自己一直在与环境变量作斗争。

    据我所知,您需要命名的环境变量应始终以前缀 REACT_APP_ 开头。你可以在任何你喜欢的地方定义它们,但是如果你使用 create-react-app 工具创建你的应用程序,那么你可以将你的变量放在 .env 文件或其他一些文件中 - (https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables)

    当我想制作自己的文件时,我的痛苦就开始了,因为我有两个不同的 Firebase 项目——一个用于暂存,一个用于生产。

    我最终使用了 react-app-env 模块,它有助于: - 定义我自己的文件 - staging.env 和 production.env - 使用 REACT_APP_ 自动为我的变量添加前缀

    例如:

    我在 staging.env 文件中定义了 Firebase ApiKey: API_KEY=xxxxxxxxxxxxxxxxxxxxx

    当我在我的 firebase.js 文件中使用它时,我将它用作:

    const config = {
        apiKey: process.env.REACT_APP_API_KEY,
    }
    

    为了确保针对暂存环境(Firebase 项目)进行开发,我将 package.json 更改为:

    "scripts": {
        "start": "react-app-env --env-file=staging.env start",
      },
    

    希望有帮助!

    【讨论】:

    • 为了将来参考,react-app-env 已被弃用,但可以使用env-cmd 包实现相同的结果,如this stackoverflow 响应中所述。
    • 无论是谁做出这个决定,强行加前缀REACT_APP_都需要认真质疑他们的技术能力。我会简单地添加一个机制来只读取定义的变量,而不是添加前缀
    【解决方案2】:

    您需要正确指定 webpack 配置文件。您将需要为 dev 创建一个单独的配置。 (webpack.config.dev.js)

    此处为示例。

    scripts: {
        "dev": "webpack --env.API_HOST=http://localhost:8000 --config webpack.config.dev.js"
    }
    

    另外,你需要使用 Webpack.DefinePlugin。

    plugins: [
      ...
      new webpack.DefinePlugin({ `process.env.API_HOST`: JSON.stringify(${env.API_HOST}) })
    ]
    

    或者你可以使用reduce来使其更全面。

      const envKeys = Object.keys(env).reduce((prev, next) => {
        prev[`process.env.${next}`] = JSON.stringify(env[next]);
        return prev;
      }, {});
    
      return {
        plugins: [
          ...
          new webpack.DefinePlugin(envKeys)
        ]
      };
    

    【讨论】:

    • 是的。每个环境我都有一个 webpack 文件
    • 我更新了我的答案。你需要使用 Webpack.DefinePlugin。
    • 是的,我忘了提到我也已经尝试过了。环境插件和定义插件。似乎没有一个工作:(
    【解决方案3】:

    同意@Philip 的回答,这就是我构建dev.config.js 的方式

      ...
      plugins: [
        new webpack.DefinePlugin({
          // process.env
          'process.env': {
            NODE_ENV: JSON.stringify(process.env.NODE_ENV),
            WHY_DID_YOU_UPDATE: process.env.WHY_DID_YOU_UPDATE,
          },
          // my other global flags
          __CLIENT__: true,
          __SERVER__: false,
          __DEVELOPMENT__: true,
          __DEVTOOLS__: true
        }),
      ]
    

    我也使用better-npm-run来管理我的package.json,在这里你可以轻松管理env变量

      "betterScripts": {
        "dev": {
          "command": "concurrently --kill-others \"better-npm-run watch-client\" \"better-npm-run start-dev\" \"gulp watch --gulpfile semantic/gulpfile.js\""
        },
        "why-did-you-update": {
          "command": "better-npm-run dev",
          "env": {
            "WHY_DID_YOU_UPDATE": true
          }
        },
        "watch-client": {
          "command": "node webpack/webpack-dev-server.js",
          "env": {
            "UV_THREADPOOL_SIZE": 100,
            "NODE_ENV": "development",
            "NODE_PATH": "./src",
            "PORT": 3000
          }
        },
        "build": {
          "command": "webpack --verbose --colors --display-error-details --config webpack/prod.config.js"
        }
      },
    

    希望这些信息也对您有所帮助!

    【讨论】:

      【解决方案4】:

      我为此找到了一个简单的解决方案。您需要安装'dotenv-webpack',然后将此配置添加到您的 webpack 配置中:

      const Dotenv = require('dotenv-webpack');
      
      ...
        plugins: [
          new Dotenv(),
        ],
      ...
      

      .env

      DB_HOST=127.0.0.1
      DB_PASS=foobar
      S3_API=mysecretkey
      

      最后你可以在你的应用中访问你的环境变量

      console.log(process.env.DB_PASS);
      

      来自文档:DB_HOST 和 S3_API 的 .env 值不存在于我们的包中,因为它们从未在代码中被引用(作为 process.env.[VAR_NAME])。 希望对您有所帮助!

      【讨论】:

        【解决方案5】:

        您可以在package.json 脚本部分指定环境变量:

        {
          ...
          "scripts": {
            "start": NODE_ENV=development webpack-dev-server
          },
          ...
        }
        

        【讨论】:

          猜你喜欢
          • 2021-09-29
          • 2019-04-19
          • 2020-01-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-30
          • 2013-02-28
          相关资源
          最近更新 更多