labext: use caret ranges so jlpm dedups JupyterLab/Lumino singletons

The exact pins introduced earlier (@jupyterlab/* 4.6.0, @lumino/widgets
2.8.0, @jupyterlab/builder 4.5.9) break the Dockerfile.studio
labext-builder stage. Exact-pinning the framework packages defeats
jlpm's (yarn classic) hoisting: transitive @jupyterlab deps request
caret ranges that resolve to newer patch releases (e.g. @jupyterlab/
notebook pulls @jupyterlab/cells ^4.6.0 -> a newer patch), so jlpm
installs a second nested copy alongside the exact top-level one. Two
copies of @jupyterlab/cells and @lumino/widgets in the tree produce
TS2345 "not assignable" errors (protected-member/identity mismatch)
and the build fails.

Caret ranges let jlpm collapse every @jupyterlab and @lumino package
to a single hoisted copy, which is required for a JupyterLab prebuilt
(federated) extension: at runtime those packages are shared singletons
provided by the host JupyterLab, so the build-time versions only need
to type-check against one consistent tree, not match an exact runtime
patch. This is the version set the published image was built and
validated with end to end.

Verified by building the labext in isolation against the base image
(Node 20 + bundled jlpm): caret ranges build clean (webpack compiled
successfully); the exact pins fail with the duplicate-package TS
errors.
This commit is contained in:
Daniel Han 2026-07-05 15:34:42 +00:00
commit 38df3879ed

View file

@ -29,22 +29,22 @@
"clean": "rimraf lib tsconfig.tsbuildinfo unsloth-jupyterlab/labextension"
},
"dependencies": {
"@codemirror/state": "6.5.4",
"@codemirror/view": "6.39.14",
"@jupyterlab/application": "4.6.0",
"@jupyterlab/apputils": "4.6.0",
"@jupyterlab/cells": "4.6.0",
"@jupyterlab/codemirror": "4.6.0",
"@jupyterlab/mainmenu": "4.6.0",
"@jupyterlab/notebook": "4.6.0",
"@jupyterlab/theme-dark-extension": "4.6.0",
"@lumino/disposable": "2.1.5",
"@lumino/widgets": "2.8.0"
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"@jupyterlab/application": "^4.5.0",
"@jupyterlab/apputils": "^4.5.0",
"@jupyterlab/cells": "^4.5.0",
"@jupyterlab/codemirror": "^4.5.0",
"@jupyterlab/mainmenu": "^4.5.0",
"@jupyterlab/notebook": "^4.5.0",
"@jupyterlab/theme-dark-extension": "^4.5.0",
"@lumino/disposable": "^2.0.0",
"@lumino/widgets": "^2.0.0"
},
"devDependencies": {
"@jupyterlab/builder": "4.5.9",
"rimraf": "5.0.10",
"typescript": "5.5.4"
"@jupyterlab/builder": "^4.5.0",
"rimraf": "^5.0.0",
"typescript": "~5.5.0"
},
"jupyterlab": {
"extension": true,