Paiza Engineering Blog

Engineering blog of browser-based web development environment PaizaCloud Cloud IDE ( https://paiza.cloud/ ), online compiler and editor Paiza.IO( https://paiza.IO/ )

Building full-stack web service - MEAN stack development(1)

(Japanese article is here.)

f:id:paiza:20140712194904j:plain (by Yoshioka Tsuneo, @ at https://paiza.IO/)

Nowadays, it is getting hard to build web services because we need to use full-stack environment: browser(client) code for interactive UI, server code for shared data or logic, and WebSockets for real-time communication.

MEAN stack package frameworks from client side to server side, making web service development much simpler, easier, and faster.

In this article, I'll introduce one of MEAN stack implementation, AngularJS Full-Stack generator(generator-angular-fullstack), and actually run, edit, and deploy an application.

There are many articles about development only for client, or only for server. But, few mention how to mash up those individual tools. Thanks to MEAN stack, now we have a best practice to build full stack applications without bothering mashing up these components. Let's try for the cool environment !

In the following articles, based on this article, I'll also introduce how to build more practical applications.

f:id:paiza:20150703174202p:plain

AngularJS Full-stack generator Demo:http://fullstack-demo.herokuapp.com

Contents

What is MEAN stack ?

MEAN stack is a package of frameworks, MongoDB, Express, AngularJS, and Node.js, to build full-stack web services.

https://www.mongodb.org

http://expressjs.com/

https://angularjs.org

https://nodejs.org/

In the past, web service frameworks, such as CakePHP and Ruby on Rails, provided best practices to build web services easily, quickly, and securely.

But, those frameworks are based on the basic HTTP flow in which clients send requests to servers, servers generate and send HTML pages to clients, and clients render the HTML in browsers. Form action or following links completely discards the current page and renders new pages generated on the servers.

However, this request-response-based architecture causes delays in every action, and clear all states(inputs, selection scrolling, etc...), and does not provide interactive UI.

So, to make web more interactive, web services like Google Maps started using JavaScript-based Ajax technology.

At first, JavaScript was used only on specific UI parts. But, more and more parts were built using JavaScript, and eventually JavaScript framework is demanded to build web application. AngularJS is one of the most widely-used (client side) JavaScript framework.

Furthermore, request-response style architecture prevents web services from actively sending notifications to users. There are few ways to send new message notifications on chat applications, or display other players' moves in the multiplayer games, for example. WebSocket technology solves such restrictions on the web with full-duplex persistent connections. With WebSocket, because browser and server applications are persistently connected, server applications need to handle a bunch of connections at the same time. Node.js manages multiple clients(browsers) on a single thread, utilizing asynchronous operations JavaScript have.

So now, we can use JavaScript for both client side, and server side. Now, it is time to introduce JavaScript database, MongoDB! MongoDB is schema-less, so it's the best fit for rapid development.

MEAN stack is such a JavaScript based full-stack environment combining the client side framework AngularJS, server side framework Node.js/Express.JS, and database MongoDB.

MEAN stack itself is a name for combination. Actual implementation includes MEAN.IO or MEAN.JS. In this article, I'll introduce AngularJS Full-stack generator(generator-angular-stack) that is easy to start with sophisticated generators and templates.

MEAN stack features(generator-angular-fullstack)

Full-stack

Full-stack web development environments provides a best practice for clients, servers and databases. That makes easy to understand whole project structure. It is especially convenient to have preconfigured combinations among clients, servers, databases, etc...

Only one language: JavaScript

We can use one language, JavaScript, to develop whole projects including clients, servers and databases. It makes development quite stress-free because you don't no need to switch context between languages.

Based on common tools

Frameworks used in MEAN stack, MongoDB, Node.js, Express, or AngularJS, are not used solely for MEAN stack. Individual frameworks are just as widely used. Tools used in AngularJS Full-stack generator, Yeoman, Bower, npm, Grunt, Karma are also commonly-used tools.

These common frameworks or tools introduce development environment stablity, use cases, and knowledges. Web development environments changes from time to time, so it is important to use common tools in order to be flexible and catch up the latest technologies.

Generator

AngularJS Full-stack generator can generate project templates using a menu-style interface. AngularJS Full-stack generator supports the following configurations:

  • Client

    • Scripts: JavaScript, CoffeeScript, Babel
    • Markup: HTML, Jade
    • Stylesheets: CSS, Stylus, Sass, Less
    • AnguarJS Routers: ngRoute, ui-router
  • Server

    • Database: None, MongoDB
    • Authentication boilerplate: Yes, No
    • oAuth integrations: Facebook, Twitter, Google
    • Socket.io integrations: Yes, No

AngularJS Full-Stack generator also provides generators for client-side and server-side code modules. These generators make it easy to start development. Heroku or OpenShift deployment commands are also provided to release products easily.

Install

So, let's install the MEAN stack implementation, AngularJS Full-Stack generator. MEAN stack works on Mac OS X, Linux, or Windows. In this article, I'm using Mac OS X, but most of the following commands works just as well on other OS.

  • Install Node.js (If not installed)

Browse https://nodejs.org, and click "Install" to download, then install Node.js package.

  • Install Yeoman, Bower, Grunt, Gulp (If not installed)
% sudo npm install -g yo bower grunt-cli gulp
  • Install AngularJS Full-Stack generator(generator-angular-fullstack)
% sudo npm install -g generator-angular-fullstack
  • Install Homebew (If not installed)
% ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • Install MongoDB(If not installed)
% brew update
% brew install mongodb
% ln -fs /usr/local/opt/mongodb/homebrew.mxcl.mongodb.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
  • Test MongoDB

MongoDB has a flexible schema, and does not have a "create" statement to declare schema, but you can just insert data directly into the database.

In MongoDB, each data("record" in SQL) is called a "document" which stores any JSON objects, and the collection of data("table" in SQL) is just called "collection".

So now, let's try to insert, find, or delete documents.

~$ /usr/local/bin/mongo
MongoDB shell version: 3.0.2
connecting to: test
> db.my_collection.save( { 'hello' : 'world' } )
WriteResult({ "nInserted" : 1 })
> db.my_collection.find()
{ "_id" : ObjectId("558b92df5eed5e30d6c9c84f"), "hello" : "world" }
> db.my_collection.remove({})
WriteResult({ "nRemoved" : 1 })

GUI tools like MongoHub on Mac OS X also exist to make database operation easy.

f:id:paiza:20150706155509p:plain

MongoHub

Create a new project

Now, let's create a new project.

  • Make project directory
% mkdir sample
% cd sample
  • Generate project files using AngularJS Full-Stack generator
% yo angular-fullstack sample

You will encounter the following question (below). You can just choose the default options, but maybe nice to enable oAuth integration. For now, let's enable all social networks.

- Would you like to include additional oAuth strategies? 
 ◉ Google
 ◉ Facebook
❯◯ Twitter

After you answer all questions, project files are generated, and modules are installed. It may take some time for the first time. Just have a cup of coffee.

  • Updating npm packages Default npm packages on Angular Full-stack generator is a bit old, so let's update to the latest versions using npm-check-updates .
% npm install -g npm-check-updates
% npm-check-updates -u
% npm install

Start server

It is time to start the server. Just type a command like this:

% grunt serve

This will setup all tasks, and start the Node.js server, and opens the browser with URL: http://localhost:9000 .

At this point, the following features are already implemented:

  • Twitter Bootstrap based UI
  • Listing, adding, and removing items.
  • Real-time listing update on other user's adding or removing items.
  • User authentication(Sign Up, Login, SNS integration(with API key))

Now, type some words in the input box, and click "Add New". The item listing will then be updated. If you opens multiple browsers and add item, other browsers listing is automatically updated without manually reloading browser.

Edit code

Change the file contents(Keeping "grunt serve" running).

app/main/main.html:

<h1>How's it going ?</h1>

Just after saving the file, (without manually reloading the browser) the browser content is updated in real time.

Debug

Client-side debugging

You can use web browser development tools for debugging.

On Chrome, click the Chrome menu icon at the right of URL base, and choose [More tools][Developer tools]. Then you'll see the "Developer Tools" window.

f:id:paiza:20150708140450p:plain

On Safari, go Safari menu's Preference, check "Show development menu" to enable the development menu. Open a page to debug, go to main menu and choose "Development" - "Show error console" to access development tools.

In the development tools, you can see console logs, set breakpoints in JavaScript code, or print variables.

Server-side debugging

Let's try Node.js debugger(Node Inspector) for server-side code. Node Inspector runs on Chrome. So, update the "open" function on "Gruntfile.js" as shown below to specify the browser application as "Google Chrome.app".

Gruntfile.js:

            // opens browser on initial server start
            nodemon.on('config:update', function () {
              setTimeout(function () {
                require('open')('http://localhost:8080/debug?port=5858', '/Applications/Google Chrome.app');
              }, 500);
            });

Then, run Node.js server on debug mode:

% grunt serve:debug

Now, chrome developer tools will start debugging the Node.js application. The debugger is suspended on the first line of the Node.js application. Just click the "Resume" button(or "F8") to restart the application.

In this window, you can set the breakpoint, step in/over, or see variables.

f:id:paiza:20150706114630p:plain

Deployment

Because "grunt serve" starts the server on the local machine, other users cannot use your web service. To make it public, deploy the application on the public server.

Angular Full-Stack generator supports Heroku deployment.

Create Heroku account

Heroku provides a free plan to deploy one application. Just browse Heroku and click "Sign up for free" to create a new account.

https://www.heroku.com

f:id:paiza:20150706114938p:plain

Install Heroku Toolbelt

To manage application on Heroku, you will use the Heroku Toolbelt command line toolkit. Download and install the toolkit from the URL below.

https://toolbelt.heroku.com

Now, login using the "heroku" command.

% heroku login

Type your Heroku username and password.

Set up application deployment environment for Heroku

To set up the Heorku application deployment environment, use the Angular Full-stack generator command "yo angular-fullstack:heroku".

Type the application name when prompted. The application URL is http://APPLICATION.herokuapp.com .

You'll also need to install the MongoDB module. Heroku supports MongoHQ and MongoLab. For now, let's use MongoLab because of its free plan.

% yo angular-fullstack:heroku
% cd dist
% heroku addons:add mongolab

From now on, you can build and deploy the application using the "grunt" and "grunt buildcontrol:heroku" commands.

% grunt
% grunt buildcontrol:heroku

Done !

Let's access the application URL with your browser.

http://APPLICATION.herokuapp.com/

In case you encounter any errors, review log messages.

% heroku logs

SNS integration

Although Sign Up and Login are already implemented, you need to set up both API key and SECRET key to integrate SNS authentication.

Twitter

On https://apps.twitter.com , click "Create New App" to create a new application. Specify the application URL to "Callback URL"(Ex: http://paizatter.herokuapp.com ).

On the application page, see "Keys and Access Tokens" to access "Consumer Key (API Key)" and "Consumer Secret (API Secret)".

f:id:paiza:20150706115258p:plain

Facebook

On https://developers.facebook.com/apps/ , click "Add a New App". Choose "Website" and input your application name and choose the category like "Utilities" under "Choose a Category". Then click "Create App ID" to create.

Choose your application from the "My Apps" menu. Choose the "Advanced" tab and specify the application URL on "Valid OAuth redirect URIs" (Ex: http://APPLICATION.herokuapp.com ). You can specify multiple URLs, so adding "http://localhost:9000/" will be convenient for testing on local environment.

f:id:paiza:20150706115559p:plain

From application's "Settings" menu, input "Contact Email". Choose "Status & Review" and answer "Yes" on "Do you want to make this app and all its live features available to the general public?" to enable application. Now, you can get access Dashboard to get "App ID" and "App Secret".

Google

On https://console.developers.google.com/project , click "Create project". Choose your created project. From the menu on the left, choose "APIs&auth"/"Credentials". On the OAuth page, click "Create new Client ID" and choose "Web application" and click "Configure consent screen".

After the consent, type the application URL under "Authorized redirect URIs" (Ex: http://APPLICATION.herokuapp.com/auth/google/callback ), and click "Create Client ID".

f:id:paiza:20150706124704p:plain

From "APIs&auth"-"API" menu, choose "Google+ API" and enable "Google+ API". Now, you can see "APIs&auth"/"Credentials" to access Client ID(API key) and Client secret(SECRET key).

Set up API key on Heroku

After retrieving API keys and SECRET keys, use the "heroku config set" command to set keys on environment variables.

% cd dist
% heroku config set FACEBOOK_ID=xxx
% heroku config set FACEBOOK_SECRET=xxx
% heroku config set TWITTER_ID=xxx
% heroku config set TWITTER_SECRET=xxx
% heroku config set GOOGLE_ID=xxx
% heroku config set GOOGLE_SECRET=xxx
% heroku config
% heroku restart

Summary

In this article, I introduced how you can use the AngularJS Full-Stack generator to build, run, and deploy MEAN stack web services. MEAN stack makes it easy to build full-stack web services quickly. So, it is especially convenient for project startup or prototyping. Let's try it !

Note: This article just runs asample application. The following articles will provides more practical applications.

Reference

AngularJS Full-Stack generator

https://github.com/DaftMonk/generator-angular-fullstack

MEAN stack development articles
* Building full-stack web service - MEAN stack development(1)
Building Twitter-like full-stack web service in 1 hour - MEAN stack development (2)
Building a QA web service in an hour - MEAN stack development(3)

10 Japanese Otaku information web sites

f:id:paiza:20150416153238j:plain Photo by t-mizo

(by Taniguchi Tomoka)

We just started a new event ! Fusion of Programming and MANGA. Write code to get your own story !( https://paiza.jp/poh/enshura?locale=en )

paiza.jp

Do you like Japanese Cartoon?

I'm gonna introduce 10 Japanese Otaku information web sites to you.

■1.Tokyo Otaku Mode

http://otakumode.com f:id:paiza:20150416181820p:plain Production country:Japan,USA

Language:English

■2.Japan Expo

http://www.japan-expo-paris.com/fr f:id:paiza:20150417145339p:plain Production country:Japan,France

Language:Japanese,English,French

■3.Anime News Network

http://www.animenewsnetwork.com f:id:paiza:20150417124451p:plain Production country:USA

Language:English

■4.Cultuer JApan

http://www.dannychoo.com f:id:paiza:20150416153552p:plain Production country:Japan

Language:Japanese・English・Chinese

■5.CharacterJAPAN

http://characterjapan.com f:id:paiza:20150416153700p:plain Production country:Japan

Language:English

■6.OTAPARK

http://otapark.com f:id:paiza:20150416153448p:plain Production country:Malaysia

Language:English

■7.asianbeat

http://asianbeat.com/ja f:id:paiza:20150416181942p:plain Production country:Japan(Fukuoka)

Language:Japanese、English、Chinese、Korean、Thai、Viet-Namese

■8.Crunchyrol

http://www.crunchyroll.com f:id:paiza:20150416182344p:plain Production country:USA、Japanese

Language:English、Spanish、Portuguese、French、German

■9.Jurnal Otaku Indonesia

http://jurnalotaku.com f:id:paiza:20150416193730p:plain Production country:Indonesia

Language:Indonesian

■10.subculture.co.kr

http://subculture.co.kr f:id:paiza:20150416183953p:plain Production country:Korea

Language:Korean

Data binding code in 9 JavaScript frameworks

f:id:paiza:20150320120255p:plain

f:id:paiza:20140712194904j:plain (by Yoshioka Tsuneo, @ at https://paiza.IO/)

(Japanese article is available here.)

The JavaScript frameworks comes every now and then. React.js, Ractive.js, Aurelia.js, and forthcoming Angular2 !

Each framework have their own features, but what's the difference of these frameworks ? From where, should I start?

I just tried to write sample code in 9 major framework, and share the experience.

  • Backbone.js
  • Ember.js
  • Knockout.js
  • AngularJS(1.x)
  • React.js
  • Ractive.js
  • Vue.js
  • Aurelia.js
  • AngularJS2.0(alpha)

These frameworks typically have some of features below.

  • MVC/MVVM model
  • Data bindings between HTML and JavaScript
  • HTML template
  • URL routing
  • RESTful API
  • Custom directive
  • DI(Dependency Injection)

A framework may or may not contains these features, but one common and the most important feature is data binding between HTML representation and JavaScript code.

So, let's focus on the data binding and go through all 9 frameworks by writing code.

Sample code

The sample web app have two input form, first name and last name, and one output area for full name. Just after changing first name or last name, full name is updated immediately.

f:id:paiza:20150310154810p:plain

This is quite simple program, but we can see important framework behavior like:

  • How to represent variables, controller, mode, in both HTML and JavaScript.
  • How to transfer input value in HTML to JavaScript variable.
  • How to observe JavaScript variable and transfer it to HTML.

Framework comparison

So, let's go through 9 frameworks. We go through roughly in chronological order.

0. No framework(jQuery or Vanilla JS)

http://jquery.com/

HTML:

First Name: <input id="firstName"/><br>
Last Name: <input id="lastName"/><br>
Full Name: <span id="fullName"></span><br>

JavaScript:

function updateFullName(){
    var fullName = $("#firstName").val() + " " + $("#lastName").val();
    $("#fullName").text(fullName);
}
$("#firstName, #lastName").bind("change keyup", function(){
    updateFullName();
});
$("#firstName").val("Taro");
$("#lastName").val("Yamada");
updateFullName();

(Sample: http://jsfiddle.net/yoshiokatsuneo/4va165n5/ )

Before trying frameworks, let's write code without framework.

jQuery is powerful enough to handle the task with simple code. But, the code have problems. At first, data is represented not as JavaScript variable but as string in jQuery selector, like "#firstName" or "#lastName" preventing refactoring. jQuery object is just coupled with DOM and act like global variables.

The worst problem is what data exists only on HTML(DOM), and is not structured.

1. Backbone.js

HTML:

<div id="person">
    First Name: <input id="firstName" value=""><br>
    Last Name: <input id="lastName" value=""><br>
    Full Name: <span id="fullName"></span>
</div>

JavaScript:

Person = Backbone.Model.extend({});
PersonView = Backbone.View.extend({
    el: '#person',
    events: {
        'change': 'change',
    },
    initialize: function(){
        this.listenTo(this.model, 'change', this.render);
        this.render();
    },    
    change: function(){
        var firstName = $('#firstName').val();
        var lastName = $('#lastName').val();
        this.model.set({firstName: firstName, lastName: lastName});
    },
    render: function(){
        this.$('#firstName').val(this.model.get('firstName'));
        this.$('#lastName').val(this.model.get('lastName'));
        var fullName = this.model.get('firstName')
                        + ' ' + this.model.get('lastName');
        this.$('#fullName').text(fullName);
    },
});
person = new Person({lastName: "Yamada", firstName: "Taro"});
personView = new PersonView({model: person});

(Sample: http://jsfiddle.net/yoshiokatsuneo/5u9czbwe/ )

Backbone.js itself is a simple framework, having Model class and View class for MVC model

Backbone.js introduced structure with MVC model, and put data model instead of just in HTML DOM. These modularization helps to work for larger application.

HTML behavior is handled by View class that may be nested. Each view have their own model, but model and HTML is completely separated. HTML and View class and communicated through jQuery's val()/text() functions or event monitoring. View class and Model class are communicated through model's set/get function or event monitoring(listenTo()).

There is no fancy feature like data binding and we need to write code explicitly for each behavior. But, this makes each module independent, and makes Backbone.js large application friendly.

2. Ember.js

index.html:

<script type="text/x-handlebars" data-template-name="index">
First Name:{{input type="text" value=firstName}}<br/>
Last Name:{{input type="text" value=lastName}}<br/>
Full Name: {{model.fullName}}<br/>
</script>

JavaScript:

App = Ember.Application.create();
App.Person = Ember.Object.extend({
  firstName: null,
  lastName: null,

  fullName: function() {
    return this.get('firstName') + ' ' + this.get('lastName');
  }.property('firstName', 'lastName')
});

var person = App.Person.create({
  firstName: "Taro",
  lastName:  "Yamada"
});

App.Router.map(function () {
});

App.IndexRoute = Ember.Route.extend({
    model:function () {
        return person;
    }
});

(Sample: http://jsfiddle.net/yoshiokatsuneo/gLkq1sd5/ )

Unlike BackboneJS where we need to write data and JavaScript relation explicitly, Ember.js introduced data binding. Data on HTML and JavaScript is automatically updated each other.

Ember.js introduced "{{}}" syntax where we can write variables to bind to JavaScript model. Input data("firstName" or "lastName") automatically update model. For about dependency, we explicitly specify the dependency using "property" function to calculate new value when depended variable is updated.

By the data biding, we no more need to write event handling explicitly.

3. Knockout.js

HTML:

<p>First name:<input data-bind="value: firstName" /></p>
<p>Last name:<input data-bind="value: lastName" /></p>
<p>Full name:<span data-bind="text: fullName"></span></p>

JavaScript:

function AppViewModel() {
    this.firstName = ko.observable("Taro");
    this.lastName = ko.observable("Yamada");

    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();    
    }, this);
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());

(Sample: http://jsfiddle.net/yoshiokatsuneo/3q880ohq/ )

As Ember.js, Knockout.js have data binding between HTML and JavaScript. Ember.js specify dependency explicitly but Knockout.js specify variables to be observed using "ko.observable".

On the code, data written like "data-bind=“value: firstName” in HTML is tied to variable in ViewModel. On ViewMode, variable changing is detected by specifying variable as "observable()". When variables change, data specified as "ko.computed" is updated automatically, and reflected to HTML representation.

4. AngularJS(1.x)

HTML:

<div ng-app ng-controller="PersonController">
First Name: <input type=text ng-model="firstName"> <br>
Last Name: <input type=text ng-model="lastName"><br>
Full Name: {{getFullName()}}
</div>

JavaScript:

function PersonController($scope) {
  $scope.firstName = "Taro";
  $scope.lastName  = "Yamada";
  $scope.getFullName = function() {
    return $scope.firstName + " " + $scope.lastName;
   };
}

(Sample: http://jsfiddle.net/yoshiokatsuneo/pqku2r33/ )

AngularJS is full-stack framework with two-way binding, routing, RESTful API, DI.

Ember.js or Knockout.js introduced data binding, but we need to specify dependency explicitly. Whereas, AngularJS automatically re-calculated depended data without writing dependency, and it makes AngularJS code much simpler.

On HTML, we can use "Angular expression" like model="DATA" or "{{}}". Those data or expression is tied to variable or method in controllers.

We can just use normal variable representing data in controller, without using syntax to specify observation. Whenever data changes, AngularJS detect the change and re-calculate depended data or function or HTML expression.

5. React.js

JavaScript:

var MyApp = React.createClass({
  getInitialState: function(){
      return {
          firstName: this.props.firstName,
          lastName:  this.props.lastName,
      }
  },
  handleChange: function(){
      var firstName = this.refs.firstName.getDOMNode().value;
      var lastName = this.refs.lastName.getDOMNode().value;
      this.setState({
          firstName: firstName,
          lastName: lastName,
              });
  },
  render: function() {
    var fullName = this.state.firstName + this.state.lastName;
    return (
        <div>
        First name: <input ref="firstName" onChange={this.handleChange} value={this.state.firstName}/><br/>
        Last name: <input ref="lastName" onChange={this.handleChange} value={this.state.lastName}/><br/>
        Full name: {fullName}
        </div>);
  }
});

React.render(<MyApp firstName="Taro" lastName="Yamada" />, document.body);

(Sample: http://jsfiddle.net/yoshiokatsuneo/k5d6jhhb/ )

React.js is a framework specialized for data binding, it also simplify data binding utilizing VirtualDOM. I

AngularJS have two-way binding. But, we need to update JavaScript models as the same way we intended to update HTML DOM. To add one item in HTML DOM, just specifying the final model is not enough but we need to add one item in the model.

React.js automatically detect how the DOM is updated without explicitly specifying how to update, and only the difference is applied to DOM. So, we no more need to manage how to change model.

On code, React.js embed HTML representation on JavaScript code using JSX syntax.

Embedded HTML is not directly updated to DOM on HTML, but stored as VirtualDOM. When we need to change state, we use setState() function. Then React.js detect the difference on VirtualDOM and update state difference to HTML. React.js have smaller performance impact because React.js does not directly manipulate DOM in HTML but manipulate VirtualDOM and only update the changing.

6. Ractive.js

HTML:

<script type="text/reactive" id="tpl">
First Name:<input type="text" value="{{firstName}}"/><br/>
Last Name:<input type="text" value="{{lastName}}"/><br/>
Full Name: {{fullName()}}<br/>
</script>
<div id='container'></div>

JavaScript:

var ractive = new Ractive({
  el: 'container',
  template: '#tpl',
  data: {
    firstName: 'Taro',
    lastName: 'Yamada',
    fullName: function () {
        return this.get( 'firstName' ) + ' ' + this.get( 'lastName' );
    }
  },
});

(Sample: http://jsfiddle.net/yoshiokatsuneo/d8dkppdb/ )

Ractive.js introduced simple data binding on HTML. Ractive.js specialized for data bindings like React.js. But, while React.js focuses on JavaScript, Ractive.js focues on HTML and minimize JavaScript code.

On HTML, we use "{{}}" to specify data binding, and the data is automatically tied to model in JavaScript. That makes JavaScript code simple.

7. Vue.js

HTML:

<div id="person">
    First Name: <input v-model="firstName"><br/>
    Last Name: <input v-model="lastName"><br/>
    Full Name: {{fullName}}<br/>
</div>

JavaScript:

var demo = new Vue({
    el: '#person',
    data: {
        firstName: 'Taro',
        lastName: 'Yamada',
    },
    computed: {
        fullName: {
            get: function(){
                return this.firstName + ' ' + this.lastName;
            }
        }
    },
})

(Sample: http://jsfiddle.net/yoshiokatsuneo/3gdzaw94/ )

Vue.js implements two-way data binding, as simple as possible. HTML is even more natural than Ractive.js.

On HTML, data written in "{{}}" or v-model is automatically tied to model in JavaScript.

It is quite simple, so good when we design HTML, prototype, or write small application.

8. Aurelia.js

app.html:

<template>
  <section>
    <form role="form">
      First Name: <input type="text" value.bind="firstName"><br/>
      Last Name: <input type="text" value.bind="lastName"><br/>
      Full name: ${fullName}
    </form>
  </section>
</template>

app.js:

export class Welcome{
  constructor(){
    this.firstName = 'Taro';
    this.lastName = 'Yamada';
  }
  get fullName(){
    return `${this.firstName} ${this.lastName}`;
  }
}

(Template project: http://aurelia.io/get-started.html)

Aurelia.js is a full-stack futuristic framework with ECMAScript 6/7.

Aurelia.js implements full-stack features introduced in AngularJS like two-way data binding, routing RESTful API, DI. At the same time, it is simple and better performance like Ractive.js/Vue.js utilizing ES6/ES7's feature like module or Object.observe().

It is one of the latest framework looking ES6-era, and works just now using polyfil.

HTML template is just ES6 template. We embed data using "${}" or "value.bind".

Controller is written as ES6 class, variables or get/put property in "this" is two-way bound to data in HTML.

9. AngularJS2.0(alpha)

app.html:

First Name: <input type=text [value]="firstName" #first (keyup)="firstNameChanged($event, first)"><br/>
Last Name:  <input type=text [value]="lastName"  #last  (keyup)="lastNameChanged($event, last)"><br/>
Full Name:  {{fullName}}

app.js:

import {Component, Template, bootstrap} from 'angular2/angular2';

// Annotation section
@Component({
  selector: 'my-app'
})
@Template({
  url: 'app.html'
})
// Component controller
class MyAppComponent {
  constructor() {
    this.firstName = 'Taro';
    this.lastName = 'Yamada';
    this.updateFullname();
  }
  changed($event, el){
    console.log("changes", this.name, el.value);
    this.name = el.value;
  }
  updateFullname(){
    this.fullName = this.firstName + " " + this.lastName;
  }
  firstNameChanged($event, first){
    this.firstName = first.value;
    this.updateFullname();
  }
  lastNameChanged($event, last){
    this.lastName = last.value;
    this.updateFullname();
  }
}
bootstrap(MyAppComponent);

(Template project: https://angular.io/docs/js/latest/quickstart.html)

AngularJS2.0(or Angular2, alpha version) is a framework announced special development site http://angular.io in AngularJS conference ng-conf.

It will take like one year to actual release, but I checked it out because AngularJS2.0 is quite attracted.

AngularJS2.0 is based on ES6 as Aurelia.JS. AngularJS2.0 uses AtScriptTypeScript that add static type checking or annotation to JavaScript. That ease syntax error detection or IDE integration to improve productivity.

AngularJS2.0 trashed two-way data binding but need to specify behavior explicitly. It makes behavior more clear and improve performance by removing digest loop.

On JavaScript code, we use @Component or @Template to specify element or template tied to the component. we create controller related to element id to specify behavior.

ng-xxx syntax is removed but introduced syntax like "[expression]" for JavaScript to HTML data transfer, "(event)" for HTML to JavaScript event propagation, "#element" to refer elements. There is no more scope, but variable on this can be just written in HTML.

Summary

I introduced, practically all, 9 major framework.

Major target of those framework would be, Backbone.js for large application with customized framework, Ember.js/Knockout.js for performance sensitive and more productive projects, AngularJS for normal projects, React.js for simple JavaScript code, Ractive.js/Vue.js for HTML/design centric projects, Aurelia.js for the future, AngularJS2.0(alpha) for framework research, as of now.

Each framework have their own philosophy or design that helps to develop web application even if we don't use the application even if we don't use the framework. So, let's have fun with JavaScript frameworks !


paiza.IO is online coding environment where you can just write and run code instantly. Just try it out !