盖茨比:环境变量 .env return 未定义
Gatsby: Environment variables .env return undefined
我正在开发一个静态网站,使用 Gatsby 进行开发,使用 Nginx 提供静态文件。
我还在使用 Docker 进行测试和生产部署,并使用 Traefik 将流量路由到 docker 应用程序的容器。
我在应用程序文件中定义了一个环境变量,该环境变量是从应用程序根文件夹中的 .env
文件调用的。
但是,当在应用程序中调用该环境变量时,它会抛出错误:
undefined
代码如下:
Docker文件
# Set base image
FROM node:latest AS builder
# Set working directory
WORKDIR /app
# Copy package.json and install packages
COPY package.json .
RUN npm install
# Copy other project files and build
COPY . ./
RUN npm run build
# Set nginx image
FROM nginx:latest
# Nginx config
RUN rm -rf /etc/nginx/conf.d/default.conf
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
# Static build
COPY --from=builder /app/public /usr/share/nginx/html
# Set working directory
WORKDIR /usr/share/nginx/html
# Start Nginx server
CMD ["/bin/bash", "-c", "nginx -g \"daemon off;\""]
.env
GATSBY_API_URL=https://myapi.mywebsite.com
docker-compose.yml
version: "3"
services:
web:
image: my-website
build:
context: .
dockerfile: Dockerfile
environment:
GATSBY_API_URL: ${GATSBY_API_URL}
expose:
- "80"
labels:
- traefik.enable=true
- traefik.http.routers.my-website.rule=Host(`my-website.com`)
restart: always
volumes:
- .:/app
networks:
default:
external:
name: traefik-proxy
index.js
const onSubmit = async (values) => {
try {
const res = await axios.post(`${process.env.GATSBY_API_URL}/api/EmployeeDetail/verify`, values)
// console.log(res, 'verify endpoint');
if( res.data.requestSuccessful === true ) {
dispatchVerifyData({
type : 'UPDATE_VERIFY_DATA',
verifyData: {
res: res.data.responseData,
loanType: values.loanType
}
})
handleNext()
} else {
setIsSuccessful({
status: false,
message: res.data.message
})
}
} catch (error) {
//error state Unsuccessful
console.log(error, 'error')
setIsSuccessful({
status: false,
})
}
}
.docker忽略
node_modules
npm-debug.log
.DS_Store
.bin
.git
.gitignore
.bundleignore
.bundle
.byebug_history
.rspec
tmp
log
test
config/deploy
public/packs
public/packs-test
yarn-error.log
coverage/
.env
.env.production
Nginx default.conf
server {
listen 80;
add_header Cache-Control no-cache;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
我似乎仍然无法判断导致应用程序在调用环境变量时 return 一个 未定义错误 的问题的原因是什么。我们将不胜感激任何形式的帮助。
经过与同事长时间的调试,我终于想通了。
这是我学到的一些东西:
首先,Gatsby默认支持2种环境:
- 发展。如果你运行
gatsby develop
,那么你将处于development
环境
- 产量。如果你 运行
gatsby build
或 gatsby serve
,那么你将在 production
环境中。
但是,如果您注意到我们 运行ning npm run build
在我们的 Dockerfile
中相当于 gatsby build
,所以这会通知应用程序我们是 运行宁在production
。环境。
其次,为客户端定义环境变量JavaScript
对于您想要在客户端浏览器中访问的项目环境变量 JavaScript,您可以定义一个环境配置文件,.env.development
and/or .env.production
,在你的根文件夹。根据您的活动环境,将找到正确的环境并将其值作为环境变量嵌入到浏览器中 JavaScript。
换句话说,我们需要将我们的环境配置文件从 .env
重命名为 .env.production
以允许 Gatsby 应用程序在我们的 production
环境中识别它。
三、使用前缀定义环境变量
除了 .env.*
文件中定义的这些项目环境变量外,您还可以定义 OS 环境变量。 OS 以 GATSBY_
为前缀的环境变量将在浏览器 JavaScript.
中可用
如果您注意到得很好,我们已经在 .env
配置文件中将其定义为 - GATSBY_API_URL=https://myapi.mywebsite.com
,因此我们对此没有任何问题。
第四,去除环境。来自 .dockerignore
的配置文件
如果我们清楚地观察客户端 Javascript 的环境变量值是如何嵌入到浏览器中的 JavaScript,您会发现它是在构建时完成的,而不是 运行时间。
因此,我们需要从 .dockerignore
中删除 .env.*
配置文件,并删除 docker-compose.yml
文件中的 environment
选项,因为它不再是必需的,因为我们没有在 运行 时间内嵌入环境变量的值。
所以我们的代码现在看起来像这样:
Dockerfile
# Set base image
FROM node:latest AS builder
# Set working directory
WORKDIR /app
# Copy package.json and install packages
COPY package.json .
RUN npm install
# Copy other project files and build
COPY . ./
RUN npm run build
# Set nginx image
FROM nginx:latest
# Nginx config
RUN rm -rf /etc/nginx/conf.d/default.conf
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
# Static build
COPY --from=builder /app/public /usr/share/nginx/html
# Set working directory
WORKDIR /usr/share/nginx/html
# Start Nginx server
CMD ["/bin/bash", "-c", "nginx -g \"daemon off;\""]
.env.production
GATSBY_API_URL=https://myapi.mywebsite.com
docker-compose.yml
version: "3"
services:
web:
image: my-website
build:
context: .
dockerfile: Dockerfile
expose:
- "80"
labels:
- traefik.enable=true
- traefik.http.routers.my-website.rule=Host(`my-website.com`)
restart: always
volumes:
- .:/app
networks:
default:
external:
name: traefik-proxy
index.js
const onSubmit = async (values) => {
try {
const res = await axios.post(`${process.env.GATSBY_API_URL}/api/EmployeeDetail/verify`, values)
// console.log(res, 'verify endpoint');
if( res.data.requestSuccessful === true ) {
dispatchVerifyData({
type : 'UPDATE_VERIFY_DATA',
verifyData: {
res: res.data.responseData,
loanType: values.loanType
}
})
handleNext()
} else {
setIsSuccessful({
status: false,
message: res.data.message
})
}
} catch (error) {
//error state Unsuccessful
console.log(error, 'error')
setIsSuccessful({
status: false,
})
}
}
.docker忽略
node_modules
npm-debug.log
.DS_Store
.bin
.git
.gitignore
.bundleignore
.bundle
.byebug_history
.rspec
tmp
log
test
config/deploy
public/packs
public/packs-test
yarn-error.log
coverage/
Nginx default.conf
server {
listen 80;
add_header Cache-Control no-cache;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
就这些了。
希望对您有所帮助
我正在开发一个静态网站,使用 Gatsby 进行开发,使用 Nginx 提供静态文件。
我还在使用 Docker 进行测试和生产部署,并使用 Traefik 将流量路由到 docker 应用程序的容器。
我在应用程序文件中定义了一个环境变量,该环境变量是从应用程序根文件夹中的 .env
文件调用的。
但是,当在应用程序中调用该环境变量时,它会抛出错误:
undefined
代码如下:
Docker文件
# Set base image
FROM node:latest AS builder
# Set working directory
WORKDIR /app
# Copy package.json and install packages
COPY package.json .
RUN npm install
# Copy other project files and build
COPY . ./
RUN npm run build
# Set nginx image
FROM nginx:latest
# Nginx config
RUN rm -rf /etc/nginx/conf.d/default.conf
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
# Static build
COPY --from=builder /app/public /usr/share/nginx/html
# Set working directory
WORKDIR /usr/share/nginx/html
# Start Nginx server
CMD ["/bin/bash", "-c", "nginx -g \"daemon off;\""]
.env
GATSBY_API_URL=https://myapi.mywebsite.com
docker-compose.yml
version: "3"
services:
web:
image: my-website
build:
context: .
dockerfile: Dockerfile
environment:
GATSBY_API_URL: ${GATSBY_API_URL}
expose:
- "80"
labels:
- traefik.enable=true
- traefik.http.routers.my-website.rule=Host(`my-website.com`)
restart: always
volumes:
- .:/app
networks:
default:
external:
name: traefik-proxy
index.js
const onSubmit = async (values) => {
try {
const res = await axios.post(`${process.env.GATSBY_API_URL}/api/EmployeeDetail/verify`, values)
// console.log(res, 'verify endpoint');
if( res.data.requestSuccessful === true ) {
dispatchVerifyData({
type : 'UPDATE_VERIFY_DATA',
verifyData: {
res: res.data.responseData,
loanType: values.loanType
}
})
handleNext()
} else {
setIsSuccessful({
status: false,
message: res.data.message
})
}
} catch (error) {
//error state Unsuccessful
console.log(error, 'error')
setIsSuccessful({
status: false,
})
}
}
.docker忽略
node_modules
npm-debug.log
.DS_Store
.bin
.git
.gitignore
.bundleignore
.bundle
.byebug_history
.rspec
tmp
log
test
config/deploy
public/packs
public/packs-test
yarn-error.log
coverage/
.env
.env.production
Nginx default.conf
server {
listen 80;
add_header Cache-Control no-cache;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
我似乎仍然无法判断导致应用程序在调用环境变量时 return 一个 未定义错误 的问题的原因是什么。我们将不胜感激任何形式的帮助。
经过与同事长时间的调试,我终于想通了。
这是我学到的一些东西:
首先,Gatsby默认支持2种环境:
- 发展。如果你运行
gatsby develop
,那么你将处于development
环境 - 产量。如果你 运行
gatsby build
或gatsby serve
,那么你将在production
环境中。
但是,如果您注意到我们 运行ning npm run build
在我们的 Dockerfile
中相当于 gatsby build
,所以这会通知应用程序我们是 运行宁在production
。环境。
其次,为客户端定义环境变量JavaScript
对于您想要在客户端浏览器中访问的项目环境变量 JavaScript,您可以定义一个环境配置文件,.env.development
and/or .env.production
,在你的根文件夹。根据您的活动环境,将找到正确的环境并将其值作为环境变量嵌入到浏览器中 JavaScript。
换句话说,我们需要将我们的环境配置文件从 .env
重命名为 .env.production
以允许 Gatsby 应用程序在我们的 production
环境中识别它。
三、使用前缀定义环境变量
除了 .env.*
文件中定义的这些项目环境变量外,您还可以定义 OS 环境变量。 OS 以 GATSBY_
为前缀的环境变量将在浏览器 JavaScript.
如果您注意到得很好,我们已经在 .env
配置文件中将其定义为 - GATSBY_API_URL=https://myapi.mywebsite.com
,因此我们对此没有任何问题。
第四,去除环境。来自 .dockerignore
的配置文件如果我们清楚地观察客户端 Javascript 的环境变量值是如何嵌入到浏览器中的 JavaScript,您会发现它是在构建时完成的,而不是 运行时间。
因此,我们需要从 .dockerignore
中删除 .env.*
配置文件,并删除 docker-compose.yml
文件中的 environment
选项,因为它不再是必需的,因为我们没有在 运行 时间内嵌入环境变量的值。
所以我们的代码现在看起来像这样:
Dockerfile
# Set base image
FROM node:latest AS builder
# Set working directory
WORKDIR /app
# Copy package.json and install packages
COPY package.json .
RUN npm install
# Copy other project files and build
COPY . ./
RUN npm run build
# Set nginx image
FROM nginx:latest
# Nginx config
RUN rm -rf /etc/nginx/conf.d/default.conf
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
# Static build
COPY --from=builder /app/public /usr/share/nginx/html
# Set working directory
WORKDIR /usr/share/nginx/html
# Start Nginx server
CMD ["/bin/bash", "-c", "nginx -g \"daemon off;\""]
.env.production
GATSBY_API_URL=https://myapi.mywebsite.com
docker-compose.yml
version: "3"
services:
web:
image: my-website
build:
context: .
dockerfile: Dockerfile
expose:
- "80"
labels:
- traefik.enable=true
- traefik.http.routers.my-website.rule=Host(`my-website.com`)
restart: always
volumes:
- .:/app
networks:
default:
external:
name: traefik-proxy
index.js
const onSubmit = async (values) => {
try {
const res = await axios.post(`${process.env.GATSBY_API_URL}/api/EmployeeDetail/verify`, values)
// console.log(res, 'verify endpoint');
if( res.data.requestSuccessful === true ) {
dispatchVerifyData({
type : 'UPDATE_VERIFY_DATA',
verifyData: {
res: res.data.responseData,
loanType: values.loanType
}
})
handleNext()
} else {
setIsSuccessful({
status: false,
message: res.data.message
})
}
} catch (error) {
//error state Unsuccessful
console.log(error, 'error')
setIsSuccessful({
status: false,
})
}
}
.docker忽略
node_modules
npm-debug.log
.DS_Store
.bin
.git
.gitignore
.bundleignore
.bundle
.byebug_history
.rspec
tmp
log
test
config/deploy
public/packs
public/packs-test
yarn-error.log
coverage/
Nginx default.conf
server {
listen 80;
add_header Cache-Control no-cache;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
expires -1;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
就这些了。
希望对您有所帮助