The killer feature of Aurelia for me is that Aurelia allows 3rd-party libs to touch the DOM. Don’t know about Angular, but any VDOM based framework, such as Vue, doesn’t work with 3rd-party libs automatically, you need a rewrite (the reason of huge react eco-system) or a not-trivial wrapper.
With Aurelia, I use bootstrap as bootstrap, use highchart as highchart, use select2 as select2, use codemirror as codemirror. If I want to reuse them, I wrap them in custom element/attribute with fairly easy-to-understand code.
Also - nesting a component in a table based component was really painful in Aurelia.
I am curious to see what design of Aurelia makes this hard, and how other frameworks work better in this use case. So far, Aurelia has not dragged me down when declaring view template.
The underlying issues might not have been considered properly. Binding syntax and cli configuration could just be some manifestations of some too conventional system that will likely lock you in.
The normal approach in this situation is to have 2 teams building the same thing, maybe?
And same with Chunpeng Huo, curious about the issues tou got with table as well
I haven’t tried it yet, but I like that Aurelia has a tool to create web components from Aurelia components. This may come in handy soon as our team has built out a nice component library in Aurelia that we may be able to share with other teams in the company who use ember and react.
Performance - Aurelia consistently beats Angular, React, and Vue in almost every major perf benchmark and has for the last several years.
Web Standards - Aurelia is committed to web standards, making your apps more present and future compatible with the web itself. Both Angular and Vue do some very non-standard things. For example, they both do very strange things related to shadow dom which aren’t compliant. Vue does odd non-ES2015 compliant stuff in its JS too.
Unobtrusiveness - Aurelia allows you to write most of your app in plain JS, and stays out of your way. This means you stay closer to the “metal” of the web, don’t end up writing lots of boilerplate code, etc. However, the most important reason for this is that it allows your app code to be the center of your app, rather than the framework. This is a critical architectural trait that you want to have. If I were to list one thing in my 15+ years of consulting that hurt projects and companies the most, it was getting this wrong. React, Angular, and Vue utterly and ravenously invade nearly every part of your app. That’s not a great place to be architecturally. It will cost you.
Stability - Aurelia has had little to no breaking changes in 4 years. Meanwhile, React, Angular, and Vue, frequently make breaking changes multiple times per year. While there are breaking changes coming in Aurelia 2, that’s something our community only has to deal with once in 4+ years. But beyond that, 90% of Aurelia 2 is non-breaking and remains just like current developers have gotten used to. There is, for example, nothing like “hooks”, which if used correctly, really requires you to rethink your entire application architecture. No thanks.
Support - If you need it, the Aurelia core team provides consulting, training, and support services directly.
Integration - As already mentioned, because we stay close to the standards and don’t introduce unnecessary abstractions (like Vue’s vDOM or Angular’s element ref wrappers), it’s very easy to integrate Aurelia with any 3rd party library. It’s trivial in most cases. This means that whole world of web libraries is open to you from day one, including anything built with web components.
There are many more things that could be added to this list. I realize that none of what I’ve listed is “sexy”, “explosive” or “jaw dropping”. However, these are the kinds of things that matter when building real software. For the most part, anything another framework can do, Aurelia can do better. And when I say “better”, I mean the things above, several of which can be objectively measured.
As part of my proof of concept, I had to re-implement some of our existing components, which include a table with collapsible rows.
Due to the way modern browsers handle tables, you can’t render and non table tag within a table, which creates issues with nested component content being rendered under the table.
Note the merge-table attribute. What mergeTable is doing is using the passed in HTML element and searching the nodes for the table content, then re-attaching those nodes to the correct table nodes.
VueJS didn’t seem to care at all, and just rendered the nested components where we declared them. I’m not sure what the Angular solution was (I would have to check), but it didn’t involve having to manually shuffle DOM nodes about.
I know this isn’t really Aurelia’s fault, but when running through it with other devs here they kept saying “but we didn’t have this problem with other frameworks”.
I see, I also had this browser “issue” with Aurelia before. Other frameworks have no such issue, because they use dedicated js code to parse html template, while Aurelia borrows the performant native browser parser.
I guess the reason you have a complex merge-table, is that you cannot do <tbody><slot></slot></tbody>.
@EisenbergEffect@bigopon I think we can borrow Knockout idea to bypass this browser limitation fairly easily. How do you think about
<!-- au:slot -->
<!-- au:slot name="optional" -->
Prefix au: was added to ease the preprocessing.
This might also open the opportunity to containerless template tag, only if following proposal yields less runtime limitations.
<template as-element="some">lorem</template>
same as:
<!-- au:template as-element="some" -->lorem<!-- /au:template -->
Both Angular and Vue do some very non-standard things. For example, they both do very strange things related to shadow dom which aren’t compliant.
Angular and Vue are allowing you to do things which aren’t web standards compliant. So you’ve now ended up with template code that is tightly coupled to the custom html parser of those frameworks, instead of something that would work with any framework that follows web standards.
So “we didn’t have this problem with other frameworks” should be rephrased as “these other frameworks are not protecting us against doing things which are not compatible with web standards”.
What you are trying to do would never work with native ShadowDOM, so you’ll never be able to leverage native ShadowDOM features. If you apparently don’t need those features, you can accomplish the same thing in Aurelia with replaceable and replace-part which is designed for these sorts of use cases.
And as with everything else in Aurelia it uses the native browser HTML parser since it doesn’t violate web standards:
With all that said, this is not necessarily sound design of components. A table is a single unit of markup / layout and you should try to avoid splitting it up like that. You can put almost anything inside table cells (except slots because those can’t be dynamically repeated) but other than that, from <table> to <td> it should all be in the same template if you want things to work as smoothly as possible.
To share certain behavior across different table instances (e.g. dragging/dropping/sorting) a good way to accomplish that is via custom attributes / template controllers. Then you don’t need a custom element to wrap anything, so no messing around with slots or replaceable, you just put attributes on your table and done.
With the whole table being in one template it would also be easier to maintain and style/customize them, wouldn’t you agree?
Actually our current components are Knockout Web Components hosted in Durandal SPAs.
Our components do not have an ideal structure (I agree!). We have 70 components which have gone through multiple rounds of WCAG compliance testing with a stack of accessibility tools/browser combinations. We are hoping to keep our DOM structure as close to our current set of components as possible (and don’t look at my posted code as an example of compliance, I changed it quite a bit to get things working in Aurelia).
@danny But the example you’re posting isn’t using regular table elements. This quirk is specific to table elements. You can nest literally any other elements/component just fine
Well I think the discussion is more or less settled now, but the key takeaway is that seemingly small things like this can make a big difference.
Common composition scenarios like this need to have an abundance of examples and documentation. We need to somewhat keep an eye on the API surface of competing frameworks (Angular and Vue in particular, since those tend to be the ones that Aurelia would be considered as an alternative of; React OTOH is kind of a unique beast that needs a different approach), and make sure that the things we also support, are documented properly, as well as their differences to how these problems are solved in other frameworks.
Whether or not @danny’s company decides to go with Aurelia will likely determine whether or not another dozen (or more) developers end up investing themselves in Aurelia, which then propagates onward.
This is not an uncommon scenario and it has to be easy for people to find the right docs/examples. How do you even know what to search for, if you don’t know that replaceable is there to fill some of the feature gaps of shadow slots?
@Eisenbergeffect are we taking this into account with the new docs?
If we take proper care of this area, it will be much more likely for existing Aurelia users as well as newcomers to stay with Aurelia, and to convince their peers/managers to do so as well.
Yes, this is mostly already taken care of in the content plan for the new docs. For example, we’re trying to use less technical terms for page titles. So, instead of “templating” or “binding”, or something that is a framework-specific term, you’ll have an article named “Displaying Basic Data” or “Working with Collections”. Each article will also have a description, keyword metadata, etc. combined with full-text search, which will all feed into the docs search engine. Beyond that, most articles will have a “next” button at the bottom, pointing you to an article that follows the current topic, and many will have a “related” section for related articles both on the site and for relevant web standards. Furthermore, there is an entire area of the docs that is completely focused on code samples for common problems. These will be designed to “copy/paste” into your own solution, as much as we can make them. We’ve got ideas for what to put there and that will also grow extensively over time based on all of your input (and contributions ).
I should also mention that we’re re-organizing the content a lot and adding a lot of new content. With Aurelia 1, even if a topic was extensively covered, the information was often spread out over many articles. We’re moving related content closer together and trying to create something that’s more coherent. To help us with this, we’ve hired a professional technical writer to review our plans, articles, etc. and help us produce the best content we can.
Hopefully the combination of all these factors in the new docs will make Aurelia much easier to not only learn, but for experienced devs as well to quickly reference or find an example of what they are trying to do.
You have hit the nail on the head here. I would not have known about replaceable. I just tried searching it in the Aurelia documentation… the first result was “Customizing Conventions” which does not even mention replaceable.
The issue here is that I am the sole developer championing Aurelia. Our internal dev mailing list has over 70 people (and that is just for one section of my organisation). When the issue is discussed in our tech lead meetings, all the other devs hear is “this thing is harder to do in Aurelia than Angular or Vue”. They don’t care why.
I am pretty sure the replaceable was the old way to compose view before shadow dom slots was implemented. Shadow dom slots syntax is more intuitive and easy to understand, so v1 doc didn’t mention replaceable at all.
I am so glad the old replaceable can fill the gap of shadow dom slots. This particular use case of replaceable in table should be and will be documented in Aurelia 2.