app-decorators icon indicating copy to clipboard operation
app-decorators copied to clipboard

Collection of JavaScript decorators (ES7) for building fast, scalable, performant web apps

app-decorates (Beta)

Quickstart with app-decorators-cli

# For Mac
npm install appdec-cli-osx --global

# For Windows
npm install appdec-cli-win --global

# For Linux
npm install appdec-cli-linux --global

# then
appdec create --name mymodule
appdec run --name mymodule --watch --server

See app-decorators-cli(Beta)


Why app-decorators?

  • compiler first AOT-Compiler, do computation at compile time and not at runtime
  • write less, do more
  • and more (coming soon)

Runtime package

Package Version Dependencies DevDependencies
app-decorators npm Dependency Status DevDependency Status

Core compiler packages

Package Version Dependencies DevDependencies
app-decorators-component npm Dependency Status DevDependency Status
app-decorators-view-precompile npm Dependency Status DevDependency Status
app-decorators-style-precompile npm Dependency Status DevDependency Status
app-decorators-component-register npm Dependency Status DevDependency Status
postcss-parse-atrule-events npm Dependency Status DevDependency Status
preset-app-decorators npm Dependency Status DevDependency Status

Command line tools (Cli) for Mac, Linux or Windows

Package Version Dependencies DevDependencies
appdec-cli-osx npm Dependency Status DevDependency Status
appdec-cli-win npm Dependency Status DevDependency Status
appdec-cli-linux npm Dependency Status DevDependency Status

Todomvc

Package Version Dependencies DevDependencies
app-decorators-todomvc npm Dependency Status DevDependency Status

Simple example

Item.js
import { component, view, on, action, style } from 'app-decorators';

@style(`
    /** These atrule (@) events will be loaded asynchronous (non blocking) **/
    
    /** will be loaded on load event **/
    @on load {
        @fetch path/to/on/load.css;
    }
    
    /** will be loaded when clicked .up class **/
    @on click .up {
        @fetch path/to/on/click/up.css;
    }

    /** will be loaded when url changed **/
    @action hello/my/friend.html {
        @fetch path/to/on/some/route/action.css;
    }

    /** critical path (inline css will appear immediately) **/
    my-box div {
        width: 100px;
        height: 100px;
    }
`)
@view(`
    <h3>{{head}}</h3>
    <div class="count">{{count}}</div>
    <div>
        <span class="up"> + </span>
        <span class="down"> - </span>
    </div>
    <div>
        <a href="?state=reset">clear count</a>
        <a href="?state=destroy">destroy</a>
        <a href="hello/my/friend.html">destroy</a>
    </div>
`)
@component({
    name: 'my-box'
})
class Item {

    @view.bind count = 0;
    
    @on('click .up') onClickUp() {
        ++this.count
    }
    
    @on('click .down') onClickUp() {
        --this.count
    }
    
    @action('?state={{type}}') onUrlStateChanged({ params }){
        
        let { type } = params;
        if(type === 'reset'){
            this.count = 0;   
        }
        // remove it self
        else if(type === 'destroy') {
            this.parentNode.removeChild(this);
        }
    }
}

export {
    Item
}

app.js


let item = Item.create({
    head: 'Some description'
});

document.body.appendChild(item);

Result in Markup

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>my com-item</title>
    </head>
    <body>
        <com-item>
            <!-- for fast rendering, style will be appended onLoad -->
            <style>
                my-box h3 {
                    font-size: 14px;
                }
                my-box div {
                    border: 1px solid gray;
                }
            </style>
            <h3>Some description</h3>
            <div class="count">0</div>
            <!-- on click .up or .down it will increment/decrement .count -->
            <div>
                <span class="up"> + </span>
                <span class="down"> - </span>
            </div>  
            <div>
                <a href="?state=reset">clear count</a>
                <a href="?state=destroy">destroy</a>
            </div>
        </com-item>
    </body>
</html>

Its also possible to put <com-item></com-item> direct in the dom like:

<body>
    <!-- It will render, see above (result in markup) -->
    <com-item></com-item>
</body>

Browser Support

Tables Version
Chrome latest stable
Edge latest stable
Firefox latest stable
Opera latest stable
Safari MacOS >= 9
IE >= 11
--------------------------- -------------------------------
iOS Safari >= 10.0.0
iOS Chrome >= 58.0.0
iOS Firefox >= 55.0.0
--------------------------- -------------------------------
Android Chrome >= 58.0.0
Android Firefox >= 55.0.0

Documentation

Decorators
  • @component
  • @view
  • @on
  • @action
  • @style
Libraries
  • Router
  • Customelement
  • Eventhandler
  • View
  • Stylesheet

Tests and Contributors guidelines

// init
npm install --global lerna

// install and test packages
make lerna-bootstrap
make lerna-test

// install and compile for browser tests
make install
make compile // required for node css fixture server
make test // and run this in separate window

Contributors guidelines (currently internal info)

build new binary on new version

Contributors guidelines (currently internal info)

// init
npm install --global lerna

// lerna-bootstrap for packages
lerna bootstrap -- --no-package-lock

// or make install for acceptance tests
cd packages/app-decorators
jspm install
cd ../..
make prepare-compile // ignore the :4000 error
make gulp-compile

// browser test
make test

// packages test
make lerna-test

// clean packages
make lerna-clean
make clean
git checkout packages/app-decorators/package.json
git checkout jspm.config.js

// when publish
- *1 update in package.json version
- update babel-preset-app-decorators to same in *1
- packages/app-decorators-todomvc update preset

app-decorators and its packages are distributed as a monorepo.

(c) 2015 - 2018 Serkan Sipahi

App-Decorators may be freely distributed under the MIT license.