如何从前端访问环境变量 [英] How to access environment variables from the front-end

查看:57
本文介绍了如何从前端访问环境变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编译脚本中定义了几个环境变量.但是,我只能从 webpack.config.babel.js 文件访问这个变量,我需要在 React 代码(前端)中访问这个变量.

I have defined several environment variables in the compilation script. But, I have only access to this variables only from webpack.config.babel.js file and I need to get access to this variables in react code (front-end).

我在这里找到了一种方法:https://blog.container-solutions.com/deploying-configurable-frontend-web-application-containers,但我认为将元标记数据(例如数据库密码)放入其中不是一个好主意.尽管如此,试图只为 .env 文件做这件事对我来说不起作用:(

I have found a way to do this here: https://blog.container-solutions.com/deploying-configurable-frontend-web-application-containers, but I don't think it would be a good idea to put in meta tags data like database passwords, for example. Despite of, trying to do only the way for .env file it doesn't work to me :(

那么,我的问题是如何从前端访问环境变量?

So, my question, is how can I get access to environment variables from the front-end?

编辑我:

我采纳了@robi932 的明智建议,但对我不起作用:(

I have applied the wise advice of @robi932 but it doesn't work to me :(

webpack.config.babel.js

webpack.config.babel.js

plugins: [
    new HtmlWebpackPlugin({
        template: "./src/client/index.html",    //where is our template
        filename: "../index.html",              //where we are going to put our index.html inside the output directory
        minify: {
            collapseWhitespace: true,
            removeComments: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true,
            useShortDoctype: true
        }            
    }),
    new MiniCssExtractPlugin({
        filename: "css/bundle.css",
        minify: {
            collapseWhitespace: true,
            removeComments: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true,
            useShortDoctype: true
        }             
    }),
    new webpack.DefinePlugin({
        URL_FEB_API: JSON.stringify(process.env.URL_FEB_API)
    })

我定义了 const URL_FEB_API 以便稍后在我的 react-js 代码中使用它,但是当我尝试访问它时,它不起作用:(

I define the const URL_FEB_API to use it later on my react-js code, but when I try to access to it, it doesn't work :(

console.log("HomeLF1Content process.env.URL_FEB_API: " + URL_FEB_API);

console.log("HomeLF1Content process.env.URL_FEB_API: " + process.env.URL_FEB_API);

这是我在 package.json 中的编译脚本:

This is my compiling scripts in package.json:

    "clean": "rm -rf ./dist",
    "compile-dev": "NODE_ENV=development URL_FEB_API=http://localhost:4000/api/feb/graphiql webpack -d --config ./webpack.config.babel.js --progress",
    "dev": "npm run clean && npm run compile-dev && cross-env NODE_ENV=development nodemon --exec babel-node src/server/server.js --ignore ./src/client"

我做错了什么?

解决方案:

感谢此链接 https://medium.com/@trekinbami/using-environment-variables-in-react-6b0a99d83cf5 由@Shubham Jain 提供,最后我找到了一个很好的解决方案来为前端定义环境变量.

Thanks to this link https://medium.com/@trekinbami/using-environment-variables-in-react-6b0a99d83cf5 give it by @Shubham Jain, finally I have found a good solution to define environment variables for the front-end.

然后,我将解释我为解决问题所遵循的步骤.

Then, I'm going to explain what have been the steps that I have followed to solve my problem.

首先,我们需要为每个环境创建两个 .env 文件.现在,我们有两个环境:开发和生产.因此,.env.development 将是我们要配置所有开发变量的文件,而 .env 将是我们要配置所有生产变量的文件.

First, we need two .env files for each environment. Now, we have two environments: development and production. So, .env.development will be the file where we are going to config all our development variables and .env will be the file where we are going to config all our production variables.

第二,要选择之前创建的文件之一,我们需要告诉node要编译哪个文件,所以在我们的编译脚本中我们必须定义一个我们正在调用的变量NODE_ENV,我们将在其中使用开发"或生产"进行初始化.

Second, to select one of those files created before, we need to say it to node which file to make the compilation, so in our compiling scripts we have to define a variable that we are calling NODE_ENV where we are going to initialize with "development" or "production".

开发脚本:

"clean": "rm -rf ./dist",
"compile-dev": "NODE_ENV=development webpack -d --config ./webpack.config.babel.js --progress",
"dev": "npm run clean && npm run compile-dev && cross-env NODE_ENV=development nodemon --exec babel-node src/server/server.js --ignore ./src/client",

生产脚本:

"clean": "rm -rf ./dist",
"compile": "NODE_ENV=production webpack -p --config ./webpack.config.babel.js --progress",
"start": "npm run clean && npm run compile && cross-env NODE_ENV=production babel-node src/server/server.js --ignore ./node_modules",

第三,现在,我们将在 webpack.config.babel.js 文件中添加一些代码,以根据 NODE_ENV 变量的值选择环境变量.

Third, now, we are going to ad some code to our webpack.config.babel.js file to select the environment variables depending of the value of NODE_ENV variable.

import webpack from "webpack";
import path from "path";
import dotenv from "dotenv";
import fs from "fs";
/**
 * Code to get the values of environment variables during compilation time for the front-end
 */
//Get the root path. Our .env files and webpack.config.babel.js files are in the root path
const currentPath = path.join(__dirname);
const basePath = currentPath + "/.env";
// We're concatenating the environment name to our filename to specify the correct env file!
const envPath = basePath + "." + process.env.NODE_ENV;
// Check if the file exists, otherwise fall back to the production .env
const finalPath = fs.existsSync(envPath) ? envPath : basePath;
// Set the path parameter in the dotenv config
const fileEnv = dotenv.config({ path: finalPath }).parsed;
// reduce it to a nice object, the same as before
const envKeys = Object.keys(fileEnv).reduce((prev, next) => {
  prev[`process.env.${next}`] = JSON.stringify(fileEnv[next]);
  return prev;
}, {});

第四,同样在webpack.config.babel.js文件中,在plugin部分,我们要在编译项目时添加对这个变量的访问:

Fourth, in webpack.config.babel.js file too, in the plugin section, we have to add the access to this variables when compiling the project:

plugins: [
    //With this entry we can get access to the environment variable for front-end
    new webpack.DefinePlugin(envKeys),
],

并且最后,为了在前端访问这些变量,我们可以使用 process.env.VARIABLE_NAME 轻松访问它们,其中 VARIABLE_NAME 是其中之一.env 或 .env.development 文件中定义的变量.

And finally, to get access to these variables in the front-end, we can access to them easily with process.env.VARIABLE_NAME where VARIABLE_NAME is one of the variables defined in the files .env or .env.development.

请投票给@Shubham Jain 的答案,因为他的链接对我非常有用.

Please, vote the answer give it by @Shubham Jain, because his link has been very useful to me.

推荐答案

有一个非常简单的方法:

There is a very simple way to to that:

第一步:转到应用程序的根文件夹并创建一个名为 .env 的文本文件.

Step one: Go to the root folder of your application and create a text file called .env.

第二步:在新文件中创建自定义变量.Create React App(CRA) 在每个自定义变量上强制使用前缀 REACT_APP.请注意,没有前缀的变量在打包时会被忽略.

Step two: Create your custom variables in the new file. Create React App(CRA) enforces the prefix REACT_APP on every custom variable. Please note that variables without the prefix are ignored during bundling.

REACT_APP_CLIENT_ID=jfjffffaddfeettgydgdffv
REACT_APP_KEY=aaddddawrfffvvvvssaa

第三步:将它们分配给变量,将它们打印到屏幕等,但它们在您的 Javascript 文件中是只读的.

Step three: Assign them to variables, print them to the screen etc, but they are read-only from your Javascript file.

console.log(process.env.REACT_APP_CLIENT_ID); 
console.log(process.env.REACT_APP_KEY);

第四步:有一个名为 NODE_ENV 的内置环境变量.您可以从 process.env.NODE_ENV 访问它.这个变量会根据你当前所处的模式而改变.当你运行 npm start 时,它等于 'development',当你运行 npm test 时它等于 'test',当你运行 npm run build 时它等于'生产'.此变量很特殊,因为它可用于根据您的模式访问不同的环境配置.例如,如果您的生产和开发有不同的数据库(通常是为了防止干扰),您可以使用它来有条件地访问某些变量.您无法手动覆盖 NODE_ENV 这一事实可防止开发人员意外将开发版本部署到生产环境中.

Step four: There is a built-in environment variable called NODE_ENV. You can access it from process.env.NODE_ENV. This variable changes based on what mode you are currently in. When you run npm start, it is equal to ‘development’, when you run npm test it is equal to ‘test’, and when you run npm run build it is equal to ‘production’. This variable is special as it can be used to access different environment configurations based on your mode. For example, if you have different databases for your production and development (usually to prevent interference) you can use it to conditionally access certain variables. The fact that you cannot override NODE_ENV manually prevents developers from accidentally deploying a development build to production.

第五步:打开 .gitignore 文件.我喜欢把 .env 和其他环境变量放在 #misc 下.

Step five: Open the .gitignore file. I like to put .env and other environment variables under #misc.

为什么在遵循这些流程后它仍然不起作用?

  • 确保在每个变量上都使用了前缀 REACT_APP

  • Make sure you used the prefix REACT_APP on every variable

确认 .env 文件中的变量名与您的 js 文件中的变量名匹配.例如,.env 中的 REACT_APP_KEY 与 process.env.REACT_APP_KY

Confirm that the variable names on the .env file match the ones on your js file. For example,REACT_APP_KEY in .env versus process.env.REACT_APP_KY

如果开发服务器正在运行,请停止它,然后使用 npm start it 重新运行.我真的很挣扎(变量是未定义的错误).每次更新 .env 文件时,都需要停止服务器并重新运行它,因为环境变量仅在构建期间更新(变量为未定义错误).

If the development server was running, stop it then rerun using npm start it. I really struggled with this (variable is undefined error). Every time you update the .env file, you need to stop the server and rerun it, as the environment variables are only updated during build (variable is undefined error).

从变量的值中删除引号.

Remove quotations from the values of the variables.

错误

REACT_APP_KEY="AHEHEHR"

对了

REACT_APP_KEY=AHEHEHR

注意:将敏感内容放入环境变量并不能使它们安全.它们在构建过程中被注入到捆绑文件中,因此任何人都可以通过检查您的文件来查看它们.我发现它们的最大用途是在将我的代码推送到远程存储库之前隐藏信息.

Note: Putting Sensitive content to environment variables doesn’t make them safe. They are injected into the bundled file during the build process so anyone can see them by inspecting your files. I have found their greatest use to be hiding the information before pushing my code to a remote repository.

这篇关于如何从前端访问环境变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆