As someone who has tried to find a way to help content authors develop and maintain big web sites by creating (HTML) components for years, I\'m really excited to see web compone
IMHO the issue you described always exists in frontend and not directly related to web components, but web components do make this even worse.
Say if you rely on component A and B which all relies on lodash, unless A and B both set lodash to peer dependencies (which makes them look like plugins like most jquery plugins do), then you can include one copy of lodash, otherwise, A and B are meant like black box to you. Though bundlers may do some post-build processing like tree shaking/dead code elimination to help mitigate this, but this could never 100% work, e.g. A and B both rely on two different versions of lodash.
Why web components make this even worse? the goal of WC is to provide a framework agnostic way to reuse UI components, say if i use vue and a bunch of vue components, my bundled js ends up with these components and a single vue runtime cuz vue is a peer dep in these components. Now if i use WC and a bunch of WC components, i will most likely end up with a larger bundled js. For example, can create a simple lit-element WC component with a simple button, then build the project and see how the bundle js is much larger. Some framework may take a different approach, vue for example, still requires you to add vue as an external framework to run vue based WC, which doesn't save you one byte if you switch vue to WC. Also, sharing styles is another problem in WC in terms of reducing bundle size.
My company uses bootstrap and react, our app is bundled with 1 bootstrap, 1 react and many external react components, which already ends up to be 3.5mb js/css, i doubt we can do the same thing in WC in 3.5mb.
I've had similar misgivings about web-components myself, but then I started working with third-party React components. They have the same problems in that they bring along all their own dependencies. But worse than that, because React doesn't like living with other versions of React, React components must list React as a Peer Dependency. This means that you are forced to use the same version of React as your third-party components.
So my conclusion is that this is in fact a feature of web-components! Every Custom Element can have it's own dependencies entirely independent from the rest of your app. I consider third-party components to be the main use-case for Web Components; where the consumer wants to be able to use a component with as little friction as possible. Sure there will be some duplicate code, but the component consumer doesn't need to know or care. I think that component authors will deal with this is by using smaller modules in their components. For example, instead of using React they could use something like Snabbdom.
If you are building an entire application out of web-components that you control, you can still use a bundling tool like Browserify or WebPack to manage your dependencies. These will allow you to override certain modules so that you can even force third-party components to use the same versions as the rest of your app (see: https://www.npmjs.com/package/aliasify). That might break some modules, but that's life.
In the current W3C spec there does not seem to be a specific way to define dependencies or even version them. Components are expected to not make use of any libraries/dependencies or to be tightly coupled with them.
This means that each major library will probably bring their own set of components with them that expect those libraries to have been loaded.
Maybe ES6 Modules provide help in this regard, but then again they currently also don't provide any versioning mechanisms.
That all said the spec is in a pretty early stage and is likely to change. Bringing the dependencies issue up with the spec authors might bring that topic to the table and might even solved before the spec solidifies. In the end using different libraries to perform the same task within a single code base has always been and will continue to be a problem in software development, regardless of platform and language. You will just have to agree upon which frameworks/libraries to use within your codebase, even if that means locking you out of others.
Also, if you are interested in developing independent components for the web already today you might want to take a look at the React library
I never heard of standardising javascript frameworks. However with HTML5 some parts that used to need javascript frameworks in earlier versions of HTML have now been added as a standard feature to HTML5 (for example the tag <canvas>
, rounded borders, shadow effects, ...), which is a first step in solving what you are mentioning.
To be honest I don't think that this is ever going to happen, or at least not in the near future. All those frameworks out there have their own purposes, advantages and disadvantages. Until you can build a huge javascript library that somehow combines them all there will always be different libraries used all over the web.
Another important point is the competition between the different libraries that keeps the javascript market growing and come up with new innovations. IF you would make a standard javascript library that all would use, you would also eliminate the competition between the different frameworks that keeps innovation and progress going.
Library bloat isn't necessarily mitigated by using web components, in fact you can trim down libraries by using custom builds (link is for Lo-Dash, but other popular libraries have build steps). Some kind of automation here can be very useful, i.e. a tool that can scan through your source code and generate a custom build based on what functions you are using.
I think with the rise of npm such libraries are becoming less and less relevant. Lo-Dash is a good example of this because its functions are being released on npm as standalone modules, but you also have things like Sizzle, the CSS selector engine that jQuery uses. If you look hard enough you can find lots of plugins that are being written without jQuery as a dependency, or it is in a project's roadmap to remove dependencies, or someone has already forked the project to remove its dependency on another library. For example, Exoskeleton, a completely underscore & jQuery free version of Backbone.
I don't think we're going to see another popular utility library such as jQuery or underscore; with npm we can simply choose the modules that we want, and fork projects that depend on these large libraries to rewrite them using only the modules that they need, or a completely dependency free version.
With AMD and requirejs, this is already a reality. You can define some source code's dependencies; instead of linking to monolithic libraries, in your code you can state that this component only needs for example microajax instead of the whole jQuery library:
define(['microajax'], function(microAjax) {
microAjax("/resource/url", function (res) {
alert (res);
});
});
Check out the microjs website for more helper libraries like this one.
As far as web components go, I'd hope that the authors of these write their components in such a way so that they don't require massive libraries like jQuery that can do everything. And if they do I would also hope that I could fork them and trim out all the unnecessary parts myself. :-)
Edit: This 24ways article is a good primer on the rise of native JS features that will eventually supersede jQuery. It's worth mentioning that jQuery was written at a time where JavaScript implementations were wildly different; but as standardisation has risen and APIs have become more consistent, the need for a wrapper around native functionality has diminished somewhat. For example, now we have querySelectorAll
:
// jQuery
$('.counter').each(function (index) {
$(this).text(index + 1);
});
// Vanilla JavaScript
var counters = document.querySelectorAll('.counter');
[].slice.call(counters).forEach(function (elem, index) {
elem.textContent = index + 1;
});
This is an issue that's been bothering me as well for a while, esp when faced with maintaining code that's been touched by numerous developers. You often encounter multiple JS libraries (some of which essentially does the same thing) included in one solution, not to mention even different versions of the same framework used in one solution.
The or rather "a" potential solution that I am looking at is to create a type of mediator framework.
The basic idea is to code "against" the mediator (never accessing/using a js library directly, but using it via the mediator), thereby essentially making the code agnostic (decoupled from its "parent" library) and including a mediation implementation underneath.
This wont address my/our immediate problem or bloat, but whatever web component I write will be able to run cross framework.
Here is a little proof of concept: Tagger Mediator POC
E.g. mediators included for:
JQuery (1.9.1)
Mootools (1.4.5)
Prototype (1.7.1.0)
YUI (3.10.3)
Dojo (1.9.1)
Ext (3.4.0)
Zepto (1.0)
But nothing stops anyone to create their own mediation framework, which "abstracts" other mediators, hmmm, so potentially something that can contribute to the bloat as well (making things worse rather than better).
I guess its up to you to set your own standards ;)