解决 Next.js 应用中环境变量配置的一些常见问题

在前端开发中,我们经常需要在应用程序中使用一些敏感的信息,如 API 密钥、数据库密码等等。为了不暴露这些敏感信息,我们通常会将它们配置成环境变量,并在应用程序中使用。在 Next.js 项目中,我们也可以使用环境变量来配置参数。然而,有时候在配置环境变量时,会碰到一些问题。本文将介绍 Next.js 应用中环境变量配置的一些常见问题和解决方法。

问题一:在客户端代码中访问环境变量

在 Next.js 中,我们可以使用 process.env 对象访问环境变量。但是,有时候我们在客户端代码中使用 process.env 时,其值是 undefined。这是因为 Next.js 在编译应用程序时会对环境变量进行静态分析,在构建时会将它们替换为变量的实际值。但是,在客户端代码中,这些变量的实际值却未定义。

例如,我们在开发阶段使用 .env.local 文件来配置环境变量,其中包含 MY_API_KEY 变量。在客户端代码中,我们使用 process.env.MY_API_KEY 来访问该变量的值。但是,我们会发现其值为 undefined

//pages/index.js
function HomePage() {
  console.log(process.env.MY_API_KEY); // 输出 undefined
  return <div>Welcome to Next.js!</div>;
}

export default HomePage;

这时候,我们需要在客户端代码中将环境变量注入到全局中。可以使用 next.config.js 配置文件中的 env 属性来定义环境变量的值,并在客户端代码中使用 __NEXT_DATA__.env 来获取它们。

// next.config.js
module.exports = {
  env: {
    MY_API_KEY: process.env.MY_API_KEY,
  },
};
// pages/index.js
import { useEffect } from 'react';

function HomePage() {
  useEffect(() => {
    console.log(__NEXT_DATA__.env.MY_API_KEY); // 输出 MY_API_KEY 的值
  }, []);

  return <div>Welcome to Next.js!</div>;
}

export default HomePage;

问题二:在服务器端代码中访问环境变量

在 Next.js 中,我们可以使用 process.env 对象来访问环境变量。但是,有时候我们在服务器端代码中使用 process.env 时,其值是 undefined。这是因为 Next.js 会在服务器端开启一个新的进程来运行应用程序,而该进程的环境变量并不是我们在命令行中设置的那些环境变量。

例如,我们在开发阶段使用 .env.local 文件来配置环境变量,其中包含 MY_DB_PASSWORD 变量。在服务器端代码中,我们使用 process.env.MY_DB_PASSWORD 来访问该变量的值。但是,在执行服务器端代码时,我们会发现其值为 undefined

// pages/api/users.js
export default function handler(req, res) {
  console.log(process.env.MY_DB_PASSWORD); // 输出 undefined
  res.status(200).json({ name: 'John Doe' });
}

这时候,我们需要在服务器端代码中读取环境变量,并将其注入到应用程序中。可以使用 next.config.js 配置文件中的 serverRuntimeConfigpublicRuntimeConfig 属性来定义需要注入的环境变量。

// next.config.js
module.exports = {
  serverRuntimeConfig: {
    MY_DB_PASSWORD: process.env.MY_DB_PASSWORD,
  },
  publicRuntimeConfig: {
    MY_API_KEY: process.env.MY_API_KEY,
  },
};
// pages/api/users.js
import getConfig from 'next/config';

export default function handler(req, res) {
  const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();
  console.log(serverRuntimeConfig.MY_DB_PASSWORD); // 输出 MY_DB_PASSWORD 的值
  console.log(publicRuntimeConfig.MY_API_KEY); // 输出 MY_API_KEY 的值
  res.status(200).json({ name: 'John Doe' });
}

问题三:在容器中运行 Next.js 应用程序

在容器中运行 Next.js 应用程序时,我们需要将环境变量传递给容器。但是,有时候我们发现容器中的应用程序无法访问环境变量。这是因为我们没有将环境变量传递给容器的操作系统。

例如,我们使用 Docker 容器来运行 Next.js 应用程序。我们使用 -e 参数将环境变量传递给容器,并使用 docker-compose.yml 文件定义容器。

version: '3.8'

services:
  app:
    build:
      context: .
    ports:
      - '3000:3000'
    environment:
      MY_API_KEY: 'secret-key'
FROM node:14-alpine

WORKDIR /app

COPY . .

RUN yarn install --production

CMD [ "npm", "start" ]
// pages/api/users.js
export default function handler(req, res) {
  console.log(process.env.MY_API_KEY); // 输出 undefined
  res.status(200).json({ name: 'John Doe' });
}

但是,我们会发现服务器端代码中访问环境变量时其值为 undefined。这是因为将环境变量传递给容器时,并没有将其传递给操作系统。我们需要在容器的启动命令中使用 --env 参数来将环境变量传递给操作系统。

version: '3.8'

services:
  app:
    build:
      context: .
    ports:
      - '3000:3000'
    environment:
      MY_API_KEY: 'secret-key'
    command: sh -c 'npm start -- --env MY_API_KEY=$MY_API_KEY'
FROM node:14-alpine

WORKDIR /app

COPY . .

RUN yarn install --production

CMD [ "npm", "start" ]
// pages/api/users.js
export default function handler(req, res) {
  console.log(process.env.MY_API_KEY); // 输出 secret-key
  res.status(200).json({ name: 'John Doe' });
}

总结

在 Next.js 中,我们可以使用环境变量来配置参数。在开发和部署应用程序时,我们可能会遇到一些与环境变量相关的问题。本文介绍了 Next.js 应用中环境变量配置的一些常见问题和解决方法,希望可以帮助到读者。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6594b1d3eb4cecbf2d8fca54


纠错反馈