Aurelia 2018 Q2 Update and vNext Progress


#1

The second quarter of 2018 is now behind us, so it’s once again time to recap the progress that the Aurelia team and community have made towards our 2018 roadmap goals. You can read the recap in the Aurelia 2018 Q2 Report. A major highlight of the Q2 work is the solid start we’ve made on the next major version of Aurelia. We’ve put together a dedicated post on this topic and hope you’ll take some time to read about Aurelia vNext.


#2

#3

Great and promising roadmap! Worth making sure Aurelia is listed among the projects implementing Lerna (in bottom of page). It’s a respectable list that includes Babel, React, etc.


#4

greate news…
we are very exited to see the vNext in action.


#5

Will components like pal-browser exist? If so, where?


#6

What was called “PAL” has been split apart a bit more. Parts that are less DOM-specific live in the Kernel. Parts that are tied more to DOM live in the Runtime. We’ve reworked how these are implemented so that there are no side-effects to global state by simply importing these modules. In vCurrent there have always been side-effects and ordering issues which led to a complicated issue of what/how/when to load the PAL. That problem has gone away. For vNext, the framework ships with the browser-oriented implementations baked in, but it’s now very easy to plugin an alternate implementation, such as one targeting Node, as part of your bootstrap process. The idea here is that the most common setup should “just work”. To that end, bootstrap, and app startup have been massively simplified as a whole. As an example, here’s what a JIT-based app startup might look like:

import { Aurelia, BasicConfiguration } from '@aurelia/jit';
import { App } from './app';

new Aurelia()
  .register(BasicConfiguration)
  .app({ host: document.querySelector('app'), component: new App() })
  .start();

Again, this is all subject to change, but we do want something fairly similar to this since it greatly simplifies everything from startup, to plugins, to isolation, and more.

(Note that the configuration would be a little different in an AOT-based app. Instead of importing Aurleia and BasicConfiguration from JIT, you would import Aurelia from Runtime and a GeneratedConfiguration, created by the AOT build process. That’s the current thinking at least.)


#7

Hello Mr. @EisenbergEffect

Do you have plans for these features in Aurelia vNext?

  1. Add afterAttached to Aurelia life cycle. this is so useful. (called after all child components are attached, and after all two-way bindings have completed)

  2. Child routers as a new feature in Aurelia vNext router.

  3. add excludePlugin() beside plugin() method. Sometimes we need to add the whole project except some plugins instead of adding plugins one by one.


#8

afterAttached is on @bigopon todo list for vNext.


#9

afterAttached is already done by @EisenbergEffect . @fkleuver already made a lot of progress on the JIT part, we should be able to see live example soon

I may try to have afterAttached for vCurrent


#10

@HamedFathi We’ve done some work to improve lifecycles for vNext. So, now there are the following: attaching, attached, detaching and detached. The attaching and detaching callbacks “tunnel” down the component hierarchy from parent to child. The attached and detached callbacks “bubble” up the hierarchy from child to parent. So, in vNext, if you implement “attached” you can be sure that all your children are attached and all of their attached callbacks have been called. This all goes hand in hand with a lot of other improvements we’ve been making in the component and binding system to make things more synchronous and intuitive/predictable. So, when you get an attached callback, you can also be sure that all children binding has completed.

For the vNext router, we haven’t yet begun the work, but we’re exploring a number of improvements there, including a centralized configuration that would include information for all routers, including child routers. Additionally, we’ll probably remove the router-view element that is used by the router today because we’ve been working to improve the compose element significantly. I’m hopeful that we’ll be able to enable the vNext router to render with compose rather than requiring a specialized element.

For plugins, we’ve opted to enhance the dependency injection container to handle this scenario. As pictured in the code sample above BasicConfiguration is a plugin that adds all the basic capabilities of the framework. However, the new mechanism and framework design allows you to add each piece individually, so you can add only what you want/need. When we enable AOT, we’re hopeful that we’ll be able to code-generate a plugin, specific for your app, that installs only the things you actually use, so you don’t have to do that by hand.


#11

@EisenbergEffect the name “attaching” is bit vague to me. At this point, is the element on DOM or not? From what you described, I believe it’s on DOM tree because vNext attaching is vCurrent attached.

If I use cocoa convention(sorry for referencing a macOS framework here), I can use some sentence like willAttach() (definitely before put on DOM tree, no equivalent in vNext if my above guessing is right), didAttach(). But I have no candidates from renaming attaching and attached yet.

Nevertheless, I feel attaching should be implemented as before attaching to DOM, as we already have the other attached callback. It’s unnecessary for attaching to behave as shallow attached.


#12

Exactly where did you get this? In the code?


#13

As I said, my guess.

… if my above guessing is right


#14

There isn’t a direct map from vNext to vCurrent because vCurrent wasn’t always consistent in it’s timing. The attaching event happens before the view is attached at the start of the attach phase and the attached happens after the view was attached at the end of the attach phase. It is like willAttach and didAttach. Developers who used attached in vCurrent will probably still use attached in vNext. We’re just making the timing more dependable and then adding new, earlier hooks as well.


#15

One of the things we’re trying to do for vNext is make the code much more approachable. So, if you want to understand, in detail, how the lifecycle for a custom element works, you can look in one place and see it all. I’ll paste the relevant code here and annotate it for you so you can see how it works. We’ll be adding comments like this to the code and also writing architectural documentation so those who want to deep dive, learn how this stuff is built or contribute on a much deeper level will have lots of resources. This code is likely to change a bit, but here’s what it is now for explanatory purposes:

    // We install the $attach method to manage the attach phase of the lifecycle for your element.
    proto.$attach = function(this: IInternalCustomElementImplementation, encapsulationSource: INode, lifecycle?: AttachLifecycle): void {
      // Guard against accidental double attach.
      if (this.$isAttached) {
        return;
      }

      // Your element may already be part of a larger lifecycle, but if not this will ensure the attach
      // lifecycle is initialized.
      lifecycle = AttachLifecycle.start(this, lifecycle);
      // An element may be projected into the DOM in different ways, depending on whether or not
      // it is containerless, uses Shadow DOM or is a simple slotless element.
      // The projector for each element handles this and also understands how styles
      // should be encapsulated. For example, when using Shadow DOM styles are
      // encapsulated by the shadow root, rather than the document.
      encapsulationSource = this.$projector.provideEncapsulationSource(encapsulationSource);

      // If your element has an attaching method, call it. This is the real start of the lifecycle.
      if (this.$behavior.hasAttaching) {
        (this as any).attaching(encapsulationSource);
      }

      // Inside your element, there may be many things that need to run their attach phase.
      // In the element's view it may use other elements, attributes, etc. 
      // We run their attach phase now. This is how the attaching callback is made to "tunnel".
      const attachables = this.$attachables;

      for (let i = 0, ii = attachables.length; i < ii; ++i) {
        attachables[i].$attach(encapsulationSource, lifecycle);
      }

      if (this.$child !== null) {
        this.$child.$attach(encapsulationSource, lifecycle);
      }

      // After we've tunneled the attaching callbacks, and they've attached to their parent,
      // we allow this element to project itself into the DOM, thus attaching to its host.
      this.$projector.project(this.$nodes);

      // This is one of the interesting parts here. Nothing that attaches directly calls its own attached
      // callback. Instead it gets queued so that all of them can be called in order, from child to parent
      // but only after the top most parent is actually attached to the DOM.
      if (this.$behavior.hasAttached) {
        lifecycle.queueAttachedCallback(this);
      }

      this.$isAttached = true;

      // When we end the attach phase for this element, one of two things will happen:
      // If this element was not part of a larger attach lifecycle, then ending the lifecycle will
      // now cause all the queued attached callbacks to fire from child to parent.
      // If it is part of a larger lifecycle, then nothing will happen. Eventually, the top most parent
      // will execute and run the queued callbacks.
      // This is how the attached callbacks are made to "bubble" and how we can be sure
      // that everything is actually attached to the document when they run.
      lifecycle.end(this);
    };

#16

don’t you think something like willAttach is easier for user to understand than attaching?


#17

It depends on your background. The “ing” and “ed” conventions are one’s I’ve seen in the past in other frameworks. We can certainly rename them to “willAttach” and “willDetach” and still keep “attached” and “detached”. That wouldn’t be any kind of breaking change at this point. Does anyone else on this thread have a strong feeling about this or argument for making the change?


#18

Definitely not strong feeling to change from me. Just throw in a debatable doubt.


#19

I do think there’s a good argument to be made since that naming pattern would be similar to other frameworks as well, particularly those in the JS space.


#20

Exactly what I (or anyone for that matter) expect them to be. Thank you.