Skip to content

build(deps): bump 5 deps to latest major + fix ESM module loading - #152

Merged
megheaiulian merged 3 commits into
mainfrom
chore/bump-deps-major-a
Jul 31, 2026
Merged

build(deps): bump 5 deps to latest major + fix ESM module loading#152
megheaiulian merged 3 commits into
mainfrom
chore/bump-deps-major-a

Conversation

@megheaiulian

Copy link
Copy Markdown

Summary

Phase 2 Batch A — 5 isolated major dep bumps, plus bug fixes required to support ESM-only packages with exports fields in the module loader.

Major dep bumps

Dep From To Breaking change Our usage affected?
mime-types 2.x 3.0.2 Node >=18, mime-score resolution No — lookup() API unchanged
cosmiconfig 8.x 9.0.2 searchStrategy defaults to none Fixed — added searchStrategy: 'global'
p-queue 8.x 9.3.3 Node >=20 No — concurrency, .add() unchanged
sugarss 4.x 5.0.1 Node >=18 No — parser interface unchanged
postcss-custom-properties 14.x 15.0.1 ESM-only, Node >=20.19 No — options unchanged

Also bumped @types/mime-types 2→3 (matching types) and engines.node to >=20.19.0 (was already required by sass 1.102 from Phase 1 PR #151).

Bug fixes (required by postcss-custom-properties v15)

postcss-custom-properties v15 is ESM-only with a nested exports map ({".": {types:..., default:...}}). This exposed two pre-existing bugs in the module loader:

1. fix(resolve): handle array returns from resolveExports

resolveExports() returns string[] for packages with nested exports maps, but packageFilterBuilder only checked typeof === 'string', missing array results. Added array handling.

2. fix(load-module): async with ESM fallback

  • require() of .mjs files fails in jest VM context ("Must use import to load ES Module"). Added fallback to await import() when require() fails.
  • Replaced no-op packageFilter: pkg => pkg with packageFilterBuilder() so packages with only an exports field (no main/module) can be resolved.

Ripple changes (making sync code async)

  • ensurePCSSOption/ensurePCSSPlugins → async
  • PostCSS loader: resolve parser/syntax/stringifier/plugins lazily in async process() instead of eagerly in sync plugin factory
  • config.ts: await async calls
  • types.ts: postcss sub-options accept string (resolved lazily)
  • Tests: updated to async (await loadModule(...), rejects.toThrowErrorMatchingSnapshot())

cosmiconfig behavior preservation

Added searchStrategy: 'global' to preserve v8's default upward directory traversal behavior (v9 defaults to none). Test fixtures have co-located configs, but real users may rely on parent-dir config discovery.

Verification

  • npm run lint (prettier + eslint)
  • npm run build (rollup + type emit)
  • npm test — 4 suites, 113 tests, 314 snapshots pass (no snapshot changes)

What's next

  • Batch B: eslint 8→10 + @typescript-eslint 7→8 + eslint plugins (flat config migration)
  • Batch C: jest 29→30 + babel-jest + @types/jest (snapshot format changes)
  • Batch D: @babel 7→8 + typescript 5→7
  • Batch E: remaining majors

Major bumps (Batch A):
- mime-types 2->3 (Node >=18, mime-score resolution; lookup() API unchanged)
- cosmiconfig 8->9 (add searchStrategy: 'global' to preserve upward dir traversal)
- p-queue 8->9 (Node >=20; API surface unchanged)
- sugarss 4->5 (Node >=18; parser interface unchanged)
- postcss-custom-properties 14->15 (Node >=20.19; ESM-only, options unchanged)
- @types/mime-types 2->3 (matching types; lookup() signature identical)
- engines.node: >=20.19.0 (was already required by sass 1.102 from Phase 1)

Bug fixes required by postcss-custom-properties v15 (ESM-only with exports):
- fix(resolve): handle array returns from resolveExports in packageFilterBuilder
  (resolveExports returns string[] for packages with nested exports maps;
  the existing code only checked typeof === 'string', missing array results)
- fix(load-module): make async with ESM fallback via dynamic import()
  (require() of .mjs fails in jest VM context; fall back to await import())
  Uses packageFilterBuilder() instead of no-op packageFilter to resolve
  packages that only have an exports field (no main/module)
- fix(options): make ensurePCSSOption/ensurePCSSPlugins async
- fix(postcss/index): resolve parser/syntax/stringifier/plugins lazily
  in async process() instead of eagerly in sync plugin factory
- fix(config): await async ensurePCSSOption/ensurePCSSPlugins calls
- fix(types): postcss sub-options accept string (resolved lazily)
- fix(tests): update load-module/ensurePCSSOption tests to async
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.97%. Comparing base (8f250a7) to head (e2b2a27).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #152      +/-   ##
==========================================
+ Coverage   98.75%   98.97%   +0.22%     
==========================================
  Files          36       36              
  Lines         962      974      +12     
  Branches      313      317       +4     
==========================================
+ Hits          950      964      +14     
+ Misses         12       10       -2     

☔ 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.

Add unit test for ensurePCSSPlugins([[autoprefixer]]) which exercises
the else branch (line 99) where a plugin is specified as an array with
only the name and no options object. Resolves codecov patch coverage.
loadModule now resolves and loads ESM-only packages that only have an
exports field (no main/module). Falls back to dynamic import() when
require() fails for .mjs files (e.g. in jest VM context).

packageFilterBuilder handles array returns from resolveExports, which
is the return type for all modern package exports shapes (flat and
nested).

parser/syntax/stringifier/plugins options are now resolved lazily in
the async postcss process() hook instead of eagerly in the sync plugin
factory, enabling async module loading.
@megheaiulian
megheaiulian merged commit 612f2e6 into main Jul 31, 2026
17 checks passed
@megheaiulian
megheaiulian deleted the chore/bump-deps-major-a branch July 31, 2026 07:06
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant