Nx Next.js 库生成实战:创建库与导出 React Server Components
2026/9/12 12:41:44 网站建设 项目流程

Nx Next.js 库生成实战:创建库与导出 React Server Components

【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx

导读

@nx/next为 Nx 工作区提供了一整套 Next.js 项目生成器,其中library生成器用于创建可供应用复用的 Next.js 库。与普通的 React 库不同,Next.js 库自带一个额外的src/server.ts入口,专门用于导出 React Server Components(RSC),从而避免客户端组件与服务器组件混用导致运行时错误。本文基于 packages/next/docs/library-examples.md 展开,结合 library 生成器源码 与 schema.json,完整讲解库的创建方式、常用配置项以及 RSC 双入口机制背后的实现原理。读完本文,你将能够熟练地在 Nx 工作区中创建任意路径下的 Next.js 库,并正确组织客户端组件与服务器组件的导出。

创建库的基本命令

@nx/next:library生成器的核心用法与@nx/react:library保持一致,但输出额外包含server入口点和 Next.js 类型声明(详见 schema.json 的描述)。

创建新库

在 Nx 工作区根目录执行以下命令,即可在默认位置生成一个名为my-lib的库:

nx g lib libs/my-lib

命令执行后,@nx/next会依次执行内部的初始化流程(调用链见 library.ts):

  1. 调用@nx/jsinitGenerator完成 JS/TS 工具链初始化;
  2. 调用nextInitGenerator完成 Next.js 相关依赖与配置初始化;
  3. 复用@nx/reactlibraryGenerator生成 React 库骨架。

也就是说,Next.js 库是 React 库的超集——它继承了 React 库的全部结构,再叠加 Next.js 专属的入口与类型配置。生成器还会自动向tsconfig.lib.jsoncompilerOptions.types中追加next@nx/next/typings/image.d.ts(library.ts),确保库内的 Next.js 代码(如Image组件、样式导入)获得正确的类型支持。这一点也有对应的单元测试验证,见 library.spec.ts。

在指定目录下创建库

directory参数(也支持别名dir)指向一个子目录,即可把库生成在嵌套路径中:

nx g lib libs/shared/my-lib

上面的命令会在libs/shared/my-lib位置生成库。directory是生成器的位置参数($default指定为 argv 的第一个参数),它会与name一起经由determineProjectNameAndRootOptions推导出最终的projectRootimportPath(见 normalize-options.ts)。默认情况下,导入路径由目录结构推导而来,例如libs/shared/my-lib对应的导入名通常为@proj/shared/my-lib(其中proj为工作区名,可通过--importPath显式覆盖)。

常用配置项速查

@nx/next:library的参数与@nx/react:library对齐(测试 library.spec.ts 专门校验了两者的 schema 保持同步),核心选项如下:

选项类型默认值说明
directorystring库所在的目录,必填,作为位置参数
namestring库名,支持@scope/name形式
stylestringcss样式文件格式,可选cssscssnone
bundlerstringnone打包器,可选noneviterollupnone表示不可构建
linterstring工作区默认静态检查工具,可选eslintoxlintnone
unitTestRunnerstringnone单元测试运行器,可选vitestjestnone
inSourceTestsbooleanfalse使用 Vitest 时把测试内联到源码文件(import.meta.vitest)而非生成独立 spec 文件
importPathstring自动推导库的导入路径,如@myorg/my-awesome-lib
componentbooleantrue是否生成默认组件
jsbooleanfalse生成 JavaScript 而非 TypeScript 文件
globalCssbooleanfalsetrue时使用全局 CSS 而非 CSS Modules
strictbooleantrue是否启用 tsconfig 严格模式
compilerstringbabel编译器,可选babelswc
buildablebooleanfalse(已弃用)生成可构建库,请改用bundler
publishablebooleanfalse生成可发布库
routingboolean生成带路由的库,配合appProject使用
appProjectstring要将库路由挂载到的应用项目
tagsstring为库添加标签(用于约束依赖的 lint 规则)
skipTsConfigbooleanfalse不更新tsconfig.json
skipPackageJsonbooleanfalse不向package.json添加依赖
enableTypedLintingbooleanfalse启用类型感知的 ESLint 检查(为性能默认关闭)

一个覆盖常见场景的完整示例:

nx g lib libs/shared/ui --style=scss --bundler=vite --unitTestRunner=vitest --importPath=@myorg/ui --tags="scope:shared,type:ui"

生成器会为带单元测试运行器的库自动安装@testing-library/react@testing-library/dom依赖;选择swc编译器时还会自动加入@swc/core(library.ts,测试见 library.spec.ts)。

导出 React Server Components:双入口机制

Next.js 库区别于普通 React 库的核心,在于其第二个入口src/server.ts。这一点在原文档中有明确说明,生成器源码也给出了直接注释:从src/index.ts导出 RSC 会把整个文件标记为 server-only,当客户端组件引入该文件时就会抛错(见 library.ts,相关历史问题见 Nx issue #15830 的注释)。

为什么需要单独的 server 入口

在 React Server Components 架构下,客户端组件(带'use client'指令或需要交互逻辑)与服务器组件(可异步访问数据库、API)的执行环境完全不同。若将两者混在同一个入口文件导出:

  • 服务器组件会要求调用方运行在服务器上下文;
  • 客户端组件一旦 import 该文件,就会把 server-only 代码带入客户端 bundle,导致构建或运行时错误。

因此生成器在创建库时生成了两个职责明确的入口文件:

  • src/index.ts:导出 React 客户端组件(带'use client'指令的组件)及其他非服务器工具函数;
  • src/server.ts:专门导出 React 服务器组件。

生成器写入的src/index.ts顶部注释即为:“Use this file to export React client components (e.g. those with 'use client' directive) or other non-server utilities”;src/server.ts则写入“Use this file to export React server components”,并默认导出一个HelloServer异步组件(library.ts)。

应用中的消费方式

原文档给出了在应用中使用库的标准姿势:客户端组件从库根路径导入,服务器组件从/server子路径导入:

// apps/my-app/app/page.tsx import { MyComponent } from '@myorg/my-lib'; import { HelloServer } from '@myorg/my-lib/server';

要让@myorg/my-lib/server这条子路径在开发与构建时都能正确解析,生成器会同步完成三处接线(测试断言见 library.spec.ts):

  1. tsconfig 路径映射:在tsconfig.base.jsoncompilerOptions.paths中追加@proj/my-lib/server -> ./my-lib/src/server.ts
  2. Vite 多入口配置(使用bundler=vite时):把vite.config.mts中单一的entry: 'src/index.ts'改写为{ index: 'src/index.ts', server: 'src/server.ts' }多入口对象,并将fileName改为按入口名输出的函数(update-vite-config.ts);
  3. package.json exports:向库的package.json添加./server导出映射,指向./dist/server.js/./dist/server.d.ts(测试见 library.spec.ts)。

在 TS Solution 工作区(使用references+customConditions的现代配置)中,非可构建库会在package.jsonexports['./server']里直接映射到源码./src/server.ts,并通过自定义 condition 指向开发源码;可构建库则映射到dist产物(library.ts)。

使用约束与最佳实践

结合原文档与源码,可以总结出以下实践准则:

  • 客户端组件与纯工具函数一律放在src/index.ts中导出;
  • 服务器组件(如需要直接访问数据库、密钥或服务端 API 的异步组件)放在src/server.ts中导出;
  • 不要在src/index.ts中导出任何服务器组件,否则会污染整个入口的模块边界;
  • 应用侧按需选择导入路径:页面与客户端组件引用@myorg/my-lib,仅服务端代码引用@myorg/my-lib/server

小结

@nx/next的 library 生成器把"创建库"与"RSC 正确导出"这两件事自动化了:一条nx g lib命令即可在任意目录生成结构完整的 Next.js 库,同时自动搭建src/index.ts(客户端)与src/server.ts(服务器组件)的双入口,并完成 tsconfig 路径、Vite 构建入口与 package.json exports 的全部接线。理解这套机制后,你可以在 Nx 工作区中放心地按"客户端/服务器"维度组织库的导出边界,避免 RSC 混用带来的构建陷阱。更多命令示例可参考同目录下的 application-examples.md、component-examples.md 与 page-examples.md;深入理解生成器实现可阅读 library.ts 及其配套测试 library.spec.ts。

【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询