在 Turborepo 与 Yarn Berry 中开发 Next.js 应用:with-berry 示例 Web 应用实战指南

发布时间:2026/10/10 23:29:30
在 Turborepo 与 Yarn Berry 中开发 Next.js 应用:with-berry 示例 Web 应用实战指南
构建工具开发工具CLI【免费下载链接】turboBuild system optimized for JavaScript and TypeScript, written in Rust项目地址https://gitcode.com/gh_mirrors/tu/turbo点击查看免费下载本篇指南以 Turborepo 仓库中with-berry示例的apps/web应用 README 为主体讲解如何在基于 Yarn BerryYarn 3的 monorepo 里启动 Next.js 开发服务器、编辑页面、使用共享组件与理解 API 路由机制并延伸到构建任务编排、远程缓存与 Vercel 部署。读完本文你将掌握这套示例从「安装依赖」到「本地开发」再到「构建部署」的完整链路并能在遇到与模板文案不一致的细节时快速定位真实代码位置。示例背景web 应用在 with-berry 中的定位apps/web是仓库中 with-berry 示例 下的一个 Next.js 应用。该示例是一个社区维护meta.json中maintainedByCoreTeam: false的 Turborepo monorepo核心特征是以Yarn v2Berry作为包管理器根目录 package.json 中声明了packageManager: yarn3.6.3并通过.yarn/releases/yarn-3.6.3.cjs锁定 Yarn 运行时版本。整个示例由两部分组成应用appsweb与docs两个都是 Next.js 应用共享包packagesrepo/uiReact 组件库、repo/eslint-configESLint 配置、repo/typescript-config各应用/包共用的 tsconfig 基座。其中web与docs共同消费repo/ui提供的组件详见各自的 web/app/page.tsx 与 docs/app/page.tsx两处都导入了Button和Header这正是 monorepo 内「代码复用 独立部署」的典型形态。作为这一架构中的一员web的 README.md 承担着「如何把这个应用跑起来」的入门说明职责。快速启动运行开发服务器web 应用 README 给出的启动命令是pnpm dev需要特别说明的是这条命令是 Next.js 模板文案的遗留。本示例实际使用的包管理器是 Yarn Berry因此在 with-berry 示例中正确的启动方式是与 apps/docs/README.md 及根 README 保持一致yarn dev从根目录执行yarn dev后打开浏览器访问 http://localhost:3000 即可看到web应用的渲染结果。这里有几个值得展开的细节命令的真实流向根目录 package.json 中dev脚本被定义为turbo run dev即由 Turborepo 统一调度。Turborepo 会依据 turbo.json 中的任务定义递归执行所有包含dev脚本的包apps/web的dev脚本是next dev见 web/package.json默认监听 3000 端口apps/docs的dev脚本是next dev --port 3001见 docs/package.json占用 3001 端口避免与web冲突。因此你会在终端看到两个开发服务器同时运行一个对应web3000一个对应docs3001。这正是 Turborepo 对「一次命令跑起全部应用」的支持。端口与访问入口webhttp://localhost:3000docshttp://localhost:3001如果你只想单独启动web也可以在apps/web目录内直接执行yarn dev但注意此时不会享受 Turborepo 的任务编排。页面编辑与热更新README 中提到「修改pages/index.js即可让页面自动更新」但这同样是模板文案——当前示例采用 Next.js App Router 结构并没有pages/目录。真实页面文件位于 apps/web/app/page.tsx内容如下import { Button } from repo/ui/button; import { Header } from repo/ui/header; export default function Page() { return ( Header textWeb / Button / / ); }编辑该文件保存后Next.js 开发服务器会执行热更新HMR浏览器中的页面即时刷新。这段代码展示了 monorepo 内的跨包导入方式组件并非写在本应用里而是来自共享包repo/uiButton.tsx 渲染一个Boop按钮Header.tsx 接收textprop 渲染一级标题ui/package.json 通过exports字段将./button、./header分别映射到对应源文件使应用可以按子路径导入。为了让 Next.js 正确编译这些来自工作区包且未经构建的 TypeScript 源码web的 next.config.js 开启了module.exports { reactStrictMode: true, transpilePackages: [ui], };transpilePackages告诉 Next.js 对ui即repo/ui包进行转译这是 monorepo 中共享源码包能否被应用直接使用的关键配置reactStrictMode则开启 React 严格模式帮助提前暴露生命周期问题。类型层面web的 tsconfig.json 继承自repo/typescript-config/nextjs.json见 packages/tsconfig/nextjs.json后者再继承 base.json从而让strict、jsx: preserve、moduleResolution: Bundler等选项在整个 monorepo 内保持一致web自身额外开启了strictNullChecks以获得更严格的空值检查。API 路由pages/api 与 App Router 的对应关系README 中关于 API 路由的说明值得单独解读原文要点如下pages/api目录被映射为/api/*该目录下的文件会被当作 API 路由API route处理而不是 React 页面示例端点位于pages/api/hello.js可通过 http://localhost:3000/api/hello 访问。这条机制在 Pages Router 时代是成立的但需要澄清两点与当前仓库状态的差异本示例实际不包含pages/api目录。从目录结构看apps/web 下仅有app/、next.config.js、package.json、tsconfig.json等文件README 中的「API routes 可访问 http://localhost:3000/api/hello」属于模板文案直接访问该地址在本示例中不会得到响应在 App Router本示例使用的结构中等价能力由 Route Handlers 提供在app/api/path/route.ts中导出GET、POST等处理函数即可实现与pages/api相同的「非页面端点」效果路径同样映射为/api/path。因此如果你想给web应用新增一个 API 端点正确做法是在app/api/下新建路由文件例如app/api/hello/route.ts导出GET而不是创建pages/api。这也是「以仓库实际代码为准」胜过照抄模板文案的典型场景。一次看懂 monorepo 里的任务编排web应用虽然是独立的 Next.js 工程但在 monorepo 中它的构建、开发、检查行为都由根目录 turbo.json 统一约束{ $schema: https://turborepo.dev/schema.json, tasks: { build: { dependsOn: [^build], inputs: [$TURBO_DEFAULT$, .env*], outputs: [dist/**, .next/**, !.next/cache/**, !.next/dev/**] }, lint: {}, dev: { cache: false, persistent: true } } }逐项说明其对web的实际影响builddependsOn: [^build]表示拓扑依赖前置——web构建前会先构建它依赖的repo/ui等上游包inputs声明了参与哈希的内容默认文件集合 环境变量文件outputs声明了可被缓存的产物dist/**、.next/**并排除.next/cache与.next/dev。执行yarn build时根脚本会转为turbo run build全量构建。lint无额外配置yarn lint会按各包自身的lint脚本执行。web的 lint 脚本是eslint . --max-warnings 0见 web/package.json其 ESLint 配置继承自 packages/eslint-config/next.js后者融合了eslint:recommended、prettier、vercel/style-guide/eslint/next与turbo规则集。devcache: false关闭缓存开发任务不适合缓存persistent: true标记为常驻进程——这就是为什么yarn dev能同时挂起web与docs两个开发服务器而不被视为「未完成任务」。此外yarn.lock采用 Yarn Berry 的 v6 元数据格式文件头部__metadata: version: 6配合 .yarnrc.yml 中的nodeLinker: node-modules与yarnPath指定保证任何人 clone 后都能以一致的方式安装依赖并复现构建结果。Learn More围绕示例的进阶学习路径README 的「Learn More」部分指向了 Next.js 官方文档、交互式教程及 Next.js 仓库反馈渠道这些是继续深入 Next.js 本身的学习资源。若你想在本仓库内继续延伸与with-berry强相关的进阶路径包括根目录 with-berry README介绍了用npx create-turbolatest -e with-berry一键生成该示例以及完整的目录说明、构建/开发命令与远程缓存启用步骤examples/basic、examples/kitchen-sink 等同级示例对比不同包管理器pnpm、npm、yarn 1、bun 等与框架组合下的 Turborepo 配置差异根目录 turbo.json 与仓库顶层 Cargo.toml前者展示真实生产仓库的任务编排写法后者对应 Turborepo 的 Rust 核心实现。部署到 Vercel 与远程缓存README 的「Deploy on Vercel」部分说明将应用部署到 Vercel 平台是 Next.js 应用最直接的发布方式并建议查阅 Next.js 部署文档获取更多细节。结合 Turborepo 的生态能力with-berry示例在部署环节还有一个关键配套——Remote Caching远程缓存默认情况下Turborepo 只在本地缓存任务产物若希望与团队及 CI/CD 流水线共享构建缓存可在示例根目录执行以下两步命令来自 with-berry READMEcd my-turborepo npx turbo login该命令完成 Turborepo CLI 与 Vercel 账号的认证随后执行npx turbo link将当前仓库关联到远程缓存。启用后web与docs的构建产物即 turbo.json 中outputs声明的内容会被上传并在不同机器间复用——例如 CI 中已构建过的应用本地拉取即可跳过重复编译显著缩短冷启动构建时间。结语apps/web的 README 看似只是一份 Next.js 启动说明但在 with-berry 这个 Turborepo 示例里它实际上是「单应用视角」与「monorepo 视角」的交汇点yarn dev背后是 Turbo 的任务编排与多端口开发服务器app/page.tsx背后是repo/ui的跨包复用与transpilePackages转译API 路由的说明则提醒我们模板文案与 App Router 现实之间的差异。以仓库源码与配置文件为准你就能把这份入门文档用透并顺畅迁移到自己的 Turborepo Yarn Berry 工程中。赞分享构建工具开发工具CLI【免费下载链接】turboBuild system optimized for JavaScript and TypeScript, written in Rust项目地址https://gitcode.com/gh_mirrors/tu/turbo点击查看免费下载相关推荐使用 Yarn BerryYarn 2/3构建 Turborepo Monorepowith-berry 示例实战指南使用 Yarn BerryYarn 2/3构建 Turborepo Monorepowith berry 示例实战指南 本篇指南围绕本仓库中的社区示例构建工具开发工具CLITurborepo with npm 示例详解在 monorepo 中运行与开发 Next.js Web 应用Turborepo with npm 示例详解在 monorepo 中运行与开发 Next.js Web 应用 Turborepo 是使用 Rust 编写、面构建工具开发工具CLITurborepo with-yarn 示例用 Yarn 工作区驱动 Next.js 应用的开发、构建与缓存Turborepo with yarn 示例用 Yarn 工作区驱动 Next.js 应用的开发、构建与缓存 导读 本文以 Turborepo 官方 with构建工具开发工具CLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考