deno
98351ae2 - fix(resolver): resolve linked packages by bare specifier (#35228)

Commit
90 days ago
fix(resolver): resolve linked packages by bare specifier (#35228) Linked packages declared via `"links"` in `deno.json` have not been resolvable through a bare specifier since #34519, which gated them out of bare-specifier resolution to fix #29436. Only a `jsr:` specifier or an import map entry worked. That broke the workflow people relied on for private packages: a private package is not published to any registry, so it cannot be referenced as a real `jsr:`/`npm:` dependency, and `"links"` was the only way to import it by name. The fallout is tracked in #34829 and #35214, and the connection to `deno link` (#34359) is described in #35227. The workarounds suggested for the new behavior all fall short. Importing via `jsr:@org/foo` trips the `no-import-prefix` and `no-unversioned-import` lints and is a supply-chain footgun, since `deno update` will then look the private name up on jsr and a colliding public publish could be pulled in. Adding an import map entry `"@org/foo": "jsr:@org/foo"` does not compose transitively: when a linked package's own files import a sibling (`@org/aaa` importing `@org/bbb`), the root import map does not apply inside the linked package's scope, so every member would have to be duplicated by hand. Using a real workspace requires the member to be nested under the workspace root rather than a sibling or absolute path. This change treats linked packages like workspace members for bare-specifier resolution. Conceptually a link is just a workspace member that lives outside the workspace tree, so the `!p.is_link` filter in the bare-resolution loop is dropped. Workspace members are still listed before links in `jsr_pkgs`, so they keep precedence when a name collides, and the `jsr:`-prefixed and import map resolution paths are untouched, so the override use case `"links"` was designed for keeps working exactly as before. This intentionally reverses the bare-resolution behavior that #34519 introduced for #29436. The original concern was that resolving a linked package by bare name was surprising, but it is not silent: you opt in by listing the path in `"links"`, and there is no private-registry alternative for the affected users. The `link_bare_specifier` spec test and the two resolver unit tests that locked in the rejection are updated to assert resolution, and a new `link_transitive_sibling` spec test covers the sibling-import case that an import map entry could not satisfy. A follow-up can simplify `deno link` (#34359) to stop injecting the `"@org/foo": "jsr:@org/foo"` import map entry, since bare imports now work without it. Closes #35227 Closes #35214
Author
Parents
Loading