-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Peer dependencies #10356
Comments
A solution that I was thinking about for this is to require the developers that are using your suite of modules to include an import map that specifies the version of the core module ( // importmap.json
{
"imports": {
"grammy": "'https://deno.land/x/grammy@v1.0.0/mod.ts'",
}
} // main.ts - User's code
import { Foo } from "grammy";
import { FooPlugin } from "https://deno.land/x/grammy-plugins-foo@v1.0.0/mod.ts";
const foo = new Foo([FooPlugin]); /// https://deno.land/x/grammy@v1.0.0/mod.ts
export function coreLogic() {
/* do stuff */
}
export class Foo {
constructor(public plugins: Function[]) {}
} /// https://deno.land/x/grammy-plugins-foo@v1.0.0/mod.ts
import { coreLogic } from "grammy";
export function FooPlugin() {
coreLogic();
/* do some other stuff */
} Now, you can run the project via the following command: deno run --import-map=importmap.json main.ts Within the READMEs of the submodules it would be extremely important to include the versions that their module is compatible with and how a dev can setup the project. Also, I want to clarify that you can include whatever url you want when importing your file as long as it ends in |
The Deno CLI does not care what semantics a placed on the import specifier. That is up to the registry. There are several registries that already provide packages that way, like unpkg, snowpack, esm.sh, etc. What you are suggesting is that you might want All that being said, this topic has been exhaustively been discussed before, so closing as duplicate of denoland/dotland#47, denoland/dotland#195, denoland/dotland#288, #4574, #6030 and others. |
Supporting semver in the website is tracked by https://github.com/denoland/deno_website2/issues/606 but it does not seem like anyone is eager to solve these problems. There is now a thin wrapper around Try clicking https://dsr.edjopato.de/grammy/0.x/mod.ts. It will parse the semver specifier and then redirect you to the correct latest |
I fail to see how any of these issues provide a solution to this problem. I don't care how radical the solution is or if I have to single-handedly rewrite the entire ecosystem around my project. My problem persists. I could accept it if we collectively decided to just ignore the problem, and be like “meh, we don't care about library creators, we care about application developers, and they can use import maps.” That would of course not be ideal, but at least we can agree that there's a problem and that we don't do anything about it. What's much worse than that is how the Deno team handles this situation currently. Closing this issue as a duplicate of other closed issues makes no sense. It seems like you are either actively suppressing any discussions on how to make the current design work, or you are lacking any understanding of the challenges our organisation is facing. Both would be disappointing. In case you are trying to silence us (out of fear we would question URL imports? No intention to do that), I don't think I can do much more here. Sorry. In case you just think that there's an easy and obvious solution, and I'm simply not seeing it, I don't mind talking this out. Our issue persists for 1.5 years now and a few dozen engineers with an understanding of the problem have participated in the conversation. No one could point out a solution. Meanwhile, the library consumers have to pay the price, as the only workaround we know causes compilation errors that are not obvious to fix. As a result, from their point of view, using Node has so much less complexity when it comes to dependency management. No one of us what's that to happen, eh? :) |
A little late to the party. In general I would also like to have a proper solution to this problem. What I do is to provide a different interface to libs that work with externally provided dependencies. Conceptionally I use smth like currying to provide my lib functionality after passing the peer Deps to it first. myLib
usage in app
For typing I try to write keep the dependencies to the peer Deps written in a duck typing manner |
Background
I am the developer of an a new framework for writing Telegram bots (ref, but the purpose is irrelevant here). The core framework is extensible by plugins that can be published by other authors. As a result, I publish one core package to deno.land/x, and other people and me publish other packages around it.
Problem Description
While it would be desirable that plugins do not depend on the core module, this is not always possible. Some plugins rely on different parts of the core package (both runtime code and some complicated type transformations) that are also exposed to users, and it makes little sense to duplicate this logic into each plugin.
Even if it is possible to achieve duplicate only some parts of the core library, and let maybe users pass in the missing components, this is not always practical and can lead to unnecessarily complex code.
Right now, some of the plugins specify the grammY core package as a direct dependency, but this can lead to users downloading multiple versions of the same package.
How Node Solves It
For an npm package, this would be solved by making the core package a peer dependency with specified semver ranges that are supported. This pattern can be seen a lot in the npm ecosystem, and while peer deps are generally to be avoided, they sometimes have their place.
One of the Solutions
It would be nice to be able to specify semver ranges in import URLs, à la
but I don't mind the exact syntax being different.
I am by far not the first person to mention this, and it is neither flawless nor the only solution. However, despite some people commenting on the problem, I cannot find a promising suggestion on how to overcome this issue. I looked into ways of restructuring the plugin architecture, but I always ended up at the point that at least one of the plugin packages needed to refer to the core package in some way or another, or at least parts of it.
Please let me know if I overlooked a GitHub issue somewhere that discusses this. If that does not exist, what are you suggesting how to handle these situations?
The text was updated successfully, but these errors were encountered: