Turborepo + Rollup 实战:用 Rollup 打包共享 UI 库并集成到 Next.js Monorepo
Turborepo Rollup 实战用 Rollup 打包共享 UI 库并集成到 Next.js Monorepo【免费下载链接】turboBuild system optimized for JavaScript and TypeScript, written in Rust项目地址: https://gitcode.com/gh_mirrors/tu/turbo导读本指南围绕 Turborepo 官方示例 examples/with-rollup 展开讲解如何在一个 Turborepo monorepo 中用 Rollup 将独立的 React 组件库repo/ui编译为可直接消费的产物并让 Next.js 应用web跨包引用它。读完本文你将掌握从create-turbo一键初始化、工作区划分、Rollup 多入口打包配置、TS/ESLint 配置包复用到 Turbo 任务编排build/dev/lint与本地/远程缓存的完整落地路径。该示例由社区维护见 meta.json目录结构小但链路完整非常适合作为纯库用 Rollup 打包、应用层用框架构建这一混合构建模式的参考蓝本。示例仓库总览Turborepo 官方为常见构建工具提供了大量-e示例如with-nextjs、with-vite、with-svelte等with-rollup是其中之一。通过 meta.json 可以确认其定位Monorepo with a single Next.js app sharing a UI library bundled with Rollup一个 Next.js 应用 一个用 Rollup 打包的共享 UI 库。使用 create-turbo 一键初始化原文档给出的创建方式是最直接、最不易出错的路径npx create-turbolatest -e with-rollup命令执行后会在当前目录生成一个名为my-turborepo的项目也可通过附加参数自定义名称。随后即可进入项目cd my-turborepo pnpm run build目录与包结构以当前仓库的 examples/with-rollup 为基准初始化后的结构如下with-rollup/ ├── apps/ │ └── web/ # Next.js 应用 │ ├── pages/index.tsx # 页面入口直接消费 repo/ui │ ├── next.config.js │ ├── package.json │ └── tsconfig.json ├── packages/ │ ├── config-eslint/ # repo/eslint-configESLint flat config 集合 │ ├── config-typescript/ # repo/typescript-config共享 tsconfig 集合 │ └── ui/ # repo/uiRollup 打包的 React 组件库 │ ├── Button.tsx │ ├── Header.tsx │ ├── rollup.config.js │ └── package.json ├── pnpm-workspace.yaml # 工作区声明apps/* 与 packages/* ├── turbo.json # Turbo 任务编排 └── package.json # 根脚本build / dev / lint / format四个核心组成部分web一个 Next.js 应用通过repo/ui/button、repo/ui/header两个子路径导入 UI 组件repo/eslint-configESLint flat 配置包包含next/eslint-plugin-next与eslint-config-prettier对外提供base、next-js、react-internal三份配置repo/typescript-config共享的tsconfig.json集合base.json、nextjs.json、react-library.json供各包通过 extends 继承repo/ui一个纯 React 组件库编译工具是 Rollup产物输出到dist/是本文的主角。每个包/应用都是 100% TypeScript并统一配好了 TypeScript静态类型检查、ESLint代码检查、Prettier代码格式化三件套。工作区与依赖声明工作区由 pnpm-workspace.yaml 声明packages: - apps/* - packages/* onlyBuiltDependencies: - swc/coreapps/*与packages/*两个通配符让 pnpm 把子目录识别为 workspace 成员onlyBuiltDependencies白名单允许swc/core执行安装后的原生构建脚本SWC 的 native 二进制需要 postinstall 编译/下载这是 Rollup 链路能正常工作的前提之一。根目录 package.json 统一了脚本入口与包管理器版本约束{ scripts: { build: turbo run build, dev: turbo run dev, lint: turbo run lint, format: prettier --write \**/*.{ts,tsx,md}\ }, packageManager: pnpm11.21.0, engines: { node: 24.19.0 } }跨包依赖通过 workspace 协议声明web依赖repo/ui: workspace:*repo/ui依赖repo/eslint-config: workspace:*与repo/typescript-config: workspace:*见 apps/web/package.json 与 packages/ui/package.json。Rollup 打包共享 UI 库多入口配置repo/ui的核心是 packages/ui/rollup.config.js。它没有采用单入口打包一个 bundle 的常见做法而是每个组件一个入口产出独立文件import swc from rollup/plugin-swc; export default [ { input: Button.tsx, output: { file: dist/button.js }, }, { input: Header.tsx, output: { file: dist/header.js }, }, ].map((entry) ({ ...entry, external: [react/jsx-runtime], plugins: [ swc({ swc: { jsc: { transform: { react: { runtime: automatic }, }, }, }, }), ], }));要点拆解多入口数组配置Rollup 支持导出配置数组每个元素是一个独立 build。这里Button.tsx→dist/button.js、Header.tsx→dist/header.js避免消费方把整个组件库一起打进包external: [react/jsx-runtime]React 19 自动 JSX runtime 的产物不应打进库文件而是作为 peer 由应用侧提供防止 React 被重复打包rollup/plugin-swcruntime: automatic用 SWC 完成 TSX → JS 的转译速度远快于 Babelautomatic运行时让 JSX 自动编译为jsx-runtime调用——这正是external需要声明react/jsx-runtime的原因两条配置是配套的编译只负责转换不做 tree-shaking 之外的额外优化产物是给消费方的最小可运行模块。package.json 的 exports 映射组件库通过 packages/ui/package.json 的exports字段对外暴露精确的入口并做到类型优先{ name: repo/ui, type: module, exports: { ./button: { types: ./Button.tsx, default: ./dist/button.js }, ./header: { types: ./Header.tsx, default: ./dist/header.js } }, scripts: { lint: eslint . --max-warnings 0, build: rollup --config, dev: pnpm build --watch } }type: module配合default: ./dist/button.js让 Rollup 输出的 ESM 产物可以被import直接消费types直接指向源文件./Button.tsx/./Header.tsx而不是生成.d.ts因为源码本身就是 TypeScript无需额外声明文件生成步骤这也保证了类型定义与实现永远同步exports只暴露./button与./header两个子路径外部无法通过repo/ui根路径或任意文件路径闯入包边界被严格锁定。组件源码与消费方式两个组件都非常简洁Button.tsx、Header.tsx// Button.tsx export const Button () { return buttonBoop/button; }; // Header.tsx export const Header ({ text }: { text: string }) { return h1{text}/h1; };应用侧在 apps/web/pages/index.tsx 中按子路径导入import { Button } from repo/ui/button; import { Header } from repo/ui/header; export default function Page() { return ( Header textWeb / Button / / ); }从源码结构看这条链路是rollup --config把 TSX 编译到dist/→ pnpm workspace 把repo/ui软链进web的 node_modules → Next.js 通过exports解析到dist/button.js并消费。中间没有任何手工复制产物的步骤全靠包解析完成。Turbo 任务编排build / dev / lint原文档给出了两个最常用的根级命令pnpm run build # 构建所有 apps 与 packages pnpm run dev # 开发所有 apps 与 packages它们都只是turbo run task的薄封装。真正的行为定义在根目录 turbo.json{ $schema: https://turborepo.org/schema.json, tasks: { build: { dependsOn: [^build], inputs: [$TURBO_DEFAULT$, .env*], outputs: [dist/**, .next/**, !.next/cache/**, !.next/dev/**] }, lint: { outputs: [] }, dev: { cache: false, persistent: true } } }逐项解读build.dependsOn: [^build]拓扑依赖。web的 build 会等待其依赖包repo/ui的 build 完成后再执行这正是先打包 UI 库、再构建 Next.js的保证同时各包之间没有依赖关系时可以被 Turbo 并行执行build.inputs哈希参与项。$TURBO_DEFAULT$代表各包自身的文件内容.env*让环境文件变化也触发缓存失效build.outputs声明可缓存的产物目录。dist/**覆盖 Rollup 的输出.next/**覆盖 Next.js 构建输出并显式排除.next/cache与.next/dev这些属于过程产物不应进入缓存lint.outputs: []lint 不产出文件因此不缓存产物dev.cache: falsepersistent: truedev 是常驻进程不参与缓存并标记为 persistent 让 Turbo 正确管理其生命周期。注意ui包的 dev 脚本是pnpm build --watchRollup watch 模式web的 dev 是next dev两者都会被turbo run dev拉起——persistent: true同时要求这类长驻任务必须被单独运行不能作为其他任务的依赖。在各包内部build/dev/lint的实现分别是repo/uibuild: rollup --configdev: pnpm build --watchlint: eslint . --max-warnings 0见 packages/ui/package.jsonwebbuild: next builddev: next devstart: next startlint: eslint . --max-warnings 0见 apps/web/package.json并在 next.config.js 中开启了reactStrictMode: true。共享 ESLint 与 TypeScript 配置与with-rollup其他示例一致这里也预设了两套共享配置包保证 monorepo 内 lint 与类型约束统一。repo/eslint-configpackages/config-eslint提供 flat config 风格的三份配置base.js基础规则供所有包使用next-js.jsNext.js 专用包含next/eslint-plugin-next与eslint-config-prettier供web使用react-internal.jsReact 库内部规则供repo/ui使用。各包的 eslint.config.mjs及 packages/ui/eslint.config.mjs通过 flat config 机制 import 对应配置配合--max-warnings 0把任何 warning 都视为失败保证 lint 质量。repo/typescript-configpackages/config-typescript提供base.json基础编译器选项nextjs.jsonNext.js 应用专用供webreact-library.jsonReact 库专用供repo/ui。各包 tsconfig 通过extends继承对应配置例如ui使用react-library.jsonweb使用nextjs.json实现一处定义、处处复用。本地缓存与远程缓存原文档强调默认情况下 Turborepo 会进行本地缓存——同一台机器上只要任务的输入哈希未变依赖文件、环境、上游产物等再次执行就会直接命中缓存并跳过重算。这与上文build.outputs的声明直接相关只有声明了outputs的任务才值得缓存lint这类无产物任务则天然跳过。在此基础上Turborepo 还支持Remote Caching远程缓存把缓存产物共享到云端让团队与 CI/CD 管道复用彼此已经构建过的结果从而显著缩短 CI 时长。启用流程如下cd my-turborepo npx turbo login # 使用 Vercel 账号认证 Turborepo CLI npx turbo link # 将项目与远程缓存关联turbo login完成 CLI 与账号的认证turbo link完成项目与远程缓存的绑定之后每个可缓存任务的上传/下载都会走远程缓存。原文档的说明以 Vercel 为默认实现Vercel Remote Cache 对所有套餐免费无需账号时可先注册再执行上述命令。需要留意的是远程缓存行为属于官方提供的配套服务若团队没有使用 Vercel也可以自行搭建符合 Turborepo 协议的自托管缓存端点但本示例默认链路仍是本地缓存 Vercel Remote Cache。进一步学习原文档推荐继续深入以下 Turborepo 核心概念对应官方文档Pipelines任务管道dependsOn、outputs、inputs等任务字段如何构成执行图与缓存键Caching缓存缓存命中判定、哈希输入与产物恢复机制Remote Caching远程缓存跨机器共享缓存的人工制品。在本文档仓库中也可以直接对照源码继续探索完整的示例结构见 examples/with-rollup根任务编排见 turbo.jsonRollup 打包细节见 packages/ui/rollup.config.js组件导出映射见 packages/ui/package.json应用消费端见 apps/web/pages/index.tsx。【免费下载链接】turboBuild system optimized for JavaScript and TypeScript, written in Rust项目地址: https://gitcode.com/gh_mirrors/tu/turbo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

个人网站的建设目标:从零搭建避开3个高价坑

个人网站的建设目标:从零搭建避开3个高价坑

个人网站的建设目标:从零搭建避开3个高价坑 找建站公司怕被坑高价?太正常了。上周刚有个朋友咨询,对方报了一万二,还没开工就要求付五成定金,吓得他连夜撤了。其实, 个人网站的建设目标 从来不是买一套模板,而是 从零搭建…

2026/9/19 22:09:36 阅读更多 →
CANN ops-transformer 算子剖析:aclnnMhcSinkhorn 双随机矩阵 Sinkhorn 迭代归一化实现

CANN ops-transformer 算子剖析:aclnnMhcSinkhorn 双随机矩阵 Sinkhorn 迭代归一化实现

算子库人工智能深度学习Ascend 【免费下载链接】ops-transformer 本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-transformer 点击查看 免费下载 导读 aclnnMhcSinkhorn 是 CANN op…

2026/9/22 6:33:54 阅读更多 →
TCN时序建模实现轴承磨损趋势预测与RUL回归

TCN时序建模实现轴承磨损趋势预测与RUL回归

简介:本资源是一份面向工业智能运维工程师、设备预测性维护算法研发人员及高校相关方向研究者的深度技术方案,系统解决轴承磨损趋势难以精准建模、维护时机决策缺乏数据支撑的行业痛点。全文374页,覆盖50个工程化章节,从多源传感器…

2026/9/22 8:10:09 阅读更多 →

最新新闻

3天吃透所噶:后端面试避坑与入门到精通实战

3天吃透所噶:后端面试避坑与入门到精通实战

3天吃透所噶:后端面试避坑与入门到精通实战 上周刚面完一个后端岗,面试官盯着我的简历问:“你简历上写的‘熟悉高并发’,那讲讲所噶在微服务里怎么落地?” 我愣了。…

2026/9/22 9:04:34 阅读更多 →
3步搞定免费新概念英语第一册手写实现避坑指南

3步搞定免费新概念英语第一册手写实现避坑指南

3步搞定免费新概念英语第一册手写实现避坑指南 官方文档太长抓不住重点?别慌,这就像你拿着《新概念英语第一册》的完整PDF,想从零搭建一个能自动解析课文结构的工具,却只看到一堆术语。今天咱们不聊虚的,直接上干货: 手写实现…

2026/9/22 9:04:34 阅读更多 →
平凡的世界第一部源码剖析:从入门到精通避坑实录

平凡的世界第一部源码剖析:从入门到精通避坑实录

平凡的世界第一部源码剖析:从入门到精通避坑实录 刚拿到《平凡的世界第一部》这个“源码”项目时,是不是也觉得自己语法都背熟了,一上手写业务逻辑就卡壳?很多应届生都卡在“学会语法却不知怎么搭项目”这一步,以为背完 API…

2026/9/22 9:04:34 阅读更多 →
搞定shuzu手写实现,3招解决API变更难题

搞定shuzu手写实现,3招解决API变更难题

搞定shuzu手写实现,3招解决API变更难题 版本升级后 API 全变了,以前能跑的代码现在全是红叉。这种崩溃感,只有真正被框架升级坑过的人才懂。这时候,与其对着报错信息抓耳挠腮,不如沉下心来, 手写实现 一遍底层逻辑。…

2026/9/22 9:04:34 阅读更多 →
mc34063中文资料保姆级教程源码解析避坑

mc34063中文资料保姆级教程源码解析避坑

mc34063中文资料保姆级教程源码解析避坑 很多人刚接触电源设计,看了一堆MC34063的数据手册,感觉每个引脚都认识,但真到了画板子、写驱动或者调参的时候,脑子就一片空白。这就是典型的“学会语法却不知怎么搭项目”的尴尬。今天这篇mc34…

2026/9/22 9:04:34 阅读更多 →
913e源码拆解 一文搞懂核心逻辑

913e源码拆解 一文搞懂核心逻辑

913e源码拆解 一文搞懂核心逻辑 盯着屏幕上一长串红色的 StackTrace,头大吗?别急,今天咱们不整虚的,直接扒开 913e…

2026/9/22 9:03:34 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/22 4:32:41 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/22 4:38:57 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/22 8:51:04 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/22 2:43:42 阅读更多 →