diff --git a/eslint.config.js b/eslint.config.js index c25afb9dc..f1cd3104e 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -27,6 +27,7 @@ export default tseslint.config( allow: [ String.raw`^.*/eslint(\.base)?\.config\.[cm]?js$`, String.raw`^.*/code-pushup\.(config|preset)(\.m?[jt]s)?$`, + String.raw`^.*/rolldown(\.base)?\.config\.[cm]?js$`, '^[./]+/tools/.*$', ], depConstraints: [ diff --git a/nx.json b/nx.json index 959979ed1..9b708339d 100644 --- a/nx.json +++ b/nx.json @@ -75,7 +75,7 @@ "--max-warnings=0", "--no-warn-ignored", "--error-on-unmatched-pattern=false", - "--format=./tools/eslint-formatter-multi/dist/src/index.js" + "--format=./tools/eslint-formatter-multi/dist/index.js" ], "env": { "ESLINT_FORMATTER_CONFIG": "{\"outputDir\":\"{projectRoot}/.eslint\"}" @@ -83,17 +83,15 @@ } }, "build": { - "dependsOn": ["^build"], - "inputs": ["production", "^production"], "cache": true, - "executor": "@nx/js:tsc", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "{projectRoot}/dist", - "main": "{projectRoot}/src/index.ts", - "tsConfig": "{projectRoot}/tsconfig.lib.json", - "assets": ["{projectRoot}/*.md"] - } + "inputs": [ + "production", + "^production", + { + "externalDependencies": ["rolldown"] + } + ], + "outputs": ["{projectRoot}/dist"] }, "unit-test": { "cache": true, @@ -358,7 +356,8 @@ "filterByTags": ["publishable"] } } - } + }, + "./tools/src/rolldown.plugin.mjs" ], "nxCloudId": "65d4d862d2adb16a45a4bc7c" } diff --git a/package-lock.json b/package-lock.json index ceb8ab72f..0d350ff34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -101,6 +101,7 @@ "prettier": "^3.4.1", "react": "18.3.1", "react-dom": "18.3.1", + "rolldown": "^1.0.0-beta.38", "ts-patch": "^3.3.0", "tsconfig-paths": "^4.2.0", "tsx": "^4.19.0", @@ -117,6 +118,7 @@ "@nx/nx-darwin-arm64": "^21.4.1", "@nx/nx-darwin-x64": "^21.4.1", "@nx/nx-linux-x64-gnu": "^21.4.1", + "@rolldown/binding-darwin-arm64": "^1.0.0-beta.38", "@rollup/rollup-darwin-arm64": "^4.0.0", "@rollup/rollup-darwin-x64": "^4.0.0", "@rollup/rollup-linux-x64-gnu": "^4.0.0", @@ -6636,6 +6638,16 @@ "@octokit/openapi-types": "^20.0.0" } }, + "node_modules/@oxc-project/types": { + "version": "0.89.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.89.0.tgz", + "integrity": "sha512-yuo+ECPIW5Q9mSeNmCDC2im33bfKuwW18mwkaHMQh8KakHYDzj4ci/q7wxf2qS3dMlVVCIyrs3kFtH5LmnlYnw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, "node_modules/@paulirish/trace_engine": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@paulirish/trace_engine/-/trace_engine-0.0.32.tgz", @@ -6801,6 +6813,301 @@ "tslib": "2.8.1" } }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.38.tgz", + "integrity": "sha512-AE3HFQrjWCKLFZD1Vpiy+qsqTRwwoil1oM5WsKPSmfQ5fif/A+ZtOZetF32erZdsR7qyvns6qHEteEsF6g6rsQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.38.tgz", + "integrity": "sha512-RaoWOKc0rrFsVmKOjQpebMY6c6/I7GR1FBc25v7L/R7NlM0166mUotwGEv7vxu7ruXH4SJcFeVrfADFUUXUmmQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.38.tgz", + "integrity": "sha512-Ymojqc2U35iUc8NFU2XX1WQPfBRRHN6xHcrxAf9WS8BFFBn8pDrH5QPvH1tYs3lDkw6UGGbanr1RGzARqdUp1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.38.tgz", + "integrity": "sha512-0ermTQ//WzSI0nOL3z/LUWMNiE9xeM5cLGxjewPFEexqxV/0uM8/lNp9QageQ8jfc/VO1OURsGw34HYO5PaL8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.38.tgz", + "integrity": "sha512-GADxzVUTCTp6EWI52831A29Tt7PukFe94nhg/SUsfkI33oTiNQtPxyLIT/3oRegizGuPSZSlrdBurkjDwxyEUQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.38.tgz", + "integrity": "sha512-SKO7Exl5Yem/OSNoA5uLHzyrptUQ8Hg70kHDxuwEaH0+GUg+SQe9/7PWmc4hFKBMrJGdQtii8WZ0uIz9Dofg5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.38.tgz", + "integrity": "sha512-SOo6+WqhXPBaShLxLT0eCgH17d3Yu1lMAe4mFP0M9Bvr/kfMSOPQXuLxBcbBU9IFM9w3N6qP9xWOHO+oUJvi8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.38.tgz", + "integrity": "sha512-yvsQ3CyrodOX+lcoi+lejZGCOvJZa9xTsNB8OzpMDmHeZq3QzJfpYjXSAS6vie70fOkLVJb77UqYO193Cl8XBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.38.tgz", + "integrity": "sha512-84qzKMwUwikfYeOuJ4Kxm/3z15rt0nFGGQArHYIQQNSTiQdxGHxOkqXtzPFqrVfBJUdxBAf+jYzR1pttFJuWyg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.38.tgz", + "integrity": "sha512-QrNiWlce01DYH0rL8K3yUBu+lNzY+B0DyCbIc2Atan6/S6flxOL0ow5DLQvMamOI/oKhrJ4xG+9MkMb9dDHbLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.38.tgz", + "integrity": "sha512-fnLtHyjwEsG4/aNV3Uv3Qd1ZbdH+CopwJNoV0RgBqrcQB8V6/Qdikd5JKvnO23kb3QvIpP+dAMGZMv1c2PJMzw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.0.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", + "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", + "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.5.tgz", + "integrity": "sha512-TBr9Cf9onSAS2LQ2+QHx6XcC6h9+RIzJgbqG3++9TUZSH204AwEy5jg3BTQ0VATsyoGj4ee49tN/y6rvaOOtcg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@tybys/wasm-util": "^0.10.1" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.38.tgz", + "integrity": "sha512-19cTfnGedem+RY+znA9J6ARBOCEFD4YSjnx0p5jiTm9tR6pHafRfFIfKlTXhun+NL0WWM/M0eb2IfPPYUa8+wg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-ia32-msvc": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.38.tgz", + "integrity": "sha512-HcICm4YzFJZV+fI0O0bFLVVlsWvRNo/AB9EfUXvNYbtAxakCnQZ15oq22deFdz6sfi9Y4/SagH2kPU723dhCFA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.38.tgz", + "integrity": "sha512-4Qx6cgEPXLb0XsCyLoQcUgYBpfL0sjugftob+zhUH0EOk/NVCAIT+h0NJhY+jn7pFpeKxhNMqhvTNx3AesxIAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.32", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.32.tgz", @@ -26690,6 +26997,57 @@ "node": ">=10.0.0" } }, + "node_modules/rolldown": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.38.tgz", + "integrity": "sha512-58frPNX55Je1YsyrtPJv9rOSR3G5efUZpRqok94Efsj0EUa8dnqJV3BldShyI7A+bVPleucOtzXHwVpJRcR0kQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.89.0", + "@rolldown/pluginutils": "1.0.0-beta.38", + "ansis": "^4.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-beta.38", + "@rolldown/binding-darwin-arm64": "1.0.0-beta.38", + "@rolldown/binding-darwin-x64": "1.0.0-beta.38", + "@rolldown/binding-freebsd-x64": "1.0.0-beta.38", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.38", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.38", + "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.38", + "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.38", + "@rolldown/binding-linux-x64-musl": "1.0.0-beta.38", + "@rolldown/binding-openharmony-arm64": "1.0.0-beta.38", + "@rolldown/binding-wasm32-wasi": "1.0.0-beta.38", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.38", + "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.38", + "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.38" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.38.tgz", + "integrity": "sha512-N/ICGKleNhA5nc9XXQG/kkKHJ7S55u0x0XUJbbkmdCnFuoRkM1Il12q9q0eX19+M7KKUEPw/daUPIRnxhcxAIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/rolldown/node_modules/ansis": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz", + "integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + } + }, "node_modules/rollup": { "version": "4.48.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.48.0.tgz", diff --git a/package.json b/package.json index f70cc974b..0fe19f3e2 100644 --- a/package.json +++ b/package.json @@ -111,6 +111,7 @@ "prettier": "^3.4.1", "react": "18.3.1", "react-dom": "18.3.1", + "rolldown": "^1.0.0-beta.38", "ts-patch": "^3.3.0", "tsconfig-paths": "^4.2.0", "tsx": "^4.19.0", @@ -123,6 +124,7 @@ "zod2md": "^0.2.4" }, "optionalDependencies": { + "@rolldown/binding-darwin-arm64": "^1.0.0-beta.38", "@esbuild/darwin-arm64": "^0.25.9", "@nx/nx-darwin-arm64": "^21.4.1", "@nx/nx-darwin-x64": "^21.4.1", diff --git a/packages/ci/rolldown.config.mjs b/packages/ci/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/ci/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/cli/rolldown.config.mjs b/packages/cli/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/cli/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/core/rolldown.config.mjs b/packages/core/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/core/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/create-cli/rolldown.config.mjs b/packages/create-cli/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/create-cli/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/models/project.json b/packages/models/project.json index 70591234a..6d592909d 100644 --- a/packages/models/project.json +++ b/packages/models/project.json @@ -17,12 +17,22 @@ "inputs": ["production", "^production", "{projectRoot}/zod2md.config.ts"], "outputs": ["{projectRoot}/docs/models-reference.md"] }, - "build": { - "dependsOn": [ - "^build", - "generate-docs", - { "projects": "models-transformers", "target": "build" } - ] + "build": {}, + "types": { + "executor": "@nx/js:tsc", + "options": { + "outputPath": "{projectRoot}/dist", + "main": "{projectRoot}/src/index.ts", + "tsConfig": "{projectRoot}/tsconfig.lib.json", + "assets": [] + }, + "inputs": [ + "production", + "^production", + "{projectRoot}/tsconfig.lib.json" + ], + "outputs": ["{projectRoot}/dist"], + "cache": true }, "lint": {}, "lint-report": {}, diff --git a/packages/models/rolldown.config.mjs b/packages/models/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/models/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/models/scripts/generate-dist-package-json.mjs b/packages/models/scripts/generate-dist-package-json.mjs new file mode 100755 index 000000000..46f4c1267 --- /dev/null +++ b/packages/models/scripts/generate-dist-package-json.mjs @@ -0,0 +1,141 @@ +#!/usr/bin/env node +import { copyFileSync, readFileSync, writeFileSync } from 'fs'; +import { dirname, join } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const packageJsonPath = join(__dirname, '..', 'package.json'); +const distPackageJsonPath = join(__dirname, '..', 'dist', 'package.json'); +const readmePath = join(__dirname, '..', 'README.md'); +const distReadmePath = join(__dirname, '..', 'dist', 'README.md'); + +// Read the main package.json +const mainPackageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); + +// Create a simplified package.json for the dist folder +const distPackageJson = { + name: mainPackageJson.name, + version: mainPackageJson.version, + license: mainPackageJson.license, + description: mainPackageJson.description, + homepage: mainPackageJson.homepage, + bugs: mainPackageJson.bugs, + repository: mainPackageJson.repository, + keywords: mainPackageJson.keywords, + publishConfig: mainPackageJson.publishConfig, + type: mainPackageJson.type, + main: './index.cjs', + module: './index.js', + types: './index.d.ts', + exports: { + '.': { + types: './index.d.ts', + import: './index.js', + require: './index.cjs', + }, + './audit': { + types: './audit.d.ts', + import: './audit.js', + require: './audit.cjs', + }, + './audit-output': { + types: './audit-output.d.ts', + import: './audit-output.js', + require: './audit-output.cjs', + }, + './cache-config': { + types: './cache-config.d.ts', + import: './cache-config.js', + require: './cache-config.cjs', + }, + './category-config': { + types: './category-config.d.ts', + import: './category-config.js', + require: './category-config.cjs', + }, + './commit': { + types: './commit.d.ts', + import: './commit.js', + require: './commit.cjs', + }, + './configuration': { + types: './configuration.d.ts', + import: './configuration.js', + require: './configuration.cjs', + }, + './core-config': { + types: './core-config.d.ts', + import: './core-config.js', + require: './core-config.cjs', + }, + './group': { + types: './group.d.ts', + import: './group.js', + require: './group.cjs', + }, + './issue': { + types: './issue.d.ts', + import: './issue.js', + require: './issue.cjs', + }, + './persist-config': { + types: './persist-config.d.ts', + import: './persist-config.js', + require: './persist-config.cjs', + }, + './plugin-config': { + types: './plugin-config.d.ts', + import: './plugin-config.js', + require: './plugin-config.cjs', + }, + './report': { + types: './report.d.ts', + import: './report.js', + require: './report.cjs', + }, + './reports-diff': { + types: './reports-diff.d.ts', + import: './reports-diff.js', + require: './reports-diff.cjs', + }, + './runner-config': { + types: './runner-config.d.ts', + import: './runner-config.js', + require: './runner-config.cjs', + }, + './source': { + types: './source.d.ts', + import: './source.js', + require: './source.cjs', + }, + './table': { + types: './table.d.ts', + import: './table.js', + require: './table.cjs', + }, + './tree': { + types: './tree.d.ts', + import: './tree.js', + require: './tree.cjs', + }, + './upload-config': { + types: './upload-config.d.ts', + import: './upload-config.js', + require: './upload-config.cjs', + }, + }, + sideEffects: false, + dependencies: mainPackageJson.dependencies, +}; + +// Write the dist package.json +writeFileSync( + distPackageJsonPath, + JSON.stringify(distPackageJson, null, 2) + '\n', +); + +// Copy README.md to dist +copyFileSync(readmePath, distReadmePath); + +console.log('✅ Generated dist/package.json successfully'); +console.log('✅ Copied README.md to dist/ successfully'); diff --git a/packages/nx-plugin/rolldown.config.mjs b/packages/nx-plugin/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/nx-plugin/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/plugin-coverage/package.json b/packages/plugin-coverage/package.json index 2eb258029..9fc78f6ad 100644 --- a/packages/plugin-coverage/package.json +++ b/packages/plugin-coverage/package.json @@ -58,7 +58,7 @@ } }, "files": [ - "src", + "dist", "!**/*.tsbuildinfo" ] } diff --git a/packages/plugin-coverage/rolldown.config.mjs b/packages/plugin-coverage/rolldown.config.mjs new file mode 100644 index 000000000..c8aae84c5 --- /dev/null +++ b/packages/plugin-coverage/rolldown.config.mjs @@ -0,0 +1,8 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, + entry: [`${projectRoot}/src/index.ts`, `${projectRoot}/src/bin.ts`], +}); diff --git a/packages/plugin-eslint/rolldown.config.mjs b/packages/plugin-eslint/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/plugin-eslint/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/plugin-js-packages/package.json b/packages/plugin-js-packages/package.json index da7008b30..0c2ae29c9 100644 --- a/packages/plugin-js-packages/package.json +++ b/packages/plugin-js-packages/package.json @@ -45,7 +45,7 @@ "zod": "^4.0.5" }, "files": [ - "src", + "dist", "!**/*.tsbuildinfo" ] } diff --git a/packages/plugin-js-packages/rolldown.config.mjs b/packages/plugin-js-packages/rolldown.config.mjs new file mode 100644 index 000000000..c8aae84c5 --- /dev/null +++ b/packages/plugin-js-packages/rolldown.config.mjs @@ -0,0 +1,8 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, + entry: [`${projectRoot}/src/index.ts`, `${projectRoot}/src/bin.ts`], +}); diff --git a/packages/plugin-jsdocs/rolldown.config.mjs b/packages/plugin-jsdocs/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/plugin-jsdocs/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/plugin-lighthouse/rolldown.config.mjs b/packages/plugin-lighthouse/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/plugin-lighthouse/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/plugin-typescript/rolldown.config.mjs b/packages/plugin-typescript/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/plugin-typescript/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/packages/utils/rolldown.config.mjs b/packages/utils/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/packages/utils/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/rolldown.base.ts b/rolldown.base.ts new file mode 100644 index 000000000..8cc110fd1 --- /dev/null +++ b/rolldown.base.ts @@ -0,0 +1,355 @@ +import { readFileSync } from 'node:fs'; +import { copyFile, mkdir, readFile, writeFile } from 'node:fs/promises'; +import { dirname, join } from 'node:path'; +import { + type OutputOptions, + type RolldownOptions, + defineConfig, +} from 'rolldown'; + +/** + * Reads and parses package.json from a given path + */ +function readPackageJson(packageJsonPath: string): Record | null { + try { + return JSON.parse(readFileSync(packageJsonPath, 'utf8')); + } catch (error) { + return null; + } +} + +/** + * Extracts all dependencies from package.json to use as external dependencies + */ +function getExternalDependenciesFromPackageJson( + packageJson: Record | null, +): string[] { + if (!packageJson) return []; + + const dependencyTypes = [ + 'dependencies', + 'devDependencies', + 'optionalDependencies', + 'peerDependencies', + ] as const; + + return dependencyTypes.flatMap(type => Object.keys(packageJson[type] || {})); +} + +/** + * Gets additional files to copy from package.json files field + */ +function getAdditionalFilesToCopy( + packageJson: Record | null, +): string[] { + if (!packageJson?.files || !Array.isArray(packageJson.files)) { + return []; + } + + return packageJson.files.filter((file: string) => { + // Skip negation patterns (starting with !) + if (file.startsWith('!')) return false; + // Skip 'src' as it's already handled by the build output + if (file === 'src') return false; + // Include specific files (README, LICENSE, etc.) + return !file.includes('*') && !file.includes('/'); + }); +} + +/** + * Copies a file, creating directories as needed + */ +async function safeCopyFile( + sourcePath: string, + destPath: string, + fileName: string, +): Promise { + try { + await mkdir(dirname(destPath), { recursive: true }); + await copyFile(sourcePath, destPath); + } catch (error) { + console.warn(`Failed to copy ${fileName}:`, error); + } +} + +/** + * Updates package.json paths by removing the dist/ and src/ prefixes + */ +function updatePackageJsonPaths( + packageJson: Record, + hasEsm: boolean, + hasCjs: boolean, +): void { + const pathFields = ['main', 'module', 'types', 'typings'] as const; + + for (const field of pathFields) { + if (packageJson[field]) { + packageJson[field] = packageJson[field] + .replace(/^(\.\/)?dist\//, './') + .replace(/^(\.\/)?src\//, './'); + // Only adjust main to .cjs for CJS-only builds + if (field === 'main' && hasCjs && !hasEsm) { + packageJson[field] = packageJson[field].replace(/\.js$/, '.cjs'); + } + } + } +} + +/** + * Updates bin field with correct extensions and paths + */ +function updateBinField( + packageJson: Record, + hasEsm: boolean, +): void { + if (!packageJson.bin) return; + + if (typeof packageJson.bin === 'string') { + packageJson.bin = packageJson.bin + .replace(/^(\.\/)?dist\//, './') + .replace(/^(\.\/)?src\//, './') + .replace(/\.js$/, hasEsm ? '.js' : '.cjs'); + } else { + packageJson.bin = Object.fromEntries( + Object.entries(packageJson.bin).map(([name, path]) => [ + name, + (path as string) + .replace(/^(\.\/)?dist\//, './') + .replace(/^(\.\/)?src\//, './') + .replace(/\.js$/, hasEsm ? '.js' : '.cjs'), + ]), + ); + } +} + +/** + * Creates an export entry with the appropriate import/require/types fields + */ +function createExportEntry( + path: string, + hasEsm: boolean, + hasCjs: boolean, +): Record { + const entry: Record = {}; + + if (hasEsm) { + entry.import = path.replace(/\.(cjs|mjs)$/, '.js'); + } + if (hasCjs) { + entry.require = path.replace(/\.(js|mjs)$/, '.cjs'); + } + entry.types = path.replace(/\.(c|m)?js$/, '.d.ts'); + + return entry; +} + +/** + * Generates exports field based on build format + */ +function generateExportsField( + hasEsm: boolean, + hasCjs: boolean, +): Record { + const exportPatterns = { + '.': './index.js', + './*': './*/index.js', + './*/': './*/index.js', + './*.js': './*.js', + }; + + return Object.fromEntries( + Object.entries(exportPatterns).map(([key, path]) => [ + key, + createExportEntry(path, hasEsm, hasCjs), + ]), + ); +} + +export interface BaseConfigOptions { + projectRoot: string; + /** + * Entry point pattern or file path. Can be: + * - A string for a single entry point + * - An array of strings for multiple entry points + * - An object mapping entry names to file paths + * @default `${projectRoot}/src/index.ts` + */ + entry?: string | string[] | Record; + /** + * Root directory for preserving module structure + * @default 'src' + */ + preserveModulesRoot?: string; + /** + * Output directory + * @default `${projectRoot}/dist` + */ + outDir?: string; + /** + * Additional external dependencies beyond those in package.json + * @default [] + */ + additionalExternals?: string[]; + /** + * Build formats + * @default ['es'] + */ + formats?: Array<'es' | 'cjs'>; + /** + * Enable sourcemaps + * @default true + */ + sourcemap?: boolean; +} + +export function baseConfig(options: BaseConfigOptions): RolldownOptions { + const { + projectRoot, + entry = `${projectRoot}/src/index.ts`, + preserveModulesRoot = 'src', + outDir = `${projectRoot}/dist`, + additionalExternals = [], + formats = ['es'], + sourcemap = true, + } = options; + + // Read package.json to get dependencies and additional files to copy + const packageJsonPath = join(projectRoot, 'package.json'); + const packageJson = readPackageJson(packageJsonPath); + + const externalDeps = getExternalDependenciesFromPackageJson(packageJson); + const additionalCopyFiles = getAdditionalFilesToCopy(packageJson); + + // Always mark node_modules as external to avoid bundling dependencies + const external = [ + ...new Set([...externalDeps, ...additionalExternals]), + /node_modules/, + ]; + + // Create output configurations for each format + const formatExtensions = { es: '.js', cjs: '.cjs' } as const; + + const outputs: OutputOptions[] = formats.map(format => { + const ext = formatExtensions[format]; + return { + dir: outDir, + format, + sourcemap, + preserveModules: true, + preserveModulesRoot, + entryFileNames: `[name]${ext}`, + chunkFileNames: `[name]${ext}`, + }; + }); + + return defineConfig({ + input: entry, + output: outputs.length > 0 ? outputs : undefined, + external, + plugins: [ + // Plugin to transform relative paths to package.json + { + name: 'transform-package-json-paths', + transform(code, id) { + // Transform relative paths to package.json by removing one ../ level + // This is needed because we build to dist/ instead of dist/src/ + if (code.includes('package.json')) { + // Match any number of ../ and reduce by one level + return code.replace( + /(['"`])((?:\.\.\/)+)(package\.json)\1/g, + (match, quote, dots, file) => { + // Remove one ../ from the path + const newDots = dots.replace(/\.\.\//, ''); + return `${quote}${newDots}${file}${quote}`; + }, + ); + } + return null; + }, + }, + // Custom plugin to copy files and modify package.json after build + { + name: 'copy-files-and-update-package-json', + async closeBundle() { + // Ensure output directory exists + await mkdir(outDir, { recursive: true }); + + // Copy standard files and additional files to dist root + const filesToCopy = [ + 'package.json', + 'README.md', + ...additionalCopyFiles, + ]; + + await Promise.all( + filesToCopy.map(file => + safeCopyFile(join(projectRoot, file), join(outDir, file), file), + ), + ); + + // Update package.json in dist + const distPackageJsonPath = join(outDir, 'package.json'); + try { + const packageJson = JSON.parse( + await readFile(distPackageJsonPath, 'utf8'), + ); + + // Remove fields not needed in published package + const fieldsToRemove = [ + 'devDependencies', + 'scripts', + 'nx', + ] as const; + fieldsToRemove.forEach(field => delete packageJson[field]); + + // Remove files field to include all built output + // (npm will include everything in dist except what's in .npmignore) + delete packageJson.files; + + // Detect which formats were built + const hasEsm = formats.includes('es'); + const hasCjs = formats.includes('cjs'); + + // Update paths, bin field, and exports + updatePackageJsonPaths(packageJson, hasEsm, hasCjs); + updateBinField(packageJson, hasEsm); + packageJson.exports = generateExportsField(hasEsm, hasCjs); + + await writeFile( + distPackageJsonPath, + JSON.stringify(packageJson, null, 2) + '\n', + 'utf8', + ); + } catch (error) { + // If package.json doesn't exist in dist, skip modification + if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { + console.error('Failed to update package.json:', error); + } + } + }, + }, + ], + }); +} + +export function getProjectNameFromActiveTask(): string { + const projectName = process.env['NX_TASK_TARGET_PROJECT']; + + if (!projectName || typeof projectName !== 'string') { + throw new Error('NX_TASK_TARGET_PROJECT is not set'); + } + + return projectName; +} + +export async function getExternalDependencies(cwd: string): Promise { + try { + const packageJson = JSON.parse( + await readFile(join(cwd, 'package.json'), 'utf8'), + ); + return getExternalDependenciesFromPackageJson(packageJson); + } catch { + // No package.json or unable to read it - return empty array + return []; + } +} diff --git a/testing/test-utils/rolldown.config.mjs b/testing/test-utils/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/testing/test-utils/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/tools/eslint-formatter-multi/rolldown.config.mjs b/tools/eslint-formatter-multi/rolldown.config.mjs new file mode 100644 index 000000000..9543b71b9 --- /dev/null +++ b/tools/eslint-formatter-multi/rolldown.config.mjs @@ -0,0 +1,7 @@ +import { baseConfig } from '../../rolldown.base.ts'; + +const projectRoot = import.meta.dirname; + +export default baseConfig({ + projectRoot, +}); diff --git a/tools/src/rolldown.plugin.md b/tools/src/rolldown.plugin.md new file mode 100644 index 000000000..18da7b13d --- /dev/null +++ b/tools/src/rolldown.plugin.md @@ -0,0 +1,107 @@ +# Rolldown Nx Plugin + +An Nx plugin that automatically integrates Rolldown into your build process. + +## Features + +- **Auto-discovery**: Automatically detects projects with `rolldown.config.ts`, `rolldown.config.js`, or `rolldown.config.mjs` files +- **Caching**: Full support for Nx caching to speed up builds +- **Project validation**: Only adds build targets to valid projects (with `package.json` or `project.json`) +- **Dependency tracking**: Properly tracks Rolldown and tsx as external dependencies + +## Installation + +Add the plugin to your `nx.json`: + +```json +{ + "plugins": ["./tools/src/rolldown.plugin.ts"] +} +``` + +Or with custom options: + +```json +{ + "plugins": [ + { + "plugin": "./tools/src/rolldown.plugin.ts", + "options": { + "targetName": "build" + } + } + ] +} +``` + +## Options + +| Option | Type | Default | Description | +| ------------ | -------- | ------- | ---------------------------------- | +| `targetName` | `string` | `build` | Name of the build target to create | + +## Usage + +Once configured, the plugin will automatically create build targets for any project containing a Rolldown config file. + +### Running builds + +```bash +# Build a specific project +nx build my-package + +# Build all projects with Rolldown configs +nx run-many --target=build --all +``` + +### Example project structure + +``` +packages/ + my-package/ + src/ + index.ts + rolldown.config.mjs + package.json +``` + +With the plugin configured, you can run: + +```bash +nx build my-package +``` + +## How it works + +The plugin: + +1. Scans your workspace for `rolldown.config.{ts,js,mjs}` files +2. Validates that the directory contains a valid project +3. Creates a build target using Rolldown's native CLI +4. Configures caching with appropriate inputs and outputs + +The plugin uses the Rolldown CLI directly with the `-c` flag to specify the config file, as documented in the [Rolldown Getting Started guide](https://rolldown.rs/guide/getting-started) + +## Integration with base config + +Works seamlessly with the `rolldown.base.ts` configuration: + +```javascript +// packages/my-package/rolldown.config.mjs +import { baseConfig } from '../../rolldown.base.ts'; + +export default baseConfig({ + projectRoot: import.meta.dirname, + preserveModulesRoot: 'src/lib', +}); +``` + +## Caching + +The plugin is configured with: + +- **Inputs**: `production` files and dependencies +- **Outputs**: `{projectRoot}/dist` directory +- **External dependencies**: `rolldown` and `tsx` + +This ensures that builds are only re-run when source files or dependencies change. diff --git a/tools/src/rolldown.plugin.mjs b/tools/src/rolldown.plugin.mjs new file mode 100644 index 000000000..6113b5398 --- /dev/null +++ b/tools/src/rolldown.plugin.mjs @@ -0,0 +1,90 @@ +import { existsSync } from 'node:fs'; +import { dirname, join } from 'node:path'; + +const ROLLDOWN_CONFIG_GLOB = '**/rolldown.config.{ts,js,mjs}'; + +/** + * Nx plugin to integrate Rolldown into the build process. + * + * @example + * ```json + * { + * "plugins": ["./tools/src/rolldown.plugin.mjs"] + * } + * ``` + * This will automatically add a build target to any project containing a `rolldown.config.ts`, `rolldown.config.js`, or `rolldown.config.mjs` file. + */ +const createNodesV2 = [ + ROLLDOWN_CONFIG_GLOB, + async (configFiles, options, context) => { + return await Promise.all( + configFiles.map(async configFile => { + const projectRoot = dirname(configFile); + const normalizedProjectRoot = projectRoot === '.' ? '' : projectRoot; + + // Check if this is a valid project (has package.json or project.json) + const hasPackageJson = existsSync( + join(context.workspaceRoot, projectRoot, 'package.json'), + ); + const hasProjectJson = existsSync( + join(context.workspaceRoot, projectRoot, 'project.json'), + ); + + if (!hasPackageJson && !hasProjectJson) { + return [configFile, { projects: {} }]; + } + + const targetName = options?.targetName ?? 'build'; + + const targets = { + [targetName]: createRolldownBuildTarget({ projectRoot }), + }; + + const result = { + projects: { + [normalizedProjectRoot]: { + targets, + }, + }, + }; + + return [configFile, result]; + }), + ); + }, +]; + +function createRolldownBuildTarget(options) { + const { projectRoot } = options; + + return { + dependsOn: ['^build'], + executor: 'nx:run-commands', + options: { + command: 'rolldown -c rolldown.config.mjs', + cwd: projectRoot, + outputPath: '{projectRoot}/dist', + }, + cache: true, + inputs: [ + 'production', + '^production', + { + externalDependencies: ['rolldown'], + }, + ], + outputs: ['{projectRoot}/dist'], + metadata: { + description: 'Build the project using Rolldown', + technologies: ['rolldown'], + }, + }; +} + +// Default export for nx.json plugins +const plugin = { + name: '@code-pushup/rolldown-plugin', + createNodesV2, +}; + +export default plugin; diff --git a/tools/src/rolldown.plugin.ts b/tools/src/rolldown.plugin.ts new file mode 100644 index 000000000..0533b088d --- /dev/null +++ b/tools/src/rolldown.plugin.ts @@ -0,0 +1,92 @@ +import { existsSync } from 'node:fs'; +import { dirname, join } from 'node:path'; + +const ROLLDOWN_CONFIG_GLOB = '**/rolldown.config.{ts,js,mjs}'; + +/** + * Nx plugin to integrate Rolldown into the build process. + * + * @example + * ```json + * { + * "plugins": ["./tools/src/rolldown.plugin.ts"] + * } + * ``` + * This will automatically add a build target to any project containing a `rolldown.config.ts`, `rolldown.config.js`, or `rolldown.config.mjs` file. + */ +const createNodesV2 = [ + ROLLDOWN_CONFIG_GLOB, + async (configFiles, options, context) => { + return await Promise.all( + configFiles.map(async configFile => { + const projectRoot = dirname(configFile); + const normalizedProjectRoot = projectRoot === '.' ? '' : projectRoot; + + // Check if this is a valid project (has package.json or project.json) + const hasPackageJson = existsSync( + join(context.workspaceRoot, projectRoot, 'package.json'), + ); + const hasProjectJson = existsSync( + join(context.workspaceRoot, projectRoot, 'project.json'), + ); + + if (!hasPackageJson && !hasProjectJson) { + return [configFile, { projects: {} }]; + } + + const targetName = options?.targetName ?? 'build'; + + const targets = { + [targetName]: createRolldownBuildTarget(configFile, projectRoot), + }; + + const result = { + projects: { + [normalizedProjectRoot]: { + targets, + }, + }, + }; + + return [configFile, result]; + }), + ); + }, +]; + +function createRolldownBuildTarget(configFile, projectRoot) { + // Extract just the config filename from the path + const configFileName = configFile.split('/').pop(); + + return { + dependsOn: ['^build'], + executor: 'nx:run-commands', + options: { + command: `rolldown -c ${configFileName}`, + cwd: projectRoot, + // needed for nx-verdaccio + outputPath: '{projectRoot}/dist', + }, + cache: true, + inputs: [ + 'production', + '^production', + { + externalDependencies: ['rolldown'], + }, + ], + outputs: ['{projectRoot}/dist'], + metadata: { + description: 'Build the project using Rolldown', + technologies: ['rolldown'], + }, + }; +} + +// Default export for nx.json plugins +const plugin = { + name: '@code-pushup/rolldown-plugin', + createNodesV2, +}; + +export default plugin;