news 2026/9/12 3:52:54

Nx + Next.js 应用生成器实战:嵌套目录、自定义 Express 服务器与纯 JavaScript 三种场景详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Nx + Next.js 应用生成器实战:嵌套目录、自定义 Express 服务器与纯 JavaScript 三种场景详解

Nx + Next.js 应用生成器实战:嵌套目录、自定义 Express 服务器与纯 JavaScript 三种场景详解

【免费下载链接】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 仓库中 @nx/next 应用生成器 的官方示例文档 application-examples.md 为核心,逐一拆解nx g app在三种高频场景下的用法:在嵌套目录中创建应用、为应用接入自定义 Express 服务器、以及生成纯 JavaScript(非 TypeScript)项目。读完本文,你将掌握这些命令的完整参数、底层生成流程与项目产物结构,并能直接在自己的 Nx monorepo 中复制运行。

前置知识:nx g app@nx/next:app的关系

在 Nx 工作区中,nx g appnx g @nx/next:app的快捷别名。该生成器在仓库中的完整实现位于 packages/next/src/generators/application/application.ts,其参数契约定义在同目录下的 schema.json 中。从 schema 可以看出,directory是唯一必填参数(同时是第一个位置参数,即$defaultargv 来源),项目名name则遵循 Nx 命名规范。

生成器内部会依次执行以下步骤(见 application.ts):

  1. 校验当前安装的 Next.js 版本(assertSupportedNextVersion);
  2. 调用@nx/js的 init 生成器初始化 JS 基础设施;
  3. 调用@nx/next的 init 生成器(nextInitGenerator)初始化 Next.js 依赖;
  4. 通过createApplicationFiles生成应用模板文件;
  5. 注册项目配置(addProject),生成 E2E、Jest/Vitest、Lint、样式依赖等配套任务;
  6. 若传入customServer,继续调用customServerGenerator追加自定义服务器代码与 targets;
  7. 最后统一格式化并返回串行任务列表。

下面三个示例正是围绕该生成器的三个关键参数展开。

示例一:在嵌套目录中创建应用

nx g app apps/nested/myapp

这是文档给出的第一个示例:将directory指定为apps/nested/myapp,Nx 会在嵌套路径apps/nested/myapp下创建应用。与直接nx g app myapp相比,嵌套目录的价值在于:

  • 更好的组织性:在大型 monorepo 中,可以按业务域(如apps/nested表示一个分组)或团队边界组织多个应用,避免所有应用平铺在apps/根下造成混乱;
  • 自动化的项目命名:当省略name时,项目名会依据目录推导。normalizeOptions(见 normalize-options.ts)通过determineProjectNameAndRootOptions同时计算projectNameappProjectRootimportPath等派生值;
  • E2E 项目自动伴生:从源码可知,E2E 项目会被自动创建为${appProjectName}-e2e,目录为${appProjectRoot}-e2e(见 normalize-options.ts),例如apps/nested/myapp会对应apps/nested/myapp-e2e。这一行为在 application.spec.ts 的测试中得到验证:生成的myapp-e2e项目带空的tags并将myapp声明为implicitDependencies

生成的目录结构大致如下(App Router +src/为默认值,见 schema.json):

apps/nested/myapp/ ├── src/ │ ├── app/ │ │ ├── api/hello/route.ts │ │ ├── global.css │ │ ├── layout.tsx │ │ └── page.tsx │ └── page.module.css ├── public/ ├── index.d.ts ├── next-env.d.ts ├── next.config.js └── tsconfig.json

这些模板文件来自生成器的 files/ 目录,其中 App Router 布局、页面、路由等均由对应的__tmpl__模板渲染生成。测试 application.spec.ts 明确断言了默认生成的产物:src/app/global.csssrc/app/page.tsxsrc/app/layout.tsxsrc/app/api/hello/route.tssrc/app/page.module.csspublic/favicon.ico均存在,而src/pages/styles.css不应存在——这正是 App Router 项目与 Pages Router 项目的关键差异。

示例二:使用自定义 Express 服务器

nx g app apps/myapp --custom-server

默认情况下,Nx 生成的 Next.js 应用使用 Next.js 内置服务器启动。当需要深度定制服务端行为(如接入中间件、自定义路由逻辑、调整 HTTP 服务器选项)时,可以传入--custom-server参数。

生成时的底层行为

在 application.ts 中,当options.customServer为真时,生成器会调用customServerGenerator,并根据swc开关决定使用swc还是tsc编译自定义服务器:

if (options.customServer) { await customServerGenerator(host, { project: options.projectName, compiler: options.swc ? 'swc' : 'tsc', }); }

其中--swc参数默认开启(见 schema.json),因此默认自定义服务器走 SWC 编译路径。

自定义服务器生成器做了什么

customServerGenerator的实现位于 packages/next/src/generators/custom-server/custom-server.ts,它做四件关键的事:

  1. 生成服务器源码:从 files/server/main.ts__tmpl__ 模板渲染出server/main.ts,以及配套的tsconfig.server.json
  2. 注册两个新 targets
    • build-custom-server:使用@nx/js:tsc@nx/js:swc执行器,输出到dist/<projectRoot>-server,默认配置为production(见 custom-server.ts);
    • serve-custom-server:使用@nx/js:node执行器启动服务器,内部引用build-custom-server作为buildTarget(见 custom-server.ts);
  3. 接线现有 targets:将buildserve与自定义服务器关联——build增加dependsOn: ['build-custom-server']servecustomServerTarget指向serve-custom-server,并区分 development/production 配置(见 custom-server.ts);
  4. 开启构建缓存:把build-custom-server加入nx.jsoncacheableOperations并注册为默认可缓存 target(见 custom-server.ts)。

生成的服务器代码长什么样

模板渲染后的 server/main.ts 是一个最小可用的 Node HTTP 服务器,核心逻辑如下:

  • 通过process.env.NODE_ENV === 'development'判断开发/生产模式;
  • 通过process.env.NX_NEXT_DIR(由@nx/next:server在运行 dev server 时注入)定位 Next.js 应用目录,生产构建时回退到基于__dirname的相对路径计算;
  • 监听process.env.HOST || 'localhost'process.env.PORT || 4200
  • 使用nextApp.getRequestHandler()处理所有进入的 HTTP 请求,将解析后的 URL 交给 Next.js 渲染管线。

模板注释明确提示:这只是一个用于起步的最小实现,你可以按需替换为 Express 等框架,并自行启用 CORS 等安全特性。若希望更深度定制,也可以改为生成后用nx g custom-server my-app为已有应用追加自定义服务器(见 custom-server-examples.md),该命令的project参数必填、compiler可选tsc/swc(默认tsc,见 custom-server/schema.json)。

示例三:使用纯 JavaScript(非 TypeScript)

nx g app apps/myapp --js

Nx 默认生成 TypeScript 项目,若团队偏好 JavaScript 或需要快速原型验证,可通过--js开关切换。该参数在 schema.json 中定义为布尔类型、默认false

"js": { "type": "boolean", "description": "Generate JavaScript files rather than TypeScript files.", "default": false }

生成器如何处理--js

在 create-application-files.ts 中可以看到明确的处理逻辑:

if (options.js) { host.delete(`${options.appProjectRoot}/index.d.ts`); toJS(host); host.delete(`${options.appProjectRoot}/next-env.d.js`); }

即生成 TS 文件后,通过toJS将模板文件转换为.js/.jsx后缀,并清理掉仅在 TS 项目中有意义的index.d.ts类型声明文件与next-env.d.js。相应地,单元测试文件也会按index.spec.${options.js ? 'jsx' : 'tsx'}决定后缀(见 create-application-files.ts),确保 JS 项目的测试同样使用 JSX 语法。

同时,--js会向上传播到初始化阶段:applicationGeneratorInternaljs: schema.js传给@nx/js的 init 生成器(见 application.ts),使整个 JS 基础设施(tsconfig、构建工具链配置等)与 JavaScript 项目保持一致。

使用建议

  • --js与嵌套目录、--custom-server等参数可自由组合,例如nx g app apps/tools/dashboard --js --custom-server
  • 纯 JS 项目同样可以享受 Nx 的缓存、依赖图与任务编排能力,因为缓存与项目图基于任务定义而非语言类型。

小结

场景命令关键参数底层要点
嵌套目录创建nx g app apps/nested/myappdirectory(必填)项目名与 E2E 项目由目录自动推导,E2E 以-e2e后缀伴生
自定义 Express 服务器nx g app apps/myapp --custom-servercustomServer(默认 false)生成server/main.ts,新增build-custom-server/serve-custom-servertargets 并接入 build/serve 链路,默认启用 SWC 编译与任务缓存
纯 JavaScript 项目nx g app apps/myapp --jsjs(默认 false)生成.js/.jsx文件,删除index.d.ts,测试文件使用.jsx后缀

三个示例均可在当前仓库的 packages/next/docs/application-examples.md 中找到原始出处,生成器的完整参数表见 packages/next/src/generators/application/schema.json,单元测试覆盖见 application.spec.ts。你可以直接复制上述命令在自己的 Nx 工作区中运行验证,并结合nx show project <app>查看生成的项目配置与 targets 详情。

【免费下载链接】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),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 3:49:57

从汉明码到LDPC:差错控制编码原理与工程实践

先问个问题&#xff1a;如果信道是理想的&#xff0c;我们还需要信道编码吗&#xff1f;答案是不需要——但现实世界从来没有理想信道。无线信号穿过空气会被衰减、反射、多径干扰&#xff0c;有线传输也躲不过热噪声和串扰。比特在信道上跑一圈&#xff0c;总会有那么几个被翻…

作者头像 李华
网站建设 2026/9/12 3:47:40

局部线性嵌入LLE:流形学习的原理、推导与NumPy实现

做流形学习的相关研究或课程作业时&#xff0c;局部线性嵌入&#xff08;Locally Linear Embedding&#xff0c;LLE&#xff09;这个名字总是绕不过去。它和 Isomap 一起被认为是流形学习领域的开山之作&#xff0c;2000 年发表在Science上时&#xff0c;给当时被 PCA 这类线性…

作者头像 李华