You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Next.js与Turborepo实现共享页面方案

问题

我用Turborepo搭建了一个包含两个Next.js应用的monorepo,目录结构如下:

base
|---apps
|   |---editor
|   |    |---pages
|   |        |---index.js // 两个应用的该文件内容不同
|   |        |---anotherPage.js // 两个应用的该文件内容相同
|   |   
|   |---etsy
|        |---pages
|            |---index.js // 两个应用的该文件内容不同
|            |---anotherPage.js // 两个应用的该文件内容相同
|
|---packages

Next.js自带自动路由功能,访问url/anotherPage会自动对应到pages/anotherPage.js。现在两个应用之间有大量共享页面,以及pages/api下的共享API,想把这些共享内容移到packages目录下,同时保留自动路由和API路由功能,该怎么做?

解决方案

下面是几种可落地的实现方式,均能保留Next.js的自动路由特性:

方法1:用符号链接直接映射共享路由(最省心)

直接通过文件系统符号链接,让Next.js的自动路由系统“识别”到packages里的共享页面/API:

  1. 在packages下创建shared-routes包,完全复刻Next.js的pages目录结构:
packages
|---shared-routes
|   |---pages
|       |---anotherPage.js // 共享页面
|       |---api
|           |---sharedApi.js // 共享API
  1. 给每个应用的pages目录创建指向共享文件的符号链接:
    • Mac/Linux:在apps/editor/pages下执行 ln -s ../../../packages/shared-routes/pages/anotherPage.js ./anotherPage.js
    • Windows:用mklink ./anotherPage.js ../../../packages/shared-routes/pages/anotherPage.js(需管理员权限)
  2. 嫌手动操作麻烦?可以在Turborepo根目录的package.json中添加脚本,一次性给所有应用创建链接:
{
  "scripts": {
    "link-shared-routes": "cd apps/editor/pages && ln -s ../../../packages/shared-routes/pages/anotherPage.js ./anotherPage.js && cd ../../etsy/pages && ln -s ../../../packages/shared-routes/pages/anotherPage.js ./anotherPage.js"
  }
}

方法2:用包导出+Next.js编译配置(规范的monorepo做法)

这种方式无需文件链接,完全靠包管理和Next.js编译配置实现,符合monorepo最佳实践:

  1. 在packages/shared-routes的package.json中配置导出规则,让应用能精准导入共享内容:
{
  "name": "@repo/shared-routes",
  "exports": {
    "./pages/*": "./pages/*",
    "./api/*": "./pages/api/*"
  },
  "type": "module"
}
  1. 给每个Next.js应用的next.config.js添加transpilePackages配置,告诉Next.js需要编译这个共享包(避免ES模块语法报错):
/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['@repo/shared-routes'],
}

module.exports = nextConfig
  1. 在应用的pages目录下创建“转发文件”,比如apps/editor/pages/anotherPage.js只需写:
// 导出共享页面的默认组件及所有路由相关方法(如getStaticProps、getStaticPaths)
export { default, getStaticProps, getStaticPaths } from '@repo/shared-routes/pages/anotherPage'
  1. 共享API的处理逻辑完全一致,比如apps/editor/pages/api/sharedApi.js:
export { default } from '@repo/shared-routes/api/sharedApi'

方法3:自定义Next.js路由映射(进阶场景)

如果需要更灵活的路由控制,可自定义Next.js的路由解析逻辑,但需手动维护映射规则,适合少量共享路由的场景:

  • 在应用的next.config.js中使用rewrites或redirects配置路由映射,将请求指向共享包中的内容。
  • 或使用@next/mdx等插件扩展路由,但复杂度较高,不推荐用于大量共享路由的场景。

注意事项

  • 确保共享包的依赖版本与应用一致,避免编译错误。
  • 使用方法2时,转发文件需导出所有必要的路由相关函数,否则会丢失Next.js的路由特性。
  • Turborepo的缓存机制会自动处理共享包的变更,修改共享路由后所有应用会同步更新。

内容的提问来源于stack exchange,提问作者Vipul Rajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 20:05:30