Skip to content

chore: bundle CLI with esbuild#2866

Open
AlbinaBlazhko17 wants to merge 22 commits into
mainfrom
feat/esbuild-bundle-cli
Open

chore: bundle CLI with esbuild#2866
AlbinaBlazhko17 wants to merge 22 commits into
mainfrom
feat/esbuild-bundle-cli

Conversation

@AlbinaBlazhko17

@AlbinaBlazhko17 AlbinaBlazhko17 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

What/Why/How?

Switched @redocly/cli to bundle with esbuild and produce one dependency-free file.

  • Added scripts/build.mjs - esbuild config that bundles src/index.tslib/index.js
  • Added scripts/prepare-publish-dir.mjs - creates a .publish staging directory with a minimal package.json (no dependencies) and only the files that need to be published
  • Changed scripts/local-pack.sh - pack:prepare now builds and packs from .publish
  • Removed packages/cli from tsconfig.build.json references - tsc no longer compiles the CLI
  • Inlined template.hbs as a string constant in build-docs/utils.ts as a fallback - esbuild does not copy assets, so resolveTemplateSource tries to read the file first and falls back to the embedded template
  • Simplified package.ts - replaced createRequire with a static JSON import, which esbuild handles natively
  • Removed pin-intersecting-deps.sh and all yarn cache workarounds from smoke tests - no transitive deps means no version conflicts to pin

Reference

Testing

Locally, in CI, in other products.

Screenshots (optional)

Check yourself

  • This PR follows the contributing guide
  • All new/updated code is covered by tests
  • Core code changed? - Tested with other Redocly products (internal contributions only)
  • New package installed? - Tested in different environments (browser/node)
  • Documentation update has been considered

Security

  • The security impact of the change has been considered
  • Code follows company security practices and guidelines

Note

Medium Risk
This changes how every consumer installs and runs the CLI (single bundled artifact vs transitive deps), so regressions would affect all commands and platforms; mitigated by updated smoke, snapshot, and Docker publish paths.

Overview
Bundles @redocly/cli with esbuild so the published tarball ships only bin/, bundled lib/, and metadata—no runtime dependencies. Workspace packages (openapi-core, respect-core) and former CLI deps are folded into the bundle at build time; the CLI workspace manifest keeps them as devDependencies for development and bundling.

Build & publish pipeline: packages/cli/scripts/build.mjs produces ESM output under lib/; prepare-publish-dir.mjs stages .publish with a stripped package.json and root README/LICENSE. Root compile runs compile:cli:bundle instead of tsc for the CLI (CLI removed from tsconfig.build.json). npm run release uses scripts/release-publish.mjs to stage .publish before changeset publish; snapshot release, local-pack.sh, and Docker pack:prepare follow the same publish-dir flow.

Runtime tweaks for bundling: build-docs is lazy-imported; default Handlebars template is embedded when template.hbs is not on disk; Redoc version comes from devDependencies.redoc via static JSON import in package.ts. Scorecard plugin evaluation sets __redocly_dirname from the config directory via pathToFileURL.

CI/smoke: Yarn/npm smoke jobs drop cache-cleaning, pin-intersecting-deps, and retry loops; Dockerfile no longer copies template.hbs after global install.

Reviewed by Cursor Bugbot for commit dc2437d. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: dc2437d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@redocly/cli Patch
@redocly/openapi-core Patch
@redocly/respect-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 81.18% (🎯 81%) 7276 / 8962
🔵 Statements 80.54% (🎯 80%) 7562 / 9389
🔵 Functions 84.4% (🎯 84%) 1461 / 1731
🔵 Branches 72.82% (🎯 72%) 4914 / 6748
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/cli/src/commands/build-docs/index.ts 93.75% 50% 100% 93.75% 55
packages/cli/src/commands/build-docs/utils.ts 59.45% 33.33% 85.71% 61.11% 51-72, 127, 134, 149
packages/cli/src/commands/scorecard-classic/validation/plugin-evaluator.ts 83.33% 76.19% 100% 82.75% 17, 59-62
packages/cli/src/commands/scorecard-classic/validation/validate-scorecard.ts 80% 73.68% 100% 79.16% 52-54, 72-92
packages/cli/src/utils/package.ts 100% 100% 100% 100%
Generated in workflow #10223 for commit dc2437d by the Vitest Coverage Report Action

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Performance Benchmark (Lower is Faster)

CLI Version Bundle Lint Check Config
cli-latest ▓▓▓▓▓▓▓▓▓ 1.29x ± 0.02 ▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 1.44x ± 0.02 ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ 1.89x ± 0.01
cli-next ▓ 1.00x (Fastest) ▓ 1.00x (Fastest) ▓ 1.00x (Fastest)

"types": "lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed order of the exports to avoid warnings. Made the same changes for respect-core.
Image

Comment thread Dockerfile
WORKDIR /build
COPY . .
RUN apk add --no-cache jq git && \
npm ci --no-optional --ignore-scripts && \

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to skip deps under optionalDependencies, because we don't have deps at all.

Comment thread package.json
"release": "node ./scripts/release-publish.mjs",
"pack:prepare": "./scripts/local-pack.sh",
"respect:parser:generate": "pegjs --format es --output packages/respect-core/lib/modules/runtime-expressions/abnf-parser.js packages/respect-core/src/modules/runtime-expressions/abnf-parser.pegjs && cp packages/respect-core/lib/modules/runtime-expressions/abnf-parser.js packages/respect-core/src/modules/runtime-expressions/abnf-parser.js",
"build-docs:copy-assets": "cp packages/cli/src/commands/build-docs/template.hbs packages/cli/lib/commands/build-docs/template.hbs ",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need any templates inside lib folder. We only have lib/index.js.

@AlbinaBlazhko17 AlbinaBlazhko17 self-assigned this Jun 11, 2026
@AlbinaBlazhko17 AlbinaBlazhko17 added the snapshot Create experimental release PR label Jun 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📦 A new experimental 🧪 version v0.0.0-snapshot.1781184257 of Redocly CLI has been published for testing.

Install with NPM:

npm install @redocly/cli@0.0.0-snapshot.1781184257

⚠️ Note: This is a development build and may contain unstable features.

@AlbinaBlazhko17 AlbinaBlazhko17 marked this pull request as ready for review June 12, 2026 07:36
@AlbinaBlazhko17 AlbinaBlazhko17 requested review from a team as code owners June 12, 2026 07:36
Comment thread packages/cli/package.json
"@redocly/cli-otel": "0.3.1",
"@redocly/openapi-core": "2.32.2",
"@redocly/respect-core": "2.32.2",
"ajv": "npm:@redocly/ajv@8.18.1",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed directly unused deps in CLI, because we bundled all deps together.

Comment thread packages/cli/scripts/build.mjs
Comment thread packages/cli/scripts/build.mjs

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit dd57cea. Configure here.

Comment thread .github/workflows/release.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

snapshot Create experimental release PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants