Skip to content

Upcoming core rework #15

@solkimicreb

Description

@solkimicreb

The next release will include several breaking changes to the core. It aims to make the initial learning curve smaller and to simplify and speed up the core. Apart from the features mentioned here, I plan to add the following changes.

The component.useOnContent method will be removed

Instead only component.use will remain and middlewares behavior will be configurable with the middleware.$process array. It may contain code for COMPONENT, ELEMENT, TEXT and COMMENT nodes.

Take a look at the following snippet.

nx.component({root: true})
  .useOnContent(interpolate)
  .use(setup)
  .register('interpolate-comp')

function interpolate (node, state) {
  if (node instanceof Text) {
    node.nodeValue = node.nodeValue.replace(/\${(.+?)}/g, (match, prop) => state[prop])
  }
}

function setup (comp, state) {
  state.message = 'Hello World!'
}

It will turn into the following after the change.

nx.component({root: true})
  .use(interpolate)
  .use(setup)
  .register('interpolate-comp')

function interpolate (text, state) {
  text.nodeValue = text.nodeValue.replace(/\${(.+?)}/g, (match, prop) => state[prop])
}
interpolate.$process = [nx.types.TEXT]

function setup (comp, state) {
  state.message = 'Hello World!'
}

By default a middleware will only process the component node and non of its content. It moves complexity from the user to the contributors and middleware developers.

Middleware inheritance and the isolate config will be removed

Middlewares will no longer be inherited from ancestor components. Instead every component will have full control over what middleware it uses.

Take a look at the following snippet.

nx.components.app()
  .use((comp, state) => state.name = 'Bob')
  .register('app-comp')

nx.component().register('my-comp')
<app-comp>
  <my-comp>${name}</my-comp>
</app-comp>

In the current version this displays ‘Bob’, but in the next version it would display ‘${name}’. The reason is that my-comp wouldn’t inherit the interpolate middleware from app-comp.

Instead of relying on middleware inheritance the next release will introduce the base component which includes all of the important middlewares. It will serve as a base for most of the current components too. The above example could be rewritten as below with the next version.

nx.components.app()
  .use((comp, state) => state.name = 'Bob')
  .register('app-comp')

nx.components.base()
  .register('my-comp')
<app-comp>
  <my-comp>${name}</my-comp>
</app-comp>

This makes components more modular an easier to maintain as they take full responsibility of their behavior.

The this context in middlewares will be changed

Previously the this context inside middlewares was the currently processed node instance - which was also the first argument. This will change. The this context will always be the parent component instance (a web component). This means that for normal component middleares nothing will change. Content middlewares will get a reference to the parent component through the this context though.

To stay consistent, the this context will be set to the current component in every callback (attributes, observed functions, etc) too.

State boundaries will be reworked

State boundaries doesn’t always match with component boundaries in NX. For example the repeat attribute may add inheriting states to non component elements.

Handling state boundaries was a big hack, which was hidden by the attributes and props middleware. The next release will change this. The middleware.$boundary boolean prop will indicate that the middleware is a boundary middleware. NX injects the context/parent state into boundary middlewares on state boundaries instead of the new state. You probably won’t have to use this, but it makes developing complex middlewares easier for maintainers.

Many middlewares will be reworked

Most middlewares will be reworked form content to component middlewares (meaning that they will have middleware.$process=[nx.types.COMPONENT]). If all goes well, after the change only the attribute and interpolate middlewares will process content. Everything else will run only once on the component instance.

This removes a lot of unnecessary work and speeds up NX.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions