具有下一个导出模式的动态路由

Posted

技术标签:

【中文标题】具有下一个导出模式的动态路由【英文标题】:Dynamic routing with next export mode 【发布时间】:2021-08-02 02:37:33 【问题描述】:

我们在 next export mode 中使用 Next.Js(静态 html 导出),我们需要高级动态路由。

我们的路线看起来像/[config1]/[config2]/[optionalConfig?]/page,其中一个段是可选的,并且页面名称是固定的。例如a/b/c/page1a1/b1/page2。页面需要配置段数据来渲染。

我还没有找到任何使用built-in routing 的方法。我可以做/pages/[config1]/[config2]/page1.tsx,但那个可选部分似乎是个问题。请注意,自定义服务器似乎不是一个选项,因为由于其他限制,我们必须使用下一个导出模式。

注意:我们不知道构建时的路径;它们代表了我们运行时配置的一部分。这必须使用客户端路由。 (我们确实知道有限的页面集 - 例如 page1 ... page10 - 但到这些页面的路径会有所不同。)

我尝试切换到 React Router,设置 useFileSystemPublicRoutes: false 并将路由添加到 pages/_app.tsx(自定义应用程序)。这几乎有效,但我在控制台中看到on-demand-entries-utils.js 的许多 404 以及一些“检测到可能的 EventEmitter 内存泄漏”警告(在开发模式下)。

有效的解决方案(必须 100% 在客户端工作):

使用内置路由的方法 将 React Router 与 Next.Js 集成的示例 替代库(我查看过 next-routes,但已 3 年未更新)

更新

我们或许能够消除对可选细分的要求。但是,看来我们必须实现getStaticPaths 并指定所有路由。例如:

pages/[config]/foo.tsx

export async function getStaticPaths() 
  // Runs at build time
  return 
    paths: [ params:  config: 'xyz'  ],
    fallback: false,
  ;


export async function getStaticProps(context) 
  return 
    props: ,
  ;


export default function FooPage(): JSX.Element 
  return <div>FOO</div>;

这会生成

┌ ○ / ├ /_app ├ ● /[配置]/foo ├ └ /xyz/foo

问题在于我们在构建时不知道配置。

我们需要动态的客户端路由。我们希望继续使用 Next.js,因为最终我们也许可以使用 s-s-r,但目前还没有选择。

【问题讨论】:

我建议查看内置的optional catch all routes。 @juliomalves Catch-all 仅适用于页面名称,不适用于目录名称。我可能会制作一个包罗万象的页面,然后根据查询对象有条件地渲染组件“页面”,但这似乎是一种 hack。 它将为您在getStaticPaths 中定义的任何路径生成页面。您只需要确保getStaticProps 在生成这些页面时正确处理参数(由getStaticPaths 传递)。 @juliomalves 我们在构建时不知道路径。 让我们continue this discussion in chat。 【参考方案1】:

您可以创建一个包罗万象的路由来获取参数,包括可选参数,然后您需要根据该参数渲染正确的组件。所以如果你创建了:

pages/[...config].tsx

这与:

pages/[...config]/index.tsx

然后在index.tsx 中,您可以根据url 将配置作为getStaticProps 中的字符串数组获取。所以/config1/config2/optional[config1, config2, optional]/config1/config2[config1, config2]

因此,如果您需要在已知和可选路径下添加其他子页面,您可以将其用作各种目录路径。

【讨论】:

不幸的是,我了解到动态路由不适用于静态 HTML 导出,除非您在构建时预定义路径 - 我们不知道这一点。我已更新问题以反映这一点。 那么您只有三个选项 - 1) 使您所说的那些页面服务器端呈现不是一个选项,2) 将您的应用程序的该部分分离成一个单独的单页应用程序,例如创建反应应用程序和反应路由器(不理想),或 3)使用 url 参数而不是 url 路径 - myapp.com/?config1=foo&config2=bar 等,然后在 ping 服务器旁边的 useEffect 中读取这些参数。我们在电子商务网站上执行此操作以获取订单历史记录。用户不在乎 - 只是我们开发人员讨厌它。 听起来 2 是我们唯一的选择 - 我们的利益相关者不会接受其他选项。谢谢。 这很糟糕,因为它绝对是最劳动密集型的,而且可能是最容易出现错误和集成问题的一种。如果可能的话,我肯定会提倡 #1 或 #3,但祝你好运! 我想你用你的三个选项搞定了。我们与 Vercel 的某个人确认,这不适用于下一次导出。将 React Router 放在自定义 404 页面中适用于选项 2,但它是一个 hack。 github.com/brajevicm/next-universal-route#readme 是一个可能。

以上是关于具有下一个导出模式的动态路由的主要内容,如果未能解决你的问题,请参考以下文章

具有动态路由和动态依赖的角模块化

反应中具有动态 URL 的私有路由

router模式是啥意思

AngularJS - 基于路由动态加载外部 JS

Vue动态路由

Next js中具有多个参数的动态路由