Struggling with extensions and dependencies/versions

Hello everyone!

I’ve been starting to look at Jupyterlab/Jupyterlite recently and I am very interested in developing my own extension.

However, i’ve been struggling a lot with the dependencies of extensions. I appreciate the fact there are a lot of examples in Github to look at and start from. But when I try to build many of them I get dependencies/build errors.

For example in this great repository with many extensions: GitHub - jupyterlab/extension-examples: JupyterLab Extensions by Examples;
I haven’t been able to build any of them. For example for the react-widget one, running npm install gives me the following error:

npm install
npm WARN deprecated crypto@1.0.1: This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.
npm WARN deprecated @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated popper.js@1.16.1: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1
npm ERR! code 1
npm ERR! path /Users/thibaut/Documents/extension-examples/react-widget
npm ERR! command failed
npm ERR! command sh -c jlpm run clean && jlpm run build:prod
npm ERR! yarn run v1.21.1
npm ERR! $ jlpm run clean:lib
npm ERR! $ rimraf lib tsconfig.tsbuildinfo
npm ERR! Done in 0.60s.
npm ERR! yarn run v1.21.1
npm ERR! $ jlpm run clean && jlpm run build:lib && jlpm run build:labextension
npm ERR! $ jlpm run clean:lib
npm ERR! $ rimraf lib tsconfig.tsbuildinfo
npm ERR! $ tsc
npm ERR! ../node_modules/@jupyterlab/rendermime/lib/widgets.d.ts(8,31): error TS2420: Class 'RenderedCommon' incorrectly implements interface 'IRenderer'.
npm ERR!   The types of 'title.owner.layout' are incompatible between these types.
npm ERR!     Type 'import("/Users/thibaut/Documents/extension-examples/node_modules/@lumino/widgets/types/layout").Layout' is not assignable to type 'import("/Users/*****/Documents/extension-examples/node_modules/@jupyterlab/rendermime-interfaces/node_modules/@lumino/widgets/types/layout").Layout'.
npm ERR!       Property '[Symbol.iterator]' is missing in type 'import("/Users/*****/Documents/extension-examples/node_modules/@lumino/widgets/types/layout").Layout' but required in type 'import("/Users/*****/Documents/extension-examples/node_modules/@jupyterlab/rendermime-interfaces/node_modules/@lumino/widgets/types/layout").Layout'.
npm ERR! info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
npm ERR! info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
npm ERR! error Command failed with exit code 1.

I actually got the same error while trying to build different extensions. My guess is, it’s probably a version mismatch, or something to do with the versions in the package.json:

  "dependencies": {
    "@jupyterlab/application": "^3.1.0",
    "@jupyterlab/launcher": "^3.1.0",
    "@jupyterlab/ui-components": "^3.1.0"
  },
  "devDependencies": {
    "@jupyterlab/builder": "^3.1.0",
    "@typescript-eslint/eslint-plugin": "^4.8.1",
    "@typescript-eslint/parser": "^4.8.1",
    "eslint": "^7.14.0",
    "eslint-config-prettier": "^6.15.0",
    "eslint-plugin-jsdoc": "^40.0.0",
    "eslint-plugin-prettier": "^3.1.4",
    "eslint-plugin-react": "^7.18.3",
    "npm-run-all": "^4.1.5",
    "prettier": "^2.1.1",
    "rimraf": "^3.0.2",
    "typescript": "~4.1.3"
  },

After trying several versions, I unfortunately haven’t been able to find a fix it for me at the moment. I’m far from being a javascript package management expert.

So, would you have any tips for me about how to handle versions/dependencies while developing Jupyterlab/Jupyterlite extensions? Are there any best-practices to follow? How do you deal with the multitude of versions between Jupyterlab and the plethora of extensions out there (and yes I’m using Python environment or conda envs).

I’m on MacOS, using Python 3.11.3, npm v9.6.6, node v16.18

Thank you in advance,
Thibaut

1 Like

Yep, all @lumino stuff needs to be tightly locked down, for typing reasons, but primarily for instanceof checks… which is kind of a bummer, as an extension author has no control over which version it will actually run with, as the as-distributed application will only allow the version it shipped with.

As a light touch, try:

  • add "skipLibCheck": true to the tsconfig.json#/compilerOptions key
    • usually webpack (and therefore the extension author) don’t really care about how @lumino/* and @jupyterlab/* packages feel about each other, for the reason described above

The heavier-duty one is to emulate what e.g. jupyterlab does

  • add "@lumino/widgets": "^1.37.2" to package.json#/resolutions
  • delete yarn.lock
  • re-run jlpm
  • re-run jlpm build
2 Likes

Thanks @bollwyvl, very much appreciated.

I tried the first method and it worked well. But I understand this is just a workaround.

I’m trying the “heavier-duty” method but haven’t been successful so far. At the same time I saw this thread in Gitter addressing the same issue. Acccording to this thread, @jupyterlab/rendermime-interfaces:3.8.0 packages is causing the conflict by depending on @lumino/widgets:2.x. I tried to pin the version to 3.6.3 by adding it to the package.json#resolutions but the 3.8.0 package is still being pulled, therefore causing the error.

  "resolutions": {
    "@jupyterlab/rendermime-interfaces": "3.6.3",
    "@lumino/widgets": "^1.37.2" 
  }

So I don’t know what I’m doing wrong yet, if you have any clue let me know! I’ll keep looking :slight_smile:

Again: extension authors have no control over the effective runtime @lumino and @jupyterlab resolutions: if tsc and jupyter labextension build are happy, there’s nothing to worry about.

Another tool in the toolbox, used in lab core:

jlpm add --dev yarn-deduplicate
# run the following "a few times"
jlpm yarn-deduplicate -s fewer --fail || jlpm
1 Like

Thanks for the info, I ran into the same problem as described above. Adding this to the package.json file worked for me:

  "resolutions": {
    "@lumino/coreutils": "1.11.0",
    "@lumino/messaging": "1.10.0",
    "@lumino/signaling": "1.10.0",
    "@lumino/widgets": "1.37.2"
  },