taptapship / wiredep

Wire Bower dependencies to your source code.
MIT License
1.15k stars 142 forks source link

Optional Dependencies #202

Closed CWSpear closed 8 years ago

CWSpear commented 9 years ago

This is more of just opening a discussion rather than an actual issue.

One of the features being removed in 3.0 is Elite Dependencies. As a developer that does a lot of Angular, the first thing I thought was, "Devs that use jQuery + Angular aren't going to get jQuery guaranteed to be injected before Angular anymore (which is a requirement to get Angular to enhance their "jQuery Lite subset of jQuery functionality" to just use regular jQuery)."

Indeed, a quick test and Angular is being injected before jQuery.

So that begs the question: what's the best way to handle optional dependencies like that? I believe mostly we've been telling people to just use an override in their bower.json (i.e. override Angular to have a dependency on jQuery).

It should be noted that we don't really want Angular to put jQuery as a dependency, as it's optional. I'd say over half of my projects don't use jQuery, and the other half have been depending on Elite Dependencies to include jQuery first and will break in 3.0 unless I do something else.

I know I tend to be long-winded, but the point was: is there anything we could do to better handle optional dependencies? I think the two extremes are, "Just handle it yourself by putting in an override when you use the optional dependency" all the way to possibly something like a public repo of common things like that that wiredep can pull in. Basically, if jQuery is present, it can reference this directory of special overrides and make sure it gets injected automatically before Angular.

In other words, similar to Elite Dependencies, but more explicit and transparent (could add note/confirmation when it does something along these lines?).

I don't know, pretty much just thinking out loud/dumping stream-of-conscious.

stephenplusplus commented 9 years ago

That's a great point! I think the best solution is using excludes because you're effectively in a situation that tooling shouldn't magically resolve for you. Being explicit guarantees no surprises. The downside of course is that it's extra configuration that the developer won't be expecting. For sure, we should make a note of this specifically in the release notes. Does that sound reasonable or not good enough?

CWSpear commented 9 years ago

I don't know... I have mixed feelings. Like I was saying, my ideas here are sort of evolving as we talk.

I guess my bigger vision is a way to handle these edge cases. In my earlier example, we want this rule to be applied 100% of the time:

if jquery is a dependency in our bower.json
then add jquery as a dependency override to angular

This is something that we always want to happen. And something bower doesn't have a way to handle on its own. I think it's silly that it's always the developer's responsibility to manually do that when it is a black and white rule (in this case).

So I guess what I've been thinking about is sort of "the next level," and I would understand if it's more than what you want wiredep to be. I've mentioned in the past (but can't find the comment) that perhaps we should take up the torch and define a spec for overrides that others can follow for common interoperability.

Likewise, I'm thinking about how we can handle the edge cases that are that way most of the time. There are always exceptions, but many of them are handled the same way. This has been something we've felt is out of scope so far, and by providing overrides, it gives people the power to manually handle most edge cases. But just think for a second, what if we could add some of that (good) magic into wiredep to make it even easier to integrate those edge cases?

One would be a way to integrate optional dependencies, like in the case I mentioned with Angular and jQuery. Another would be when there are multiple themes (what if wiredep had a way to ask you which theme to choose when you injected files and to persist that choice?). Things like that, that have a very predictable and common methodology.

A couple things we could do is either define a spec to extend bower's kind of like we have done with overrides, but more well-defined. I know we've tried to get overrides as part of the bower official spec, but it's failed. The problem with something like optional deps or choosing among multiple deps is that would be on the package author to put something like that in their bower.json. But if we did it with an open, well-defined spec, we could do it in a way that other tools could hook into.

So the other alternative could be some sort of dedicated repo to define these sorts of overrides and optional things, etc, and to use that for the rules.

I realize this is a decently sized paradigm shift, and maybe not one that we really want now (or ever). But I love the magic of wiredep and how I can just install a package and it "just works." This proposal (is you want to call something this vague a "proposal") may be too little of a benefit for the added complexity, but I guess I just dream of a world where all I need to do is bower install package and wiredep and I'm good to go!

Ok... done rambling! ...for now =)

eddiemonge commented 8 years ago

This is something that we always want to happen

Not necessarily. If you load angular first then it will use jqLite, which some people want and have coded against and don't have to worry about using a specific version of jQuery that is compatible with that version of Angular. A newer breaking jQuery may be what they want.

I feel like this is on the developer to be explicit about what they want that is non-standard. If you disagree, then lets keep this open and spitball some more ideas. Otherwise going to close as it would be probably impractical to implement something like this since we would have to know about every package and its requirements.