在 Gatsby React 应用程序中插入环境变量客户端
Interpolate env vars client side in gatsby react app
我正在使用 Gatsby 作为静态站点生成器并使用 Netlify 进行部署。
Netlify 允许您在其 UI 后端设置环境变量。
我在 Netlify 后端设置了一些环境变量,以便能够 post 订阅邮件列表。
DATA_NO = 'XXXX'
LIST_ID = '123456'
API_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'
在我的 src 文件中,我有一个组件响应 onSubmit
事件并构建一个 URL 到 post 新订阅者。
(axios
作为发送HTTP请求等的包)
import React, { useState } from "react"
import axios from 'axios'
const Form = () => {
const [userEmail, setState] = useState({'email_address': ''})
const creds = 'anystring:'+ process.env.API_KEY
let URL = 'https://'+ process.env.DATA_NO +'.api.example.com/3.0'
URL += '/lists/'+ process.env.LIST_ID +'/members'
const submitSubscribe = async e => {
e.preventDefault()
const payload = {
'email_address': userEmail.email_address,
'status': 'subscribed'
}
try {
const response = await axios.post( URL , payload, {
headers: {
'Authorization': 'Basic ' + Buffer.from(creds ).toString('base64')
}
})
console.log('r', response)
console.log('r data', response.data)
} catch(err) {
console.log(err);
}
}
return (
<form name="newsletter-signup" method="post" onSubmit={submitSubscribe}>
{/*<input type="hidden" name="form-name" value="newsletter-signup" />*/}
<input type="email" placeholder="Email required" onChange={handleChange} value={userEmail.email_address} required />
<button type="submit" className="button primary-button-inverted">Send'</button>
</form>
)
}
所以,发生的事情是在 运行 时间,我的 env vars
出现了 undefined
。
我一直在看 Netlify 文档,他们一直说您需要 插入 客户端的值才能使用它们。我明白这里的逻辑。这些环境变量需要在构建时打印和捆绑,而不是在 运行 时间调用。
我遇到的问题是我该如何?
我已经在项目的根目录中设置了一个 .env.development
文件。我试过用 GATSBY_
作为我的环境变量的前缀,但我仍然遇到同样的问题。
我尝试使用 require('dotenv').config()
,但我不确定 将 准确地放置在何处(在我的 gatsby-node.js
、gatsby-config.js
中)或我是否需要在页面上包含使用这些环境变量的组件?
我希望能够在一个地方设置这些变量(如果在开发中测试的话可能是两个)但是我不想为了能够在开发和生产构建中使用它们而进行太多调整.
我也知道 Netlify 或 Gatsby 可以将这些变量处理到我的源代码中的 functions/
文件夹中,我可以以某种方式利用它,但这似乎比我需要的更多 post一个简单的表格。
请帮忙!
更新
当前代码:
在我的项目根目录中,我创建了两个 .env
文件,一个用于开发,一个用于生产。它们各自共享以下格式(请记住,我正在使用 GatsbyJS 进行开发):
GATSBY_MC_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxx-xxxx"
GATSBY_MC_DATA_NO="xxxx"
GATSBY_MC_AUDIENCE_ID="xxxxxxxxxxx"
我在 src/config/config.js
中设置了一个单独的 config.js
文件来组织和验证我的 env vars
(感谢@Baboo_)。看起来像:
export const MC_API_KEY = process.env.GATSBY_MC_API_KEY;
export const MC_DATA_NO = process.env.GATSBY_MC_DATA_NO;
export const MC_AUDIENCE_ID = process.env.GATSBY_MC_AUDIENCE_ID;
const envVars = [
{name: "MC_API_KEY", value: MC_API_KEY},
{name: "MC_DATA_NO", value: MC_DATA_NO},
{name: "MC_AUDIENCE_ID", value: MC_AUDIENCE_ID}
]
export const checkEnvVars = () => {
const envVarsNotLoaded = envVars.filter((envVar) => envVar.value !== undefined);
if (envVarsNotLoaded.length > 0) {
throw new Error(`Could not load env vars ${envVarsNotLoaded.join(",")}`);
}
}
checkEnvVars()
但是,当我 运行 gatsby develop
时,会抛出 "Could not load env vars" 错误。
你做得对。
你所要做的确实是在你的环境变量前加上GATSBY_
,Gatsby 会自动加载它们。然后在您的代码中调用它们:
const creds = 'anystring:'+ process.env.GATSBY_API_KEY
let URL = 'https://'+ process.env.GATSBY_DATA_NO +'.api.example.com/3.0'
tURL += '/lists/'+ process.env.GATSBY_LIST_ID +'/members'
确保使用整个字符串 process.env.GATSBY_LIST_ID
而不是 process.env[GATSBY_LIST_ID]
因为对象 process.env
是 undefined
.
本地
确保创建 .env
个文件,.env.development
和 .env.production
。前者用于 运行 gatsby develop
后者用于 运行 gatsby build
.
您可能已经知道不应该提交这些文件。
Netlify
在 Netlify 上的部署管道中添加相同的环境变量。这里是related doc。这样 Netlify 就可以在部署时构建您的网站。
改进
不是直接引用环境变量,而是在加载它们的地方创建一个文件,如果无法检索其中一个,则抛出错误。这样当加载失败时你会被注意到并节省调试时间。
示例:
// config.js
export const API_KEY = process.env.GATSBY_API_KEY;
export const DATA_NO = process.env.GATSBY_DATA_NO ;
const envVars = [
{name: "API_KEY", value: API_KEY},
{name: "DATA_NO", value: DATA_NO},
]
const checkEnvVars = () => {
const envVarsNotLoaded = envVars.filter(isUndefined);
if (envVarsNotLoaded.length > 0) {
throw new Error(`Could not load env vars ${envVarsNotLoaded.join(",")}`);
}
}
const isUndefined = (envVar) => typeof envVar.value === "undefined";
// component.js
import React, { useState } from "react"
import axios from 'axios'
// Import environment variables
import { API_KEY, DATA_NO } from "./config"
const Form = () => {
// ...
const [userEmail, setState] = useState({'email_address': ''})
const creds = 'anystring:'+ API_KEY
let URL = 'https://'+ DATA_NO +'.api.example.com/3.0'
我正在使用 Gatsby 作为静态站点生成器并使用 Netlify 进行部署。
Netlify 允许您在其 UI 后端设置环境变量。
我在 Netlify 后端设置了一些环境变量,以便能够 post 订阅邮件列表。
DATA_NO = 'XXXX'
LIST_ID = '123456'
API_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXX'
在我的 src 文件中,我有一个组件响应 onSubmit
事件并构建一个 URL 到 post 新订阅者。
(axios
作为发送HTTP请求等的包)
import React, { useState } from "react"
import axios from 'axios'
const Form = () => {
const [userEmail, setState] = useState({'email_address': ''})
const creds = 'anystring:'+ process.env.API_KEY
let URL = 'https://'+ process.env.DATA_NO +'.api.example.com/3.0'
URL += '/lists/'+ process.env.LIST_ID +'/members'
const submitSubscribe = async e => {
e.preventDefault()
const payload = {
'email_address': userEmail.email_address,
'status': 'subscribed'
}
try {
const response = await axios.post( URL , payload, {
headers: {
'Authorization': 'Basic ' + Buffer.from(creds ).toString('base64')
}
})
console.log('r', response)
console.log('r data', response.data)
} catch(err) {
console.log(err);
}
}
return (
<form name="newsletter-signup" method="post" onSubmit={submitSubscribe}>
{/*<input type="hidden" name="form-name" value="newsletter-signup" />*/}
<input type="email" placeholder="Email required" onChange={handleChange} value={userEmail.email_address} required />
<button type="submit" className="button primary-button-inverted">Send'</button>
</form>
)
}
所以,发生的事情是在 运行 时间,我的 env vars
出现了 undefined
。
我一直在看 Netlify 文档,他们一直说您需要 插入 客户端的值才能使用它们。我明白这里的逻辑。这些环境变量需要在构建时打印和捆绑,而不是在 运行 时间调用。
我遇到的问题是我该如何?
我已经在项目的根目录中设置了一个 .env.development
文件。我试过用 GATSBY_
作为我的环境变量的前缀,但我仍然遇到同样的问题。
我尝试使用 require('dotenv').config()
,但我不确定 将 准确地放置在何处(在我的 gatsby-node.js
、gatsby-config.js
中)或我是否需要在页面上包含使用这些环境变量的组件?
我希望能够在一个地方设置这些变量(如果在开发中测试的话可能是两个)但是我不想为了能够在开发和生产构建中使用它们而进行太多调整.
我也知道 Netlify 或 Gatsby 可以将这些变量处理到我的源代码中的 functions/
文件夹中,我可以以某种方式利用它,但这似乎比我需要的更多 post一个简单的表格。
请帮忙!
更新
当前代码:
在我的项目根目录中,我创建了两个 .env
文件,一个用于开发,一个用于生产。它们各自共享以下格式(请记住,我正在使用 GatsbyJS 进行开发):
GATSBY_MC_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxx-xxxx"
GATSBY_MC_DATA_NO="xxxx"
GATSBY_MC_AUDIENCE_ID="xxxxxxxxxxx"
我在 src/config/config.js
中设置了一个单独的 config.js
文件来组织和验证我的 env vars
(感谢@Baboo_)。看起来像:
export const MC_API_KEY = process.env.GATSBY_MC_API_KEY;
export const MC_DATA_NO = process.env.GATSBY_MC_DATA_NO;
export const MC_AUDIENCE_ID = process.env.GATSBY_MC_AUDIENCE_ID;
const envVars = [
{name: "MC_API_KEY", value: MC_API_KEY},
{name: "MC_DATA_NO", value: MC_DATA_NO},
{name: "MC_AUDIENCE_ID", value: MC_AUDIENCE_ID}
]
export const checkEnvVars = () => {
const envVarsNotLoaded = envVars.filter((envVar) => envVar.value !== undefined);
if (envVarsNotLoaded.length > 0) {
throw new Error(`Could not load env vars ${envVarsNotLoaded.join(",")}`);
}
}
checkEnvVars()
但是,当我 运行 gatsby develop
时,会抛出 "Could not load env vars" 错误。
你做得对。
你所要做的确实是在你的环境变量前加上GATSBY_
,Gatsby 会自动加载它们。然后在您的代码中调用它们:
const creds = 'anystring:'+ process.env.GATSBY_API_KEY
let URL = 'https://'+ process.env.GATSBY_DATA_NO +'.api.example.com/3.0'
tURL += '/lists/'+ process.env.GATSBY_LIST_ID +'/members'
确保使用整个字符串 process.env.GATSBY_LIST_ID
而不是 process.env[GATSBY_LIST_ID]
因为对象 process.env
是 undefined
.
本地
确保创建 .env
个文件,.env.development
和 .env.production
。前者用于 运行 gatsby develop
后者用于 运行 gatsby build
.
您可能已经知道不应该提交这些文件。
Netlify
在 Netlify 上的部署管道中添加相同的环境变量。这里是related doc。这样 Netlify 就可以在部署时构建您的网站。
改进
不是直接引用环境变量,而是在加载它们的地方创建一个文件,如果无法检索其中一个,则抛出错误。这样当加载失败时你会被注意到并节省调试时间。
示例:
// config.js
export const API_KEY = process.env.GATSBY_API_KEY;
export const DATA_NO = process.env.GATSBY_DATA_NO ;
const envVars = [
{name: "API_KEY", value: API_KEY},
{name: "DATA_NO", value: DATA_NO},
]
const checkEnvVars = () => {
const envVarsNotLoaded = envVars.filter(isUndefined);
if (envVarsNotLoaded.length > 0) {
throw new Error(`Could not load env vars ${envVarsNotLoaded.join(",")}`);
}
}
const isUndefined = (envVar) => typeof envVar.value === "undefined";
// component.js
import React, { useState } from "react"
import axios from 'axios'
// Import environment variables
import { API_KEY, DATA_NO } from "./config"
const Form = () => {
// ...
const [userEmail, setState] = useState({'email_address': ''})
const creds = 'anystring:'+ API_KEY
let URL = 'https://'+ DATA_NO +'.api.example.com/3.0'