denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
98.09k stars 5.4k forks source link

deno install deep/peer dependency types version collision error during build #26145

Open muuvmuuv opened 1 month ago

muuvmuuv commented 1 month ago

Version: Deno 2.0.0

I am testing Deno as a pm replacement in our repo currently, since v2 seems pretty promising (also benchmarked a build). Sadly during the build it breaks with errors reporting type version collisions where a peer/deep dependency has a different version. This is a little bit related to #17286 whereas I want to report a type issue.

Our package.json stripped ```json { "name": "", "version": "0.0.0", "description": "", "license": "UNLICENSED", "private": true, "type": "module", "dependencies": { "@angular/animations": "19.0.0-next.9", "@angular/common": "19.0.0-next.9", "@angular/core": "19.0.0-next.9", "@angular/forms": "19.0.0-next.9", "@angular/platform-browser": "19.0.0-next.9", "@angular/platform-browser-dynamic": "19.0.0-next.9", "@angular/router": "19.0.0-next.9", "@angular/service-worker": "19.0.0-next.9", "@capacitor/app": "^6.0.1", "@capacitor/app-launcher": "^6.0.2", "@capacitor/browser": "^6.0.2", "@capacitor/camera": "^6.0.2", "@capacitor/clipboard": "^6.0.1", "@capacitor/core": "^6.1.2", "@capacitor/device": "^6.0.1", "@capacitor/dialog": "^6.0.1", "@capacitor/filesystem": "^6.0.1", "@capacitor/geolocation": "^6.0.1", "@capacitor/keyboard": "^6.0.2", "@capacitor/network": "^6.0.2", "@capacitor/preferences": "^6.0.2", "@capacitor/push-notifications": "^6.0.2", "@capacitor/share": "^6.0.2", "@capacitor/splash-screen": "^6.0.2", "@capacitor/status-bar": "^6.0.1", "@capacitor/toast": "^6.0.2", "@date-fns/utc": "^2.1.0", "@ionic/angular": "8.3.1", "@ionic/core": "^8.3.2", "@ionic/pwa-elements": "^3.3.0", "@jsverse/transloco": "^7.5.0", "@lottiefiles/dotlottie-web": "^0.35.0", "@ngneat/error-tailor": "^5.0.1", "@ngneat/reactive-forms": "^5.0.2", "@sentry/angular": "8.33.0", "@sentry/capacitor": "1.0.1", "@supabase/auth-js": "^2.65.0", "@tanstack/angular-query-experimental": "^5.59.6", "@total-typescript/ts-reset": "^0.6.1", "date-fns": "^4.1.0", "dot-prop": "latest", "hash-wasm": "^4.11.0", "humanize-string": "^3.0.0", "ionicons": "^7.4.0", "jose": "^5.9.3", "marked": "^14.1.2", "nanoid": "^5.0.7", "ngxtension": "^4.0.0", "rxjs": "^7.8.1", "shiki": "^1.22.0", "slugify": "^1.6.6", "sort-on": "^6.1.0", "swiper": "^11.1.14", "tslib": "^2.7.0", "type-fest": "^4.26.1" }, "devDependencies": { "@analogjs/vite-plugin-angular": "^1.8.2", "@analogjs/vitest-angular": "^1.8.2", "@angular-builders/custom-esbuild": "^18.0.0", "@angular-devkit/architect": "0.1900.0-next.10", "@angular-devkit/build-angular": "19.0.0-next.10", "@angular-devkit/core": "19.0.0-next.10", "@angular-devkit/schematics": "19.0.0-next.10", "@angular/build": "19.0.0-next.10", "@angular/cli": "19.0.0-next.10", "@angular/compiler": "19.0.0-next.9", "@angular/compiler-cli": "19.0.0-next.9", "@biomejs/biome": "^1.9.3", "@capacitor/android": "^6.1.2", "@capacitor/cli": "^6.1.2", "@capacitor/ios": "^6.1.2", "@commitlint/cli": "^19.5.0", "@commitlint/config-angular": "^19.5.0", "@j-ulrich/release-it-regex-bumper": "^5.1.0", "@jsverse/transloco-keys-manager": "^5.1.0", "@jsverse/transloco-validator": "^7.0.1", "@release-it/conventional-changelog": "^8.0.2", "@sentry/cli": "^2.37.0", "@types/apple-mapkit-js-browser": "^5.78.1", "@types/node": "^22.7.5", "angular-eslint": "^18.3.1", "conventional-changelog-cli": "^5.0.0", "dotenv": "^16.4.5", "eslint": "^9.12.0", "eslint-plugin-compat": "^6.0.1", "eslint-plugin-unicorn": "^56.0.0", "globals": "^15.11.0", "html-minifier-terser": "^7.2.0", "lefthook": "^1.7.18", "prettier": "^3.3.3", "prettier-plugin-organize-attributes": "^1.0.0", "release-it": "^17.8.2", "standard-changelog": "^6.0.0", "stylelint": "^16.9.0", "stylelint-config-clean-order": "^6.1.0", "stylelint-config-standard-scss": "^13.1.0", "ts-node": "^10.9.2", "typescript": "^5.6.3", "typescript-eslint": "^8.8.1", "vite": "5.4.8", "vite-tsconfig-paths": "^5.0.1", "vitest": "^2.1.2" }, "scripts": { "postinstall": "[[ -z \"${CI}\" ]] && just || echo" }, "pnpm": { "overrides": { "uuid": "latest", "semver": "latest", "@stencil/core": "latest" }, "peerDependencyRules": { "ignoreMissing": ["zone.js"], "allowAny": ["zone.js"] } } } ``` > This also includes some `pnpm` modifiers I am still searching to get to work with Deno if possible

Steps.

https://codesandbox.io/p/devbox/6jv2wk (could not find a good cloud repl for deno that is free)

  1. deno install --allow-scripts=npm:lefthook,@sentry/cli,@biomejs/biome

    Warning The following packages are deprecated:
    ┠─ npm:glob@7.2.3 (Glob versions prior to v9 are no longer supported)
    ┠─ npm:glob@8.1.0 (Glob versions prior to v9 are no longer supported)
    ┖─ npm:inflight@1.0.6 (This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.)
    Warning The following packages contained npm lifecycle scripts (preinstall/install/postinstall) that were not executed:
    ┠─ npm:@sentry/capacitor@1.0.1
    ┠─ npm:nx@19.8.4
    ┠─ npm:lmdb@3.1.3
    ┠─ npm:lmdb@3.0.13
    ┠─ npm:nice-napi@1.0.2
    ┠─ npm:core-js-pure@3.38.1
    ┠─ npm:msgpackr-extract@3.0.3
    ┃
    ┠─ This may cause the packages to not work correctly.
    ┖─ To run lifecycle scripts, use the `--allow-scripts` flag with `deno install`:
    deno install --allow-scripts=npm:@sentry/capacitor@1.0.1,npm:nx@19.8.4,npm:lmdb@3.1.3,npm:lmdb@3.0.13,npm:nice-napi@1.0.2,npm:core-js-pure@3.38.1,npm:msgpackr-extract@3.0.3
    sync hooks: ✔️ (pre-commit, commit-msg)
  2. deno run --allow-all node_modules/@angular/cli/bin/ng.js build

✘ [ERROR] NG2: Type 'FormGroup<{ firstname: FormControl<string>; lastname: FormControl<string>; username: FormControl<string>; gender: FormControl<Gender>; birthday: FormControl<...>; }>' is not assignable to type 'FormGroup<any>'.
  Types of property 'controls' are incompatible.
    Type '{ firstname: FormControl<string>; lastname: FormControl<string>; username: FormControl<string>; gender: FormControl<Gender>; birthday: FormControl<...>; }' is not assignable to type '{ [key: string]: AbstractControl<any, any>; }'.
      Property 'firstname' is incompatible with index signature.
        Type 'FormControl<string>' is not assignable to type 'AbstractControl<any, any>'. [plugin angular-compiler]
Add-on if one is interesting seeing build executiong numbers (but with pnpm as pm) ``` Direct execution of : node_modules/@angular/cli/bin/ng.js ## Node/pnpm > node node_modules/@angular/cli/bin/ng.js build Cold: 8.0s HotC: 6.3s ## Bun(node)/pnpm > bun run node_modules/@angular/cli/bin/ng.js build Cold: 7.3s HotC: 5.7s ## Bun(--bun)/pnpm > bun run --bun node_modules/@angular/cli/bin/ng.js build Cold: NaN HotC: NaN ## Deno/pnpm > deno run --allow-all node_modules/@angular/cli/bin/ng.js build Cold: 8.3s HotC: 5.8s ```
nathanwhit commented 1 month ago

It looks like the issue is that we don't allow pre-release versions to satisfy peer dependencies. For instance, if a package bar has a peer dependency of "foo": ">=1.0.0", and you explicitly depend on "foo": "2.0.0-next.0", we will still install foo@1.0.0 to satisfy the peer dependency, instead of allowing the pre-release version to satisfy it.

repro:

package.json

{
  "name": "peer-deps",
  "version": "1.0.0",
  "dependencies": {
    "package-direct": "1.0.0",
    "package-a": "2.0.0-next.0"
  }
}

package-a has two published versions: 1.0.0 and 2.0.0-next.0.

package-direct's package.json

{
  "name": "package-direct",
  "version": "1.0.0",
  "peerDependencies": {
    "package-a": ">=1.0"
  }
}

running deno install will install both package-a@1.0.0 and package-a@2.0.0-next.0

cc @dsherret

muuvmuuv commented 1 month ago

Oh, nice catch! Did not think about that case. Just asking, but is there something like pnpm overrides so I could temporarly override it for any dependency (it behaves a little different)?

marvinhagemeister commented 1 month ago

Yes, you can also use pnpm to install your packages instead of deno. Note that Deno doesn't support resolving pnpm workspaces though, only npm workspaces.

muuvmuuv commented 1 month ago

Ah yes, I know, the question was if Deno has something like "pnpm overrides", then I could just test if building works with Deno as pm and runtime, since the only issue atm is the type error. I already tested Deno/pnpm (see bottom <details)

marvinhagemeister commented 1 month ago

Right, apologies for my misunderstanding. We don't have a feature equivalent to pnpm overrides at the moment. It's something that we'd love to add to Deno at some point, but there is no timeline for when that's going to happen.