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

Reply via email to