【问题标题】:Next.js pass NODE_ENV to clientNext.js 将 NODE_ENV 传递给客户端
【发布时间】:2019-04-15 10:45:59
【问题描述】:

我正在使用 Next.js 构建一个 React SSR 应用程序。

我希望能够在客户端访问 NODE_ENV,因为这将告诉我的应用使用哪些 API 端点。

我正在努力为此寻找合适的方法。当我第一次在服务器上呈现页面时,我想将 NODE_ENV 定义为窗口变量,然后在我进行 API 调用的辅助函数中,我会检查代码是在服务器上还是在客户端上被调用,并根据需要使用windowprocess.env 对象。

对于这样的问题,有人有好的解决方案吗?这一定是一个普遍的问题,但我找不到任何好的解决方案。

【问题讨论】:

标签: javascript node.js reactjs environment-variables next.js


【解决方案1】:

从 Next.js 9.4 开始,NextJs 现在内置了对环境变量的支持,允许您使用 .env 文件执行以下操作:

.env.local 示例:

DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword

如果你想向客户端公开环境变量,你必须在变量前面加上NEXT_PUBLIC_,例如:

NEXT_PUBLIC_API_PORT=4000

如果要使用变量,可以这样使用:process.env.NEXT_PUBLIC_API_PORT

有关文档,请参阅here

【讨论】:

    【解决方案2】:

    另一个简单的解决方案:

    在根文件夹创建 2 个文件:

    .env.development
    .env.production
    

    根据需要在里面添加变量,例如在 .env.development 文件中:

    NEXT_PUBLIC_ENV="development"
    

    在 .env.production 文件中:

    NEXT_PUBLIC_ENV="production"
    

    然后用它举例:

    console.log('Version: ', process.env.NEXT_PUBLIC_ENV);
    

    【讨论】:

      【解决方案3】:

      使用 Next 的构建时配置

      @DarrylR 已经使用next.config.js 和 接下来是runtime configuration, 不过你也可以使用Next的build-time configuration

      这使您可以将process.env.XXXX 直接放入代码中(如下面的第 3 步所示),您无需导入任何内容。但是,如果您在使用Next.js 本地构建和部署到ZEIT Now 时都应设置环境变量,我不知道您是否可以使用此方法将它们保存在一个文件中(请参阅下面的步骤2) .

      运行时配置文档建议您通常要使用构建时配置:

      警告:通常您希望使用构建时配置来提供您的配置。原因是运行时配置增加了渲染/初始化开销并且automatic prerendering不兼容。


      步骤:

      1。为构建过程设置NODE_ENV

      1.1 使用ZEIT Now

      如果您使用 ZEIT Now 进行部署,您可以在now.json 中设置env variables used at build time

      {
        "version": 2,
        "build": {
          "env": {
            "NODE_ENV": "production"
          }
        }
      }
      

      1.2 本地运行时(可选)

      如果您希望在本地运行时也设置NODE_ENV,则now.json 不会设置。 但是您可以通过其他方式设置它,例如:

      $ NODE_ENV=production npm run build
      

      或者将package.json中的构建脚本改成

      "build": "NODE_ENV=production next build"
      

      如果您愿意,当然也可以为其他脚本设置NODE_ENV,而不是构建。

      2。使process.env.NODE_ENV 的下一个内联值

      将其添加到next.config.js,如here 所述:

      module.exports = {
        env: {
          NODE_ENV: process.env.NODE_ENV
        }
      };
      

      3。在代码中使用

      if (process.env.NODE_ENV === "production") {
        console.log("In production")
      } else {
        console.log("Not in production")
      }
      

      【讨论】:

      • 我尝试了这个解决方案,但在我的情况下,next.config.js 中不允许使用 NODE_ENV:github.com/zeit/next.js/blob/master/errors/…
      • 您忘记了实际答案。你只说如何使用变量,而不是如何设置它....
      • 在第 1 步和第 2 步中,我尝试解释如何设置它。你能解释一下它的哪一部分缺失或令人困惑吗? (实际上,不确定您是指我还是第一条评论。)
      【解决方案4】:

      1。您可以将其包含在 webpack 配置中(使用 dotenv-webpack 依赖项):

      require('dotenv').config()
      
      const path = require('path')
      const Dotenv = require('dotenv-webpack')
      
      module.exports = {
        webpack: (config) => {
          config.plugins = config.plugins || []
      
          config.plugins = [
            ...config.plugins,
      
            // Read the .env file
            new Dotenv({
              path: path.join(__dirname, '.env'),
              systemvars: true
            })
          ]
      
          return config
        }
      }

      参考:here


      2。使用 babel 插件将变量导入整个应用程序:

      env-config.js

      const prod = process.env.NODE_ENV === 'production'
      
      module.exports = {
        'process.env.BACKEND_URL': prod ? 'https://api.example.com' : 'https://localhost:8080'
      }
      

      .babelrc.js

      const env = require('./env-config.js')
      
      module.exports = {
        presets: ['next/babel'],
        plugins: [['transform-define', env]]
      }
      

      index.js

      export default () => (
        <div>Loading data from { process.env.BACKEND_URL }</div>
      )
      

      参考:here

      3。使用下一个/配置:

      next.config.js

      module.exports = {
        publicRuntimeConfig: {
          API_URL: process.env.API_URL
        }
      }
      

      index.js

      import React from 'react'
      import getConfig from 'next/config'
      
      const {publicRuntimeConfig} = getConfig()
      const {API_URL} = publicRuntimeConfig
      
      export default class extends React.Component {
        static async getInitialProps () {
          // fetch(`${API_URL}/some-path`)
          return {}
        }
      
        render () {
          return <div>
                  The API_URL is {API_URL}
          </div>
        }
      }
      

      参考:here

      【讨论】:

      • 谢谢,这是一个非常有帮助的答案!
      • 我认为最后一个是最好的解决方案,谢谢!
      • 最新的NextJS版本是否需要?
      • @SalahAdDin 这取决于您的系统设计。如果您将后端(例如:nodejs)和前端 NextJS 组合在一个项目中,或者使用 NextJS 中的 SSR,则仍然需要 env 配置,如果您想将其传递给前端,您可以使用上述方式。否则,就像使用静态导出 NextJS 你不需要这个。
      猜你喜欢
      • 2014-01-31
      • 1970-01-01
      • 1970-01-01
      • 2016-01-10
      • 2019-03-16
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多