【问题标题】:Next.js under a proxy with different pathNext.js 在具有不同路径的代理下
【发布时间】:2019-07-28 01:42:48
【问题描述】:

使用 next.js 版本 8.0.3 我不知道如何在具有不同子路径的代理下为自定义服务器提供服务。

我在做:

npm run build && npm start

为了构建和打开自定义服务器。

我没有打开http://localhost:3000,而是使用带有另一个子路径http://localhost:8000/example的代理。

代理很简单,复制它:

proxy.js

const express = require('express')
const proxy = require('http-proxy-middleware')

const options = {
  target:'http://localhost:3000/',
}
const exampleProxy = proxy(options)
const app = express()

app.use('/example', exampleProxy)
app.listen(8000)

然后:

node proxy.js

但是,当我打开 http://localhost:8000/example 网址时,正在加载主页,但没有样式、静态、javascript...任何东西...

我怎样才能正确地做到这一点?

非常感谢!

【问题讨论】:

    标签: node.js proxy next.js


    【解决方案1】:

    作为警告,我首先要说的是,我不相信 NextJS 可以很好地处理代理,尤其是在子路径上。

    话虽如此,以下应该可行,但有限制:

    const express = require('express')
    const proxy = require('http-proxy-middleware')
    
    const options = {
      target:'http://localhost:3000/',
      pathRewrite: {
        '^/example': ''
      }
    }
    const exampleProxy = proxy(options)
    const app = express()
    
    app.use(['/example', '/_next', '/static'], exampleProxy)
    app.listen(8000)
    

    pathRewrite 选项确保代理上的 /example/xyz 重定向到 NextJS 服务器上的 /xyz

    您需要代理/_next或任何您将构建目录重命名为),以便您的页面找到所有构建的资产(脚本、样式表、webpack 块等)。如果您检查 Next 的任何项目页面,您会发现这些资产链接是绝对的,因此也需要代理该目录。

    出于同样的原因,您需要代理 /static,除了该目录用于保存您的静态 NextJS 资产(图像等)。

    您还会注意到 Next 中的页面链接通常也是绝对链接(我知道我的所有项目中都包含我的链接)。

    以上都是我认为 NextJS 并不真正适合子路径代理使用的原因。

    更新:

    您可以在 NextJS 项目根目录的 next.config.js 文件中添加以下配置:

    module.exports = {
      assetPrefix: '/example'
    }
    

    这会将/example 添加到所有已构建资产的前面,因此您将链接到/example/_next/pages/xyz 而不是/_next/pages/xyz。通过此更新,您可以删除代理端的 /_next 代理,并且您的 可构建 资产(脚本、样式表等)仍应加载。

    关于 NextJS 应用程序中的导航(即“页面”)链接,如我的评论中所述,您可以设置自己的 Link 版本并添加子路径:

    import Link from 'next/link'
    
    // for proxied server
    const PROXY_PATH= '/example'
    // for non-proxied server
    // const PROXY_PATH= ''
    
    export default MyLink = ({ as, children, ...props }) => <Link {...props} as={`${PROXY_PATH}${as}`}>{children}</Link>
    

    您必须确保您的所有 MyLink 组件都定义了一个 as 属性。您不想想要更改 href 道具本身(链接 ),只更改 as 道具(链接 出现)。

    最后,对于 /static 资产,您只需在 NextJS 应用程序中重写静态链接,即转

    <img src='/static/mylogo.svg' />
    

    <img src=`${PROXY_PATH}/static/mylogo.svg` />
    

    并且代理端的路径重写应该正确处理它。 有了这个,您可以在单独的配置文件中的项目范围内定义PROXY_PATH,或者从环境变量中加载它。

    【讨论】:

    • 非常感谢您的回答!但是,我想这不是我正在寻找的解决方案:( ...基本上有两个原因:(1)代理的想法是让不同的项目在不同的子路径上运行,并且我们可以有冲突路由像/static...这样的路径(2)您的解决方案可以很好地加载带有静态文件的页面,但是,使用 next.js 导航是从 / 开始而不是从 /example 开始。我想要一个仅触摸的解决方案next.js 部分,而不是代理部分。这不可能吗?:O 无论如何,非常感谢!非常感谢您的努力。
    • @AralRoca 我完全理解。正如我在开场评论中所说,我认为 NextJS 不能很好地与子路径代理配合使用。然而,您可以 做一件事,那就是创建您自己的MyLink 组件(继承自Next 的Link)并将您的子路径添加到所有链接。但是您仍然需要处理 /static 并构建目录...
    • @AralRoca 我已经用 NextJS 端的附加配置更新了我的答案,这将有助于构建目录和页面链接,但 /static assets 目录仍然是一个问题。也许它可以通过 NextJS 端的自定义服务器路由来处理?
    • @AralRoca 查看我的最新更新,了解/static assets 目录的可能(且简单)解决方案
    猜你喜欢
    • 2018-03-18
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-03
    • 2023-02-12
    • 1970-01-01
    相关资源
    最近更新 更多