Next.js 将 NODE_ENV 传递给客户端
Posted
技术标签:
【中文标题】Next.js 将 NODE_ENV 传递给客户端【英文标题】:Next.js pass NODE_ENV to client 【发布时间】:2019-04-15 10:45:59 【问题描述】:我正在使用 Next.js 构建一个 React s-s-r 应用程序。
我希望能够在客户端访问 NODE_ENV,因为这将告诉我的应用使用哪些 API 端点。
我正在努力为此寻找合适的方法。当我第一次在服务器上呈现页面时,我想将 NODE_ENV 定义为窗口变量,然后在我进行 API 调用的辅助函数中,我会检查代码是在服务器上还是在客户端上被调用,并根据需要使用window
或process.env
对象。
对于这样的问题,有人有好的解决方案吗?这一定是一个普遍的问题,但我找不到任何好的解决方案。
【问题讨论】:
Have you tried using theDefinePlugin
?
您可以将其包含到 window.__INITIAL_STATE__ = $JSON.stringify(initialState || );
【参考方案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 中的 s-s-r,则仍然需要 env 配置,如果您想将其传递给前端,您可以使用上述方式。否则,就像使用静态导出 NextJS 你不需要这个。以上是关于Next.js 将 NODE_ENV 传递给客户端的主要内容,如果未能解决你的问题,请参考以下文章
在页面加载时将道具传递给子组件 - 与 next.js 做出反应
如何将可拖动属性传递给 Next.js Image 组件中的 <img>?