Next.js under a proxy with different path

时间:2019-03-06 11:42:34

标签: node.js proxy next.js

Using next.js version 8.0.3 I don't know how to serve a custom server under a proxy with a different subpath.

I'm doing:

npm run build && npm start

In order to build and open the custom server.

And instead of open http://localhost:3000, I'm using a proxy with another subpath http://localhost:8000/example.

The proxy is simple, to reproduce it:

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)

And then:

node proxy.js

However, when I open the http://localhost:8000/example url is loading the home page but without styles, statics, javascript... Anything...

How can I do it correctly?

Thank you so much!

1 个答案:

答案 0 :(得分:2)

需要说明的是,我首先要说的是,我认为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并不真正适合子路径代理用法的原因。

更新

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

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

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

关于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或从环境变量中加载它。