我正在使用一个带有next.config.js
文件的应用程序,该文件会根据环境变量设置一堆配置变量,以在应用程序的其他位置使用。我想根据URL向此列表添加更多内容,我正在使用软件包jekrb/next-absolute-url
来读取URL。
我在示例const { origin } = absoluteUrl(req)
中遇到了问题,但无法在next.config.js
文件中使用它。它只是告诉我req
没有定义。
这是我当前的next.config.js
文件的精简示例。
const withTM = require('next-transpile-modules');
const withCSS = require('@zeit/next-css');
const withFonts = require('next-fonts');
const withImages = require('next-images');
const withOffline = require('next-offline');
const compose = require('crocks/helpers/compose');
const absoluteUrl = require('next-absolute-url');
const { origin } = absoluteUrl(req);
require('dotenv').config();
const injectedConfig = {
serverRuntimeConfig: {
KEY: process.env.VALUE,
},
publicRuntimeConfig: {
KEY: process.env.VALUE,
},
}
module.exports = compose(
withCSS,
withFonts,
withImages,
withTM,
withOffline
)(injectedConfig);
答案 0 :(得分:0)
由于该“ req” 对象实际上是客户请求,因此无法正常工作,这意味着它仅在运行时上有效。 next.config.js
在配置时运行,因此在那里不可用。
您可以使用常规的env变量或.env
文件并用dotenv加载它
答案 1 :(得分:0)
我认为可以使用自定义文档来实现:
import Document, { Html, Head, Main, NextScript } from "next/document";
class MyDocument extends Document {
static async getInitialProps(ctx) {
const { pathname, query } = ctx;
// having pathname and query, read config from elsewhere
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps, config: { pathname, query } };
}
render() {
return (
<Html>
<Head>
<script
id="config"
dangerouslySetInnerHTML={{
__html: JSON.stringify(this.props.config, null, 1)
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
在Document#getInitalProps
中,您可以获得当前的pathname
并从某个地方读取相应的配置,然后将该配置呈现在<script>
内部。虽然看起来有点黑。
此外,还需要自定义_app
才能从<script>
标记读取配置。在_app
中,您可以使用配置填充React上下文,以便能够在其他组件中方便地使用它。
UPD
这里是如何使用<script>
标记中的内容:创建一个自定义应用程序组件,在componentDidMount
中获取该元素并解析其中的数据,然后将其用作上下文值。 / p>
import App from "next/app";
import React from "react";
export const ConfigContext = React.createContext({});
export default class MyApp extends App {
constructor() {
super();
this.state = { config: {} };
}
componentDidMount() {
const config = JSON.parse(document.getElementById("config").textContent);
this.setState({ config });
}
render() {
const { Component, pageProps } = this.props;
return (
<ConfigContext.Provider value={this.state.config}>
<Component {...pageProps} />
</ConfigContext.Provider>
);
}
}
在页面组件中,您可以从上下文中读取它:
import React, { useContext } from "react";
import { ConfigContext } from "./_app";
export default props => {
const config = useContext(ConfigContext);
return (
<div>
<pre>{JSON.stringify(config, null, 1)}</pre>
</div>
);
};
同样,此问题似乎是一种解决方案:https://github.com/zeit/next.js/issues/9524