next.config.js中的访问请求对象

时间:2019-12-11 07:56:11

标签: next.js

我正在使用一个带有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);

2 个答案:

答案 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