news 2026/9/12 17:38:14

使用 @nx/rollup 在 Nx 中构建与发布 JavaScript 库:执行器、推断插件与迁移实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 @nx/rollup 在 Nx 中构建与发布 JavaScript 库:执行器、推断插件与迁移实战

使用 @nx/rollup 在 Nx 中构建与发布 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/rollup插件包展开,介绍如何在 Nx 工作区中借助 Rollup 将库构建为 ESM / CommonJS 产物:从readme-template.md所定义的包定位出发,覆盖快速开始、@nx/rollup:rollup执行器的全部配置项、自定义rollup.configwithNx编程式 API、样式与依赖处理原理,以及从执行器迁移到@nx/rollup/plugin推断插件的完整路径。读完本文,你将掌握在 Nx 中为库项目配置 Rollup 构建、按需定制产物格式与外置依赖、并平滑迁移到新式推断目标的全套方案。

一、包定位:@nx/rollup是什么

在 packages/rollup/readme-template.md 中,这个包被一句话定义清楚:

This package is a Rollup plugin for Nx.

@nx/rollup是 Nx 的 Rollup 插件包,使命是在 Nx 工作区中"Packages a library for different web usages (ESM, CommonJS)"——把一个库项目打包成面向不同 Web 使用场景的 ESM 与 CommonJS 产物。包内同时提供执行器(executor)生成器(generator),以及新式的推断插件(inferred plugin),具体能力可以从包的清单文件确认:

  • packages/rollup/package.json 中描述为 "The Nx Plugin for Rollup contains executors and generators that support building applications using Rollup.",其peerDependencies声明支持rollup: "^3.0.0 || ^4.0.0"(且为 optional,rollup 由工作区自行安装);
  • packages/rollup/executors.json 注册了唯一执行器@nx/rollup:rollup("Bundle a package using Rollup");
  • packages/rollup/generators.json 注册了initconfiguration(别名rollup-project)与convert-to-inferred三个生成器;
  • 包还通过 packages/rollup/plugin.ts 暴露createNodes/createNodesV2/RollupPluginOptions,通过 packages/rollup/with-nx.ts 暴露withNx编程式配置函数。

值得注意的是,readme-template.md本身是一个发布模板:其中{{links}}{{content}}是占位符。scripts/copy-readme.js 会在打包发布时用 scripts/readme-fragments/links.md 与 scripts/readme-fragments/content.md 替换它们,最终生成dist/packages/rollup/README.md。这意味着模板中的"Getting Started"章节是所有 Nx 包通用的入门指引,而本文下面将结合仓库源码,把模板中一句话带过的"Rollup plugin"展开成可落地的完整方案。

二、快速开始:在 Nx 中启用 Rollup 构建

模板的 Getting Started 部分(即 scripts/readme-fragments/content.md)给出了两种进入路径,它们是使用@nx/rollup的前提:

1. 创建全新 Nx 工作区

# 方式一:npx npx create-nx-workspace # 方式二:npm init npm init nx-workspace # 方式三:yarn create yarn create nx-workspace

2. 为已有仓库接入 Nx

npx nx@latest init

进入工作区后,先安装插件包与 rollup:

npm install -D @nx/rollup rollup

随后通过init生成器完成插件初始化(该生成器在 packages/rollup/src/generators/init/init.ts 中实现,支持skipFormatskipPackageJsonkeepExistingVersionsupdatePackageScripts等选项),再为具体库项目生成构建配置:

nx g @nx/rollup:configuration my-lib

configuration生成器(别名rollup-project)的参数定义见 packages/rollup/src/generators/configuration/schema.json,常用参数包括:

参数说明默认值
project要配置的库项目名必填
compiler编译源码使用的编译器babel(可选swctsc
main入口文件(相对工作区根)<projectRoot>/src/index.ts
tsConfig构建用的 tsconfig(相对工作区根)<projectRoot>/tsconfig.lib.json
format输出模块格式["esm"](可选cjs
external不打进产物、保持外置的模块列表[]
rollupConfig自定义 rollup 配置文件路径(相对工作区根)
buildTarget生成的构建目标名build
importPath库的导入名,如@myorg/my-lib

生成后,project.json中会得到一个使用@nx/rollup:rollup执行器的build目标,随后即可运行:

nx build my-lib

三、@nx/rollup:rollup执行器全参数详解

执行器的完整 schema 定义在 packages/rollup/src/executors/rollup/schema.json,实现位于 packages/rollup/src/executors/rollup/rollup.impl.ts。核心参数整理如下(带默认值):

参数类型默认值说明
mainstring必填入口文件路径(相对项目),别名entryFile
outputPathstring必填产物输出目录
outputFileNamestringmain同名主输出文件名
tsConfigstring必填tsconfig 路径
deleteOutputPathbooleantrue构建前清空输出目录
format("esm"\|"cjs")[]与 tsconfig 匹配输出模块格式列表,别名f
externalstring[]|"all"|"none"[]外置模块列表;all表示全部外置、none表示全部打进产物
watchbooleanfalse文件变更时增量重建
rollupConfigstring | string[]一个或多个接收 rollup config 并返回新 config 的模块路径
extractCssboolean | stringtrue提取 CSS 到输出目录,也可传自定义文件名(如styles.css
assetsobject[] | string[][]静态资源列表(glob+input+output
compiler"babel" \| "swc" \| "tsc""babel"使用的编译器
babelUpwardRootModebooleanfalseBabelrootMode: "upward",用于 monorepo 中逐包应用.babelrc
javascriptEnabledbooleanfalse为 less loader 开启javascriptEnabled
generateExportsFieldbooleanfalse在输出package.json中生成exports字段,别名exports
additionalEntryPointsstring[][]追加到exports字段的额外入口
buildLibsFromSourcebooleantrue直接以源码方式读取可构建库,而非预先单独构建它们
skipTypeCheckbooleanfalse跳过 TypeScript 类型检查
skipTypeFieldbooleanfalse不在输出package.json写入type字段
sourceMapboolean输出 sourcemap
projectstringpackage.json文件路径(已废弃,自动探测项目根package.json

一个典型的project.json配置示例:

{ "my-lib": { "targets": { "build": { "executor": "@nx/rollup:rollup", "outputs": ["{workspaceRoot}/dist/my-lib"], "options": { "main": "packages/my-lib/src/index.ts", "outputPath": "dist/my-lib", "tsConfig": "packages/my-lib/tsconfig.lib.json", "compiler": "swc", "format": ["esm", "cjs"], "external": ["react", "react-dom"], "assets": [{ "glob": "*.md", "input": ".", "output": "." }], "generateExportsField": true } } } } }

3.1 底层执行流程

从 rollup.impl.ts 可以看清执行器的工作方式:

  • 先执行warnRollupExecutorDeprecation()(见 packages/rollup/src/utils/deprecation.ts),提示该执行器已废弃、将在 Nx v24 移除;
  • 通过require('rollup')懒加载 rollup(因为 rollup 是 optional peer dependency,图构建阶段可能尚未安装);
  • 默认把NODE_ENV置为production
  • watch模式下:rollup.rollup(opts)创建 bundle,再对每个 output 执行bundle.write(o),计时并输出⚡ Done in ${duration}watch模式下则切换到rollup.watch,监听START/END/ERROR事件,并在SIGTERM/SIGINT/SIGQUIT时关闭 watcher;
  • 支持同时产出 ESM 与 CJS:当format包含cjs时,resolveOutfile会把 CJS 主文件解析为<outputPath>/<name>.cjs.js

3.2 用户自定义 rollupConfig 的合并规则

createRollupOptions(rollup.impl.ts)展示了自定义配置的两类合并语义:

  • 导出为函数finalConfig = config(finalConfig, options),把默认配置与标准化后的 options 交给你做任意改写;
  • 导出为对象:做浅合并,且plugins采用"默认插件 + 用户插件"拼接的方式追加,而不是覆盖。

无论哪种方式,generatePackageJson插件都会被确保保留在最终插件列表中,以维持输出package.json的生成能力。

四、用withNx编写自定义 rollup.config

除了在project.json中声明式配置,@nx/rollup还提供了编程式配置入口withNx(导出自 packages/rollup/with-nx.ts,实现位于 packages/rollup/src/plugins/with-nx/with-nx.ts)。它的调用形态为withNx(options, overrideConfig, dependencies):第一参传入与执行器一致的标准化选项,第二参传入需要覆盖/追加的 rollup 配置,第三参为可构建依赖节点列表(执行器内部调用时即为withNx(options, {}, dependencies))。

典型用法(新建rollup.config.ts并把rollupConfig指向它):

import { withNx } from '@nx/rollup/with-nx'; export default withNx( { main: './src/index.ts', outputPath: './dist', tsConfig: './tsconfig.lib.json', compiler: 'swc', format: ['esm', 'cjs'], external: ['react', 'react-dom'], generateExportsField: true, }, { // 此处可叠加任意原生 rollup 配置或自定义插件 plugins: [myCustomPlugin()], } );

可用的RollupWithNxPluginOptions完整字段定义见 packages/rollup/src/plugins/with-nx/with-nx-options.ts,与执行器选项一一对应,并额外支持:

  • generatePackageJson?: boolean:是否在输出目录生成package.json(TypeScript Project References + 包管理器 Workspaces 场景下不支持,其余场景默认true)。

选项在 packages/rollup/src/plugins/with-nx/normalize-options.ts 中被归一化:字符串形式的assets必须位于项目 source root 内,目录会展开为**/*的 glob;对象形式的 asset 输出路径不允许以..开头(不能写到输出目录之外);format会去重并保持esm/cjs顺序。

4.1 内置插件管线

with-nx.ts的导入(packages/rollup/src/plugins/with-nx/with-nx.ts#L20-L42)可以看到默认装配的完整工具链:

  • @rollup/plugin-babel@rollup/plugin-commonjs@rollup/plugin-node-resolve@rollup/plugin-image@rollup/plugin-json@rollup/plugin-typescript
  • 内联的 postcss 插件(不依赖外部rollup-plugin-postcss),实现在 packages/rollup/src/plugins/postcss/postcss-plugin.ts,并附带 sass/less/stylus 三套 loader(packages/rollup/src/plugins/postcss/loaders),配合autoprefixer处理前缀;
  • nxCopyAssetsPlugin(packages/rollup/src/plugins/nx-copy-assets.plugin.ts)负责把assets拷贝到输出目录;
  • generatePackageJson(packages/rollup/src/plugins/package-json/generate-package-json.ts)负责生成输出package.json
  • swc(packages/rollup/src/plugins/swc.ts)在compiler: "swc"时替代 babel 编译。

五、依赖包含与babelUpwardRootMode实战细节

packages/rollup/docs/rollup-examples.md 是该执行器 schema 的examplesFile(在 schema.json 中被引用),包含两个高频实战要点:

5.1 把依赖写进输出 package.json

要让某个依赖出现在输出产物的package.jsondependencies中,它必须安装在仓库根package.jsondependencies区(而不是devDependencies):

{ "dependencies": { "some-dependency": "^1.0.0" } }

这是generatePackageJson插件生成输出package.json时的依据:只有根dependencies中的包才会被视为运行时依赖写入产物清单。

5.2babelUpwardRootMode的正确打开方式

babelUpwardRootMode: true会把 Babel 的rootMode设为upward,令 Babel 从工作目录向上查找babel.config.json并将其位置作为 "root"。这在 monorepo 中适用于"每个项目必须应用各自.babelrc"的场景。配置示例:

{ "my-app": { "targets": { "build": { "executor": "@nx/rollup:rollup", "options": { "babelUpwardRootMode": true } } } } }

开启后,工作区根需要一份包含所有包范围的babel.config.json

{ "babelrcRoots": ["*"] }

每个包再提供自己的.babelrc,例如:

{ "presets": ["@babel/preset-env", "@babel/preset-typescript"] }

目录形态如下:

├── packages │ ├── a │ │ └── .babelrc │ └── b │ └── .babelrc └── babel.config.json

注意其语义细节:若a导入了b,则b会应用packages/b/.babelrc,而不会应用a自己的配置;babel.config.json中的内容对所有包生效。由于各包需各自维护正确的 presets/plugins,这种模式容易造成包间构建差异,官方文档明确建议默认不要设置babelUpwardRootMode(保持默认false),仅在确实需要逐包.babelrc时才启用。

六、迁移到推断插件@nx/rollup/plugin

@nx/rollup:rollup执行器已在 schema 中标记废弃,packages/rollup/src/utils/deprecation.ts 明确说明:

The@nx/rollup:rollupexecutor is deprecated and will be removed in Nx v24.

Nx v24 中执行器将被移除,而推断插件(@nx/rollup/plugin)与convert-to-inferred生成器会继续得到支持。因此"executor → plugin"的迁移是当前仓库指向的标准演进路径。

6.1 一条命令完成迁移

# 迁移所有使用 @nx/rollup:rollup 的项目 nx g @nx/rollup:convert-to-inferred # 只迁移指定项目 nx g @nx/rollup:convert-to-inferred --project=my-lib

生成器参数见 packages/rollup/src/generators/convert-to-inferred/schema.json,实现见 packages/rollup/src/generators/convert-to-inferred/convert-to-inferred.ts。其工作步骤包括:

  1. assertSupportedRollupVersion(tree)校验工作区的 rollup 版本;
  2. forEachExecutorOptions遍历所有使用@nx/rollup:rollup的目标(--project指定时只处理该项目),跳过命名 configuration;
  3. nx.jsontargetDefaults里针对@nx/rollup:rollup的默认选项拷贝到目标上,弥补移除 executor 后 defaults 不再生效的问题;
  4. 通过 extract-rollup-config-from-executor-options.ts 把 executor 选项转写为rollup.config.ts(内部走withNx形态),并删除project.json中的旧 target;
  5. 通过 add-plugin-registrations.ts 在nx.jsonplugins中注册@nx/rollup/plugin

6.2 推断插件的工作机制

推断插件的实现位于 packages/rollup/src/plugins/plugin.ts:

  • 以 glob**/rollup.config.{js,cjs,mjs,ts,cts,mts}扫描工作区(plugin.ts#L44),只要项目根(含package.jsonproject.json)存在 rollup 配置文件,就自动为其生成build目标,无需在project.json手工声明;
  • 通过calculateHashesForCreateNodes对项目根与选项做哈希,并把生成结果缓存到 Nx 的workspace-data目录(rollup-<optionsHash>.hash),未变更时直接复用缓存中的目标配置;
  • 加载配置时优先解析工作区自身安装的 rolluploadConfigFile,以保证与 rollup 大版本兼容(例如 rollup@2 允许 config 中使用require,rollup@4 则不行);TypeScript 写的 config 会附加--configPlugin typescript={tsconfig:'tsconfig.lib.json'},并以 watch 模式加载配置以规避缓存;
  • 生成的build目标为command: "rollup -c <config>"cwd指向项目根,cache: truedependsOn: ["^build"](先构建依赖库),inputs使用production/default命名输入并声明对rollup的外部依赖,outputs从 config 的output.dir/output.file推导(缺失时默认dist);
  • 插件选项通过nx.json中插件配置传入:buildTargetName(默认build)、buildDepsTargetNamewatchDepsTargetName

插件还通过addBuildAndWatchDepsTargets自动补充构建/监听依赖库的目标;在 TypeScript Project References 场景(isUsingTsSolutionSetup())下,会额外挂上@nx/js:typescript-sync同步生成器。

6.3 迁移后的形态与配套迁移

迁移完成后,项目不再依赖 executor,project.json中的build目标消失,构建行为完全由rollup.config.ts驱动,nx build my-lib依然可用,同时nx graph中会展示基于 Rollup 的目标关系。此外,仓库还在 packages/rollup/src/migrations/update-23-0-0 提供了配套升级迁移:createNodesV2迁移、移除已废弃的useLegacyTypescriptPlugin选项、内部子路径导入重写,确保旧配置在升级后平滑衔接新式插件体系。

七、总结

@nx/rollup是 Nx 生态中专用于 Rollup 构建的插件包,其能力图谱如下:

  • 声明式配置@nx/rollup:rollup执行器(schema.json)覆盖入口、输出、格式、外置依赖、资源、样式提取、编译器选择等 20 余项参数;
  • 编程式配置withNx(packages/rollup/with-nx.ts)在原生rollup.config中复用 Nx 的库构建管线;
  • 自包含工具链:内联 postcss(sass/less/stylus)、assets 拷贝、输出package.json生成、exports字段与额外入口点支持;
  • 面向未来:执行器已废弃(Nx v24 移除),推荐通过nx g @nx/rollup:convert-to-inferred迁移到@nx/rollup/plugin推断目标,实现配置即代码、缓存即收益的现代构建方式。

无论你是要快速为现有库添加构建目标,还是希望把 Rollup 构建完全收敛到配置文件、享受 Nx 的缓存与依赖图编排,@nx/rollup都提供了对应层级的接入方式。相关源码与示例可继续在仓库中查阅:packages/rollup/docs/rollup-examples.md、packages/rollup/src/plugins/plugin.ts、packages/rollup/src/plugins/with-nx/with-nx.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),仅供参考

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

加湿器高压脉冲场景下MOS管选型与可靠性设计

1. 这颗MOS管不是“万能胶”&#xff0c;而是加湿器高压大电流场景下的精准解药 你拆过加湿器主板吗&#xff1f;尤其是那种带超声波雾化片、支持多档功率调节、还能智能恒湿的中高端机型——打开壳子&#xff0c;主控芯片旁边那颗黑黢黢、带散热片、引脚粗壮的MOS管&#xff0…

作者头像 李华
网站建设 2026/9/12 17:37:23

PakePlus 完整指南:把任意网页打包成 5MB 以下的跨端应用

PakePlus 完整指南&#xff1a;把任意网页打包成 5MB 以下的跨端应用 【免费下载链接】PakePlus Turn any webpage/HTML/Vue/React and so on into desktop and mobile app under 5M with easy in few minutes. 轻松将任意网站/HTML/Vue/React等项目构建为轻量级(小于5M)多端桌…

作者头像 李华
网站建设 2026/9/12 17:36:42

AI降权技术解析:2025年降AI率方法与平台评测

1. 项目概述&#xff1a;AI降权网站的兴起与价值 2025年&#xff0c;随着AI生成内容在互联网的爆炸式增长&#xff0c;一个全新的需求正在浮出水面——如何有效降低AI生成率&#xff08;AI Rate&#xff09;。作为从业十余年的技术博主&#xff0c;我注意到这个领域正在形成独特…

作者头像 李华
网站建设 2026/9/12 17:32:39

《拉娜之星2》XGP零成本体验:治愈系解谜冒险游戏游玩指南

最近我一直在XGP的游戏库里翻来翻去&#xff0c;想找那种不用动脑子、不用对抗、打开就能静静玩一下午的作品&#xff0c;结果被《拉娜之星 2》狠狠治愈了一把。如果你也是XGP订阅用户&#xff0c;那这波确实等于零成本体验一款公认的治愈神作&#xff0c;尤其适合那种玩累了竞…

作者头像 李华