composite-js

Architecture      ≡ Table of Contents      Expression Language


Getting Started

Contents Overview

Prerequisites

Choose a Runtime Variant

The runtime consists of one JavaScript file. It can be included through a release-channel URL or downloaded as a release.

Release channels continuously provide the latest final major versions.

Each release provides versions for different purposes. These versions are available in two variants. The standard variant is compressed for production environments. The uncompressed and documented max variant is available for development and error analysis.

First Composite

Create index.html and declare a composite:

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/@seanox/composite-js/release/composite-js-testing-max.js"></script>
  </head>
  <body>
    <section id="example" composite></section>
  </body>
</html>

The combination of the composite attribute and the id attribute defines the composite ID, in this case example.

Create the resources of the composite module:

+ modules
  - example.css
  - example.js
  - example.html
- index.html

Implement the composite script in modules/example.js:

const example = {
    message: "",
    validate(element, value) {
        return true;
    }
};

#export example;

The composite script establishes the application module of the composite. The runtime does not prescribe how application logic must be structured. It can be implemented using objects, functions, classes, or combinations of these structures.

Implement the view in modules/example.html:

<input id="message" type="text"
    events="input change" validate render="#preview"/>
<p id="preview">{{example.message}}</p>

Optional styles in modules/example.css:

#example {
  padding: 8px;
}

The view describes the declarative presentation of the composite. It contains markup and expressions and refers to application data provided by the application module. The expression {{example.message}} accesses data exposed by the application module through composite binding.

What Happens During Realization

When the runtime encounters the composite declaration, it forms the composite ID from the id attribute and the composite attribute, resolves the corresponding composite module and loads its resources:

Composite Module
    -> example.html
    -> example.css
    -> example.js

The composer then realizes the composite within the declared DOM context.

Conceptually, the realization follows this dependency chain:

Composite declaration
    -> Composite ID
        -> Composite Module resolution
            -> resource loading
                -> Composite Script execution
                    -> Application Module establishment
                        -> View realization
                            -> Composite Binding
                                -> running Composite

As shown here, the composite lifecycle begins with the loading of the composite module. At the end of this process, the composite reaches its running state. The resulting composite consists of:

Composite
    -> DOM context
    -> JavaScript context
    -> CSS context

Composite Script and Application Module

The composite script and the application module are related but distinct concepts.

Composite Script
    -> establishes
        -> Application Module

The composite script is the executable JavaScript program of the composite module, whose execution establishes the application module as the resulting runtime representation of the application logic.

Objects that participate in composite binding must be explicitly exported:

#export example;

Without the export, the object would remain internal to the composite script and would not be available to the view.

Composite Binding

Composite binding connects the declarative DOM structure of the view with explicitly exported objects of the application module.

View
    <-> Composite Binding <-> Application Module

The runtime resolves this relationship during realization and makes the application data available to the view.

Optional Next Step: Reactive Application Data

The previous example uses explicit rendering so that the data flow remains visible.

const example = {
    message: "",
    validate(element, value) {
        return true;
    }
}.reactive();

#export example;
<input id="message" type="text"
    events="input change" validate/>
<p>{{example.message}}</p>

When reactive application data is used, the runtime reacts to changes of its properties. Any expression in the view that depends on a changed property is updated automatically, so explicit rendering is no longer required in this case.

Learning Path

The following tutorials provide separate learning paths for micro-frontends and Single-Page Applications. Each path consists of incremental steps, from a prototype to a finished application, that extend or modify the previous result. The commented differences between consecutive steps illustrate the implementation of individual concepts.


Architecture      ≡ Table of Contents      Expression Language