I reproduced the issue in a clean stonking container and verified the
fix.
Root Cause & Context:
Upstream cheerio 1.2.0 was designed as a hybrid package built with tshy,
providing both ESM and CommonJS exports.
In debian/patches/debian-build-adjustments.patch, the "require" export
conditions were dropped and tshy was constrained to "dialects": ["esm"],
stripping dist/commonjs from the binary package.
In Debian unstable, the maintainer recently adapted Debian to this change by
uploading eslint 6.4.0~dfsg+~6.1.9-14 (which switches the HTML formatter test
to dynamic import("cheerio")) and node-cheerio 1.2.0+~cs2.1.0-3 (with Breaks:
eslint << 6.4.0~dfsg+~6.1.9-14~).
However, due to Ubuntu's Debian Import Freeze for stonking, neither package
synced to Ubuntu. node-cheerio 1.2.0+~cs2.1.0-2 remained stranded in
stonking-proposed, breaking against Ubuntu's eslint 6.4.0~dfsg+~6.1.9-13 and
blocking the node-parse5 migration.
Restoring the CommonJS build in node-cheerio is the cleanest solution: it
preserves backward compatibility for CommonJS consumers without forcing
downstream packages to rewrite their imports.
Fix:
1. Revert the package.json modification in
debian/patches/debian-build-adjustments.patch so tshy builds dist/commonjs
alongside dist/esm and keeps the "require" export map.
2. Add .tshy/ to debian/clean.
Verification:
- Clean build of node-cheerio 1.2.0+~cs2.1.0-2ubuntu1 source and binary
packages.
- Direct CommonJS require test:
$ node -e 'const cheerio = require("cheerio"); console.log(cheerio.load("<h2
class=\"title\">Hello</h2>")("h2.title").text())'
Result: prints "Hello", exit code 0.
- cheerio-select require test:
$ node -e 'require("cheerio-select")'
Result: exit code 0.
- eslint html formatter test:
$ NODE_PATH=tools eslint --format tap tests/lib/cli-engine/formatters/html.js
Result: ok 1 (passes cleanly; was failing before with ruleId:
node/no-missing-require).
- Mocha test suite:
11 passing (79ms).
Attached debdiff node-cheerio_1.2.0+~cs2.1.0-2ubuntu1.debdiff against
1.2.0+~cs2.1.0-2.
Forwarded to Debian BTS: https://bugs.debian.org/cgi-
bin/bugreport.cgi?bug=1149801
** Description changed:
- node-cheerio 1.2.0+~cs2.1.0-2 in stonking-proposed cannot be loaded with
- require(), which breaks CommonJS consumers. This blocks node-cheerio
- from migrating and, through it, node-parse5 and node-jsdom.
+ [ Impact ]
+ node-cheerio 1.2.0+~cs2.1.0-2 in stonking-proposed cannot be loaded via
require(), failing with ERR_PACKAGE_PATH_NOT_EXPORTED.
+ This causes an autopkgtest regression in eslint (6.4.0~dfsg+~6.1.9-13) and
blocks node-cheerio from migrating into stonking.
+ Because node-cheerio is blocked, node-parse5 (8.0.1+dfsg-3build3) is also
held in proposed (it breaks node-cheerio << 1.2~), which in turn blocks
node-jsdom and renders multiple packages (jest, ts-jest, jupyterlab,
node-jupyter-widgets-*, etc.) uninstallable.
+
+ [ Fix ]
+ In debian/patches/debian-build-adjustments.patch, revert the hunk that
stripped the "require" export conditions from package.json and restricted tshy
to "dialects": ["esm"].
+ This allows tshy to build dist/commonjs alongside dist/esm, restoring full
CommonJS compatibility as intended by upstream cheerio 1.2.0.
+ Also add .tshy/ to debian/clean to ensure reproducible clean builds.
+
+ [ Test Plan ]
+ 1. Direct CommonJS require test:
+ $ node -e 'const cheerio = require("cheerio");
console.log(cheerio.load("<h2 class=\"title\">Hello</h2>")("h2.title").text())'
+ Expected output: "Hello" (exit code 0).
+ 2. cheerio-select require test:
+ $ node -e 'require("cheerio-select")'
+ Expected: exits 0 without error.
+ 3. eslint autopkgtest test case:
+ $ NODE_PATH=tools eslint --format tap
tests/lib/cli-engine/formatters/html.js
+ Expected output: ok 1 (passes cleanly; was failing before with ruleId:
node/no-missing-require).
+ $ mocha tests/lib/cli-engine/formatters/html.js
+ Expected output: 11 passing.
+
+ [ Where problems could occur ]
+ The fix restores the upstream-supported CommonJS build (dist/commonjs). The
ESM build in dist/esm and browser build in dist/browser remain completely
unchanged. Since this broadens export conditions rather than restricting them,
the risk of regression is negligible.
+
+ [ Other Info ]
+ - Upstream status: Upstream cheerio 1.2.0 is built with tshy and natively
supports both ESM and CommonJS exports.
+ - Debian status: In Debian unstable, the maintainer treated cheerio as
ESM-only and uploaded eslint 6.4.0~dfsg+~6.1.9-14 (adapting its test to dynamic
import()) and node-cheerio 1.2.0+~cs2.1.0-3 (with Breaks: eslint <<
6.4.0~dfsg+~6.1.9-14~). However, because stonking reached Debian Import Freeze,
those packages never synced to Ubuntu. Restoring CommonJS in node-cheerio is
strictly better as it preserves backward compatibility for all CommonJS
consumers without requiring changes to reverse dependencies.
+ - Target: Ubuntu 26.10 (stonking devel).
+ - Package builds cleanly, debdiff has 0 rejects.
+
+ --- [ Original Report ]
+ node-cheerio 1.2.0+~cs2.1.0-2 in stonking-proposed cannot be loaded with
require(), which breaks CommonJS consumers. This blocks node-cheerio from
migrating and, through it, node-parse5 and node-jsdom.
Symptom: the eslint autopkgtest fails on every architecture (amd64, amd64v3,
arm64, armhf, ppc64el) when triggered by node-cheerio/1.2.0+~cs2.1.0-2:
not ok 381 - tests/lib/cli-engine/formatters/html.js
message: '"cheerio" is not found.' ruleId: node/no-missing-require
https://autopkgtest.ubuntu.com/results/autopkgtest-stonking/stonking/amd64/e/eslint/20260928_111538_1192f@/log.gz
Reproducer (Node 24.19, stonking-proposed):
$ node -e 'require("cheerio")'
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in
/usr/share/nodejs/cheerio/package.json
Cause: upstream cheerio 1.2.0 is a dual CJS and ESM package built with tshy,
and its exports include
"require": { "types": "./dist/commonjs/index.d.ts", "default":
"./dist/commonjs/index.js" }
debian/patches/debian-build-adjustments.patch removes the "require"
conditions for ".", "./slim" and "./utils" and sets the tshy "dialects" to
["esm"]. The binary package therefore ships only dist/esm and dist/browser,
with no dist/commonjs. None of the other changes in that patch (TypeScript 5.2
compatibility, the cheerio-select adapter fix, dropping
fromURL/loadBuffer/stream helpers) appear to need ESM-only output.
Impact on proposed-migration: node-parse5 8.0.1+dfsg-3build3 Breaks
node-cheerio (<< 1.2~) and node-jsdom (<< 20.0.3+~cs124.18.21-7~).
Because node-cheerio is not a candidate, node-parse5 makes jest, ts-
jest, node-jest-react, jupyterlab, node-jupyter-widgets-*, node-bqplot,
node-ipydatagrid, node-jsdom, node-cheerio, node-http-server,
perlnavigator and python-ipywidgets-doc uninstallable, so it stays in
proposed. node-jsdom -10build3 is in turn held behind node-parse5.
Suggested fix: keep the CommonJS dialect ("dialects": ["esm",
"commonjs"]) and the "require" export conditions in debian-build-
adjustments.patch, so that dist/commonjs is built and shipped again.
This should also be fixed in Debian, where no bug has been reported yet.
** Patch added: "node-cheerio 1.2.0+~cs2.1.0-2ubuntu1 debdiff for stonking"
https://bugs.launchpad.net/ubuntu/+source/node-cheerio/+bug/2169270/+attachment/6005134/+files/node-cheerio_1.2.0+~cs2.1.0-2ubuntu1.debdiff
** Tags added: patch stonking
** Changed in: node-cheerio (Ubuntu)
Status: New => Confirmed
** Changed in: node-parse5 (Ubuntu)
Status: New => Confirmed
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2169270
Title:
node-cheerio 1.2.0 is ESM-only: require("cheerio") fails with
ERR_PACKAGE_PATH_NOT_EXPORTED (eslint autopkgtest regression, blocks
node-parse5)
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/node-cheerio/+bug/2169270/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs