Skip to content

feat: minify a precompiled check - #235

Merged
alexander-akait merged 3 commits into
mainfrom
feat/precompile-minify
Oct 18, 2026
Merged

alexander-akait merged 3 commits into
mainfrom
feat/precompile-minify

Conversation

@alexander-akait

@alexander-akait alexander-akait commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

Summary

A check from schema-utils precompile is loaded every time the tool that ships it starts. For webpack's own options it comes out at 983 KB and takes ~21 ms to load. webpack's tooling/precompile-schemas.js produces 423 KB that loads in ~13 ms, so webpack can't switch to schema-utils precompile without slowing every start.

--minify (or precompile(schema, { minify: true })) closes that gap:

  • Drops the error objects a check never reports. This uses the same regex as webpack's tooling.
  • Inlines equal and ucs2length. Both are small and self-contained, and loading them through schema-utils/dist/runtime costs ~1.3 ms, more than a check takes to run. uri still comes from the runtime.
  • Defines the absolutePath regex once with ajv's gen.scopeValue, instead of writing it out at every use (56 places for webpack) and creating a new RegExp on every call.
  • Minifies with terser, using the same settings as webpack. terser is an optional peer dependency, loaded only for minify, with a clear error when it's missing. ES module checks are minified as modules.

Measurements

webpack's WebpackOptions.json, median of 21 fresh Node 22 processes:

Size Load First call
precompile (current) 983 KB 21.0 ms 4.3 ms
precompile --minify 438 KB 13.2 ms 3.9 ms
webpack's own check 423 KB 13.2 ms 3.7 ms

The remaining ~15 KB is ucs2length. webpack's check uses .length for minLength, which accepts a single emoji for minLength: 2 where validate rejects it. That's the unsafe direction for a check, so the minified check keeps counting characters the way validate does.

Compatibility

Without --minify, the output is byte-identical to 4.7. Checks already committed, such as minimizer-webpack-plugin's, stay up to date under --check. All of the changes above apply only with --minify.

Tests

  • I ran the full parity suite (every schema/value case compares a check with full validation) once locally with every check minified. All 1038 cases agree.
  • New tests:
    • no error objects or requires, and the regex written once;
    • correct results, including astral characters, enum objects and absolutePath;
    • ES module output stays an ES module;
    • the error when terser is missing;
    • the CLI: --minify writes the minified check, and --check with --minify passes on it, while --check without --minify reports it out of date.
  • npm run lint and the full suite (1043 tests) pass. Coverage is 100% statements in cli.js and 99% in precompile.js.

Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added a --minify option to precompilation, also available through the precompile API. It generates smaller checks that load faster while preserving validation behavior.
    • Minification omits error details a check would not report. Terser must be installed to use this option.
  • Documentation
    • Updated precompilation guidance with minification details and performance examples. Use the same minification setting when generating and checking precompiled output.

`schema-utils precompile --minify` and `precompile(schema, { minify: true })`
drop the error objects a check never reports, write the `equal` and
`ucs2length` helpers into the check instead of loading them from
`schema-utils`, keep the `absolutePath` regex in one constant, and minify
with terser, an optional peer dependency.

For webpack's options the check goes from 983 KB to 438 KB and loads in
13ms instead of 21ms, the same as webpack's own tooling/precompile-schemas.js
output, while still counting characters the way `validate` does.

Without --minify the output is byte-identical, so checks generated with
4.6/4.7 stay up to date.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QYPkbvwyRWt2SHgXDoYRdo
@codecov

codecov Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.21%. Comparing base (f0e381d) to head (665060b).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #235      +/-   ##
==========================================
+ Coverage   97.17%   97.21%   +0.03%     
==========================================
  Files          13       13              
  Lines        1204     1220      +16     
  Branches      465      472       +7     
==========================================
+ Hits         1170     1186      +16     
  Misses         32       32              
  Partials        2        2              
Flag Coverage Δ
integration 97.21% <100.00%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 34 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 46fec07d-1e37-445d-a346-89099cb462f7
📥 Commits

Reviewing files that changed from the base of the PR and between 1a6ba01 and 665060b.

⛔ Files ignored due to path filters: 1
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing: 7
  • .changeset/precompile-minify.md
  • README.md
  • declarations/precompile.d.ts
  • package.json
  • src/cli.js
  • src/precompile.js
  • test/precompile.test.js

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ff8dde11-a15a-47c1-8f6d-2321a3fee516
📥 Commits

Reviewing files that changed from the base of the PR and between dd1e1a5 and 1a6ba01.

📒 Files selected for processing: 2
  • src/precompile.js
  • test/precompile.test.js
🚧 Files skipped from review as they are similar to previous changes: 1
  • test/precompile.test.js

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.

Walkthrough

The precompile API and CLI now support a minify option. When enabled, code generation inlines selected helpers and uses Terser to minify generated checks. The option is documented, and tests cover generated output, validation behavior, missing Terser, and CLI checks.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 1a6ba

Minified checks preserve the reported schema-pattern behavior, and no actionable merge risk remains.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: adding minification for precompiled checks.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 5 files.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ee8e9462-fa2b-4ee7-8706-ae4b63d0659e
📥 Commits

Reviewing files that changed from the base of the PR and between f0e381d and dd1e1a5.

⛔ Files ignored due to path filters: 1
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing: 8
  • .changeset/precompile-minify.md
  • README.md
  • declarations/precompile.d.ts
  • package.json
  • src/cli.js
  • src/precompile.js
  • test/helpers/precompiled.js
  • test/precompile.test.js

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

Comment thread src/precompile.js
alexander-akait and others added 2 commits October 18, 2026 19:03
The regex removing error objects also matched a schema string or pattern
that only looked like one, such as `\{instancePathx,keyword:y,`, and
changed what it matched. It now needs the assignment and the exact shape
ajv writes. webpack's minified options check is byte-identical.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QYPkbvwyRWt2SHgXDoYRdo
Use webpack's own JavaScript minifier (webpack 5.112.0 or later, an
optional peer) instead of terser, so --minify needs nothing beyond
webpack itself.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QYPkbvwyRWt2SHgXDoYRdo
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatedwebpack@​5.110.3 ⏵ 5.112.081 -1210093 +197 -2100

View full report

@alexander-akait
alexander-akait merged commit 898f9a0 into main Oct 18, 2026
33 checks passed
@alexander-akait
alexander-akait deleted the feat/precompile-minify branch October 18, 2026 21:53
@lorenzodallavecchia

Copy link
Copy Markdown

Just letting you know that the new peer dependency breaks builds that already use a webpack 5.x version older than 5.112. Strictly speaking, this is a breaking change: we should have declared 5.0.0 as a peer dependency.
In most cases, the quickest solution is just updating webpack to 5.112 or later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants