Skip to content

build(deps): bump juice from 11.1.1 to 12.0.0 - #1736

Closed
dependabot[bot] wants to merge 1 commit into
masterfrom
dependabot/npm_and_yarn/master/juice-12.0.0
Closed

build(deps): bump juice from 11.1.1 to 12.0.0#1736
dependabot[bot] wants to merge 1 commit into
masterfrom
dependabot/npm_and_yarn/master/juice-12.0.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Jun 4, 2026

Copy link
Copy Markdown
Contributor

Bumps juice from 11.1.1 to 12.0.0.

Release notes

Sourced from juice's releases.

v12.0.0

Juice 12

Modernizes the entire stack: ESM-only, PostCSS-based parsers to support CSS Nesting + spec-correct selector specificity, Node 22.12+ floor, Vitest 4.

Breaking changes

  • Juice is now ESM-only. CJS consumers on Node ≥ 22.12 keep working transparently via Node's built-in require(esm) interop. Older Node versions need to upgrade.
  • Node ≥ 22.12.0 required. Drops support for Node 18 and Node 20. CI matrix is now Node 22, 24, 26.
  • Browser: client.js is ESM. Modern bundlers (Vite, webpack 5, esbuild, Rollup, Parcel 2+) handle it via the "browser" condition in the exports map. Browserify is no longer supported, it cannot parse ESM. README updated to point at modern bundlers.
  • CSS parser swapped: menschpostcss + postcss-safe-parser. Selector parser swapped: slickpostcss-selector-parser. Both old libs were unmaintained since 2022. Inlining semantics unchanged; preserved-CSS output inside <style> blocks is now canonically formatted (mensch had quirks like ;} squashed onto one line). 4 fixture .out files refreshed to match.
  • Spec-correct selector specificity for :is(), :where(), :has(), :not() per CSS Selectors Level 4: :where(...) contributes 0, the others contribute max(spec(args)). Previously juice treated all four as a generic :pseudo and :not used "first arg only" (a slick legacy). Any cascade resolution that depended on the old quirks will produce different inlined styles.
  • commander upgraded to v14, entities upgraded to v8 (ESM-only), cheerio pinned to 1.2.0.
  • TypeScript declarations renamed juice.d.ts → index.d.ts and restructured for ESM default-export resolution. Import as import juice from 'juice'.

New features

  • CSS Nesting (Level 1) is supported. Nested rules (.card { &:hover { ... } }), nested at-rules (.card { @media (...) { ... } }), the & parent selector, and bare nested selectors (per the 2023 CSSWG resolution) are flattened via postcss-nesting before inlining. Previously these were silently dropped. No behavior change for already-flat CSS.
  • @container and @layer at-rules are preserved through inlining (mirrors how @media/@font-face/@keyframes already worked). New options preserveContainerQueries and preserveLayers default to true.
  • Long-standing crashes/hangs in :not(a, b, …) are gone as a side effect of the parser swap — the underlying causes of #390, #471, and #398 were quirks in mensch/slick that don't exist in postcss.
  • TypeScript types ship via the types condition in exports and resolve correctly under nodenext module resolution.

Tooling

  • Test runner: Mocha → Vitest 4 with @vitest/coverage-v8. New scripts: npm test, npm run test:watch, npm run coverage. The previously broken testcover script is gone.
  • CLI extraction: bin/juice's logic moved into lib/cli.js as a testable cli.run(argv, deps) with dependency injection. The bin itself is now a 3-line ESM shim.
  • Test files renamed: cli.js → cli.test.js, test.js → integration.test.js, run.js → cases.test.js. TypeScript test now uses a dedicated test/typescript/tsconfig.json with nodenext resolution.
  • Test assertions migrated from Node's assert to Vitest's expect: better failure diffs, more matchers, idiomatic.
  • Removed devDependencies: mocha, should, batch, browserify. Added: vitest, @vitest/coverage-v8, postcss, postcss-safe-parser, postcss-selector-parser, postcss-nesting.

Migration notes

Scenario Action needed
Node 18 or 20 user Upgrade to Node 22.12+
const juice = require('juice') on Node ≥22.12 None, require(esm) handles it
const juice = require('juice') on older Node Upgrade Node, or switch to import juice from 'juice'
TypeScript import juice = require('juice') Switch to import juice from 'juice'
juice/client via Browserify Switch bundler (Vite, webpack 5, esbuild, Rollup, Parcel 2+)
Using :is/:where/:has in email CSS Specificity is now per-spec; cascade may resolve differently
Using @container or @layer They now pass through inlining instead of being silently dropped
Using CSS Nesting Was silently dropped — now flattened and inlined correctly

Fixes #390, fixes #392, fixes #398, fixes #403, fixes #471, fixes #557, fixes #587, fixes #593


... (truncated)

Changelog

Sourced from juice's changelog.

Unreleased

Breaking changes

  • Juice is now ESM-only. Consumers using require('juice') from CJS on Node ≥ 22.12 will continue to work via Node's built-in require(esm) interop. CJS consumers on older Node versions will need to migrate to import or upgrade Node.
  • Node ≥ 22.12.0 required. Dropped support for Node 18 and Node 20. CI now runs on Node 22, 24, and 26.
  • Browser: the package's client.js entry is now ESM. Modern bundlers (Vite, webpack 5, esbuild, Rollup, Parcel 2+) handle it transparently via the "browser" condition in exports. Browserify is no longer supported — it cannot parse ESM.
  • CSS parser replaced: menschpostcss + postcss-safe-parser. Selector parser replaced: slickpostcss-selector-parser. Both old libs were unmaintained since 2022 and mis-handled modern CSS. Inlining behaviour is unchanged; preserved-CSS output inside <style> blocks is now canonically formatted (fixes mensch quirks like ;} squashed on one line and 0%,\n100% selector splits).
  • Specificity is now spec-correct for :is(), :where(), :has(), and :not() (CSS Selectors Level 4). :where(...) contributes 0; :is(...), :has(...), and :not(...) contribute the maximum specificity across their arguments. Previously juice treated all four as a generic :pseudo and :not used "first argument only" (a slick legacy). Any cascade resolution that depended on the old quirks will produce different inlined styles.
  • @container and @layer at-rules are now preserved through inlining (mirroring @media / @font-face / @keyframes). New options preserveContainerQueries and preserveLayers default to true; pass false to drop them. Note: @layer is preserved verbatim only — layer-aware cascade resolution is not implemented (email clients don't support layers anyway).
  • CSS Nesting is now supported. Nested rules (.card { &:hover { ... } }), nested at-rules (.card { @media (min-width: 600px) { ... } }), and the & parent selector are flattened via postcss-nesting before inlining. Previously, nested rules were silently dropped during parsing. No behaviour change for already-flat CSS.
  • commander upgraded to v14. Positional CLI arguments are now declared explicitly via .argument() (commander v14 errors on excess undeclared args).
  • entities upgraded to v8 (ESM-only).
  • cheerio pinned to 1.2.0.
  • TypeScript declarations renamed juice.d.ts → index.d.ts and restructured for ESM default-export resolution (import juice from 'juice').
  • Test runner migrated from Mocha to Vitest 4.

Tooling

  • npm test now runs vitest run --coverage && npm run test-typescript.
  • New npm run coverage script using @vitest/coverage-v8 (replaces the previously broken testcover script).
  • New npm run test:watch for interactive development.
  • Test files renamed: test/cli.js → test/cli.test.js, test/test.js → test/integration.test.js, test/run.js → test/cases.test.js.
  • bin/juice extracted: the CLI logic now lives in lib/cli.js as a testable cli.run(argv, deps) function with dependency injection. The bin itself is a 3-line ESM shim.
  • TypeScript test now uses a dedicated test/typescript/tsconfig.json with nodenext module resolution.
  • Removed devDependencies: mocha, should, batch, browserify. Added: vitest, @vitest/coverage-v8.
  • package.json now declares "type": "module" and an "exports" map with types / browser / default conditions.
Commits
  • 5afeb21 12.0.0
  • aafcd94 Merge pull request #612 from Automattic/juice-12
  • ac5f477 12.0.0-beta.2
  • 7c4e394 feat: add data-juice-duplicates attribute
  • 826aa05 Merge branch 'master' into juice-12
  • 40744f4 Merge pull request #617 from Automattic/dependabot/npm_and_yarn/qs-6.15.2
  • f668dba Merge pull request #616 from Automattic/dependabot/npm_and_yarn/js-yaml-4.2.0
  • 04aa65a Merge pull request #615 from Automattic/dependabot/npm_and_yarn/multi-770cfcd984
  • 775c59b Merge pull request #618 from Automattic/dependabot/npm_and_yarn/undici-6.26.0
  • b3076c2 build(deps): bump undici from 6.21.3 to 6.26.0
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [juice](https://github.com/Automattic/juice) from 11.1.1 to 12.0.0.
- [Release notes](https://github.com/Automattic/juice/releases)
- [Changelog](https://github.com/Automattic/juice/blob/master/CHANGELOG.md)
- [Commits](Automattic/juice@v11.1.1...v12.0.0)

---
updated-dependencies:
- dependency-name: juice
  dependency-version: 12.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Jun 4, 2026
@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
Updatedjuice@​11.1.1 ⏵ 12.0.0100100100 +195 +1100

View full report

@cossssmin cossssmin closed this Jun 4, 2026
@dependabot @github

dependabot Bot commented on behalf of github Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting @dependabot ignore this major version or @dependabot ignore this minor version. You can also ignore all major, minor, or patch releases for a dependency by adding an ignore condition with the desired update_types to your config file.

If you change your mind, just re-open this PR and I'll resolve any conflicts on it.

@dependabot
dependabot Bot deleted the dependabot/npm_and_yarn/master/juice-12.0.0 branch June 4, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant