Vue.js : Best way to implement MPA(Multi page app) in laravel - javascript

I have been looking around for quite a time, But didn't got anything convening.
What will be the best approach and practice to implement Vue MPA architecture in laravel.
Searched for quite a bit. But there isn't anything which will give you a clear idea. Your answer will help alot, Please make it brief.
It will also be helpful to answer the point :
Is it a good idea to use just laravel as a data API, And keep Vue
separate from laravel ?
Best approach for implementing hybrid of SPA and MPA.

Some options that I've already used:
Use Laravel to render the "main view" + connect vue.js application.
Basically laravel will render the Vue application and every request goes throught an API.
Easy to setup
Authentication + user validation is easier (you can use laravel session manager for that - don't need to build/use tokens or whatever. "No need to worry about your application state".)
Easy to "disconnect" from Laravel - if you choose in the future to decouple the SPA application.
Use laravel (or lumen) only as an API, and on another server render a SPA.
This can take more time, since you'll need to setup an extra server, prepare cross-origin, etc.
Also easy to setup, but can take more time than option #1
You'll need to create something for user validation/state management, etc.
Easy to place into laravel, if you decide in the future to use "only one app".
Can be easier to maintain/scale (if you have a frontend team, they don't need to worry about laravel - same for your "laravel team", they "won't need to worry" about the frontend)
Laravel + Vue = "one application"
You can use Laravel to render all views + vuejs for components/elements in the page.
Easy to setup. You have laravel + vuejs, and they are already prepared to be used together. https://laravel.com/docs/5.5/frontend#writing-vue-components
Not so easy to decouple. In this case you'll need to create the same views for vue.js. This can take time.
This is the "traditional web development" (in my opinion). If I had to start a project like this today, I wouldn't create all pages in Vue.js + something in Laravel (Controller + new route) to render this view. If you do this (again - my opinion), it's just extra work. If you are worried about SEO, there are "fallbacks"/extra options.
--
All options are testable + scalable.
It also depends on how you start (Should I worry about how I'll decouple the app in the future? Laravel + Vue will be for good?), how your team will work (Does the frontend team really needs to setup laravel or they only need to worry about the frontend code?), etc.
Not sure if i answered your question, if not, please leave a comment.

You haven't found anything clear because there isn't really anything to talk about other than 'What feels right to your understanding and project needs'. If you found yourself very unsure, feel free to dive into doing whatever makes sense to you and then re-adjust the structure when you gain more experience.
Also, read books about system architecture, those will help a lot.
Is it a good idea to use just laravel as a data API, And keep Vue separate from Laravel?
By this, I'm assuming you mean a SPA? Honestly, if your application is small, then I see this is fine.
Larger applications tend to be difficult to maintain if they were SPA.
Read: https://medium.com/#NeotericEU/single-page-application-vs-multiple-page-application-2591588efe58
If you end up using Laravel as an API endpoint, then use the stripped down version of it, Lumen, because it comes without Blade and few other stuff. Lumen is stripped down version to act as an API-endpoint.
Best approach for implementing hybrid of SPA and MPA.
From my experience having attempted to build 4+ projects as hybrids, here's what I found the most optimal structure:
My example will be about an app that saves 'Posts'.
1. Use a repository design pattern.
This one will save you a lot of headache in maintaining your code and maintain a DRY (Don't Repeat Yourself) concept on your code.
Create a directory App\Repositories\
Make a new class PostsRepository. This one will be the one communicating with the database and contains most of the logic.
Create the directory App\Services\
Make a new class PostsService. This one will have the PostsRepository in its constructor.
The service class will be one handling taking user's input whether from the Web controller or the API controller.
<?php
namespace App\Service;
use App\Repositories\PostsRepository;
class PostsService;
{
protected $repository;
public function __construct(PostsRepository $repository)
{
$this->repository = $repository;
}
}
Make a seperation between Web and API controllers.
For web controllers, you create the controller like usual:
php artisan make:controller PostsController
For API controllers, you create the controller to be inside an Api folder.
php artisan make:controller Api\PostsController
The last command will create the directory App\Http\Controllers\Api and have the controller be placed in it.
Recapping
Now we have different controllers to return results appropriate to the startpoint (web / api).
We have services that both the (web / api) controllers send their data to be validated (and have the action taken by the repository).
Examples:
<?php
namespace App\Http\Controllers;
use App\Service\PostsService;
class PostsController extends Controller
{
protected $service;
public function __construct(PostsService $service)
{
$this->service = $service;
}
public function index()
{
/**
* Instead of returning a Blade view and
* sending the data to it like:
*
* $posts = $this->service->all();
* return views('posts.index', compact('posts'));
*
* We go ahead and just return the boilerplate of
* our posts page (Blade).
*/
return view('posts.index');
}
}
...
<?php
namespace App\Http\Controllers\Api;
use App\Service\PostsService;
class PostsController extends Controller
{
protected $service;
public function __construct(PostsService $service)
{
$this->service = $service;
}
/**
* Returns all posts.
*
* A vue component calls this action via a route.
*/
public function index()
{
$posts = $this->service->all();
return $posts;
}
/**
* Notice we don't have a store() in our
* Web controller.
*/
public function store()
{
return $this->service->store();
}
}
...
<?php
namespace App\Services;
use App\Repositories\PostsRepository;
class PostsService extends Controller
{
protected $repository;
public function __construct(PostsRepository $repository)
{
$this->repository = $repository;
}
public function all()
{
$posts = $this->repository->all();
return $posts;
}
public function store()
{
$request = request()->except('_token');
$this->validation($request)->validate();
return $this->repository->store($request);
}
public function validation(array $data)
{
return Validator::make($data, [
'content' => 'required|string|max:255',
//
]);
}
}
In our PostsRepository we actually call methods that save the data. E.g. Post::insert($request);.
2. Dedicate an API group
Route::prefix('api/v1')->middleware('auth')->group(function() {
Route::post('posts/store', 'Api\PostsController#store')->name('api.posts.store');
});
Giving API routes a ->name() helps when you make phpunit tests.
3. Blade views
Those are ought to be stripped-down simple.
views/posts/index.blade.php:
#extends('layouts.app', ['title' => trans('words.posts')])
#section('content')
<!-- Your usual grid columns and stuff -->
<div class="columns">
<div class="column is-6">
<!-- This comp. can have a modal included. -->
<new-post-button></new-post-button>
<div class="column is-6">
<posts-index-page></posts-index-page>
</div>
</div>
#endsection
4. Vue structure.
https://github.com/pablohpsilva/vuejs-component-style-guide
So those Vue components might live in resources/assets/js/components/posts/ where inside /posts/ I'd have folders titled for example IndexPage, CreateModal, EditModal with each folder having its .vue and README.md.
I'd use the <posts-index-page> in index.blade.php and drop in the <post-create-modal> and <edit-post-modal> whenever I want.
All the vue components will use the API endpoint we specified in our Routes file.

Related

Using singleton design pattern for better code quality

We have a node-express app with multiple endpoints. We have created 5 different services that does different jobs such as making HTTP calls, process/modify data, cache data, search specific data, etc.
We realized that the services we created are not singleton. The services were being instantiated left right and center. A total of 26 objects were being created.
We changed that and made all our services singleton, and now only 5 objects get created across the entire application. We want to structure the app properly now.
We want each express route to call DataService (which checks if that data is available in the CacheService, if not then make an HTTP call and store the data in cache and return the data to the express route).
But, the current code makes use of CacheService and DataService together to check if the data is available in the cache or fetches fresh data using DataService. Which approach is recommended? Use one service (Dataservice) that internally uses multiple services (CacheService, DataModificationService), or use all the services together in the express route (DataService, CacheService, DataModificationService)
Before making the classes singleton, we were using static classes. Do we even need to make services singleton or continue to use static classes? Which one is more recommended and why?
Here's the code that we've written to create a Singleton Service . Is this the correct way?
class DataService {
private dataModificationService: DataModificationService;
private tokenService: TokenService;
private constructor(tokenService: TokenService, dataModificationService: DataModificationService) {
this.tokenService = tokenService;
this.dataModificationService = dataModificationService;
}
public static getInstance(): DataService {
const dataModificationService: DataModificationService = DataModificationService.getInstance();
const tokenService: TokenService = TokenService.getInstance();
if (!DataService.instance) {
DataService.instance = new DataService(tokenService, dataModificationService);
}
return DataService.instance;
}
}
It's good that you've reduced the number of singletons. Now try and get rid of the rest!
Changing from a static class to a singleton object often makes no difference - they're both just ways of making stuff global.
What you need to be doing is looking at how many places use each singleton, and if the usages are localised, then try to replace the singleton with dependency injection. Nothing fancy, just pass the (non static) instance of the DataService or whatever in as a parameter where needed. If that would create too much code, then what you've done is perfectly fine.

.NET Core MVC - Different Controllers, Different HTML In Same View-page, Different Scripts

I am developing an application using .NET Core MVC. I have different data-sets that loads through request to the controllers. For example, I have this controller methods:
localhost/Election
localhost/Election/2008
localhost/Election/2008/United_States
And the methods that works for this parameters are in ElectionController like:
public async Task<IActionResults> Index(){
// Return a list of data
}
public async Task<IActionResults> Index(string year){
// Return a list of data
}
public async Task<IActionResults> Index(string year, string location){
// Return a list of data
}
What happens is, these methods return some data in the same view page / Election/ Index.
But I want to use different JavaScript codes and different html to represent this data-sets in the /Election/Index view page. Let's consider a scenario:
If user enters : localhost/Election Then application is Rendering some table and using /script/jsCode1.js
When user enters into: localhost/Election/2008 Then application is Rendering some cards and using /script/jsCode2.js
When user enters into: localhost/Election/2008/United_States
Then application is Rendering some charts and using /script/jsCode3.js
How should I approach to solve this problem?
you need to render then in different pages.You should not render all in one.
Ex: localhost/Election will render Table.Html with their respective js. You can return specific html for specific endpoint.
Then you will have uno html for one of your endpoints in controller.
Ok so... first of all, there are a few different ways to deal with your issue, and each will teach you something very important about the framework. The first two I'll mention are not suggested but you should know what is possible to do, in general, even though in this specific scenario they are.... bad, conceptually (imo)
So, first of all: You can add a property to the Model. Say, HasYear... and HasCountry. And in your view do a switch or an if and output the needed scripts and/or html.
Second: You can have each of the Controller endpoints use a different view. So, instead of return View() at the end, you return View('IndexWithElection)andreturn View('IndexWithCountry')`
And here's the actually correct way to deal with this, conceptually:
The other two endpoints you have called Index are not Index endpoints. One is Year and the other is Country. You can annotate those endpoints with, say, [Route("{year}")] and [Route("{year}/{location}")]. So now you have three different controller actions, with explicit routes, and explicit View cshtmls.
Good luck!

AngularJS - generating view from .NET controller only executed once

I have a MVC .NET application with AngularJS. In my route provider I use the controllers of mvc for retreiving the views as follows:
.when('/Units', {
templateUrl: 'Unit/Units'
})
.when('/UnitsDetail', {
templateUrl: 'Unit/UnitsDetail'
})
And my .NET UnitController has the following methods:
[Authorize]
public ActionResult Units()
{
return View();
}
[Authorize]
public ActionResult UnitsDetail()
{
ViewBag.reference = Guid.NewGuid().ToString().Substring(0, 6);
return View();
}
For the UnitsDetail view I need a reference that is generated in the UnitsDetail() method.
The problem comes when I go from Units to UnitsDetail several times. The first time the UnitsDetail() method is called and thus, the reference is generated but if I go back to Units and access again UnitsDetail the method is not called and the reference is the same. I need to generate one reference each time.
I know I could generate it using JS in the client or make an AJAX request from Angular to the server but what I really want to know is how to make Angular call the method UnitsDetail() every time I go to "#/UnitsDetail".
Thanks!
By default angular will cache all views in its template cache.
This is by design.
Angular expects the view to be just static HTML with the dynamic part marked using the {{ dynamicScopeVariable }} code. Angular will use scope objects to replaces the dynamic bit . But the static part will be shown from the cache.
The first time you execute the view , the view is cached.
You have 2 options here. Actually just one which is good from the Design point of you #2.
Option #1
Disable template caching in Angular as shown here
https://stackoverflow.com/a/27432167/2794980
This means that angular will call the HTML ACTION every time it needs the view.
This is not the best way to use angualar but it will work. You should also consider the performance side .. By far the most time consuming call on a ASP.NET MVC applications are Actions calls. This method means that while you are using a client side MVC framework , you are not utilizing one of its important benifits.
Options #2
Use a angualar service to get the GUID from back end . i.e. the code below.
ViewBag.reference = Guid.NewGuid().ToString().Substring(0, 6);
Preferably use a WebAPI if u can ( your request will be small ). The use angular to replace the GUID in ur VIEW.
It is not clear from the question why you need the GUID and if you could do with generating a random unique number using Javascript . If that is possible , it might be the best solution . But based on the info in the question you could use either of option 1 or 2.
Edit : Didn't realize that you have already tried option 2 , in that case Option 1 it is.
Edit 2 : If you want to remove a single element from the cache , you can do
$templateCache.remove("<Element Name>");
or you could use the
$cacheFactory.remove("Name")
Read more about cache factory here :
https://docs.angularjs.org/api/ng/service/$cacheFactory
The name is generally the page name , you can look at the template cache or cache factory object in debugger console to find the exact name.

Is this architecture still valid under Angular 1.2 and above

There are many code examples using $resource out there. I came across this one, and the code is quite clearly laid out: https://github.com/apotry/stockwatch
I like this example because:
It interacts with a Rails backend, which is how I am using Angular
It uses $resource
It is using a non-rest route (ohlc)
The code is quite clean
To call the functions defined is quite simple as shown in the controller code below, but is it a good idea to embed the save in the factory?
My question is: now that Angular 1.2+ includes promises, is this type of code still valid and considered a good practice? How would this code respond to an error state?
Here the resources are defined
app.factory('Stock', ['$resource', function($resource) {
function Stock() {
this.service = $resource('/api/stocks/:stockId', {stockId: '#id'}, {'update': { method: 'PUT' }});
};
Stock.prototype.all = function() {
return this.service.query();
};
Stock.prototype.delete = function(stId) {
return this.service.remove({stockId: stId});
};
Stock.prototype.create = function(attr) {
return this.service.save(attr);
};
Stock.prototype.update = function(attr) {
return this.service.update(attr);
};
Stock.prototype.ohlc = function(stId) {
return $resource('/api/stocks/:stockId/ohlc', {stockId: '#id'}).get({stockId: stId});
}
return new Stock;
}]);
Here is an example of the delete, create and a custom route (ohlc):
$scope.requestOHLC = function (stockid) {
return Stock.ohlc(stockid);
}
$scope.createStock = function() {
$scope.fetchYahooFinanceData($filter('uppercase') ($scope.newCompany["symbol"])).then(function(result) {
$scope.error = false;
$scope.stocks.push(Stock.create(result));
$scope.newCompany = '';
}, function(error) {
$scope.error = true;
});
};
$scope.deleteStock = function(id, idx) {
Stock.delete(id);
$scope.stocks.splice(idx, 1);
};
EDIT
I am trying to work out a simple and clear practice for using $resource based rest routes in angular.
Different from the above code, but based on it. Assume the code below uses a service which is basically the same as the factory above. In this example I call one REST resource to create a new resource (rails table entry), and then pass the newly created id to another call. Note that createPanelHeader references the $scope.selector.paneldata.primer3_parameter_id scope variable. Not sure if this is a good practice either.
I found this would not work unless I uses $promise.then but this seemed a bit convoluted. Am I on the right track?
// Section: Create Panel header
createPrimer3Parameter = function() {
primer3_parameter = Primer3Parameter.create().$promise.then(function(primer3_parameter){
$scope.selector.paneldata.primer3_parameter_id = primer3_parameter.id;
createPanelHeader();
}, function() {
alert('Error creating primer3parameter');
})
};
COMMENT
I am really just trying to work out a simple method for accessing REST resources from a Rails API, with at most 1 level of nesting. I think I am missing something as it seems remarkably difficult.
What I am hearing so far is not to use $resource, even under 1.2. That I should instead use raw $http or Restangular.
Also, there seem to be some 1.2 changes that affect Restangular. The solution feels a bit like a hack to me:
https://github.com/mgonto/restangular#using-values-directly-in-templates
UPDATE
I didn't really come away 100% clear, so I have posted a Bounty: https://bountify.co/write-an-angular-service-for-these-rails-routes-using-restangular
is this type of code still valid and considered a good practice?
This code is valid, but considered deprecated as of 1.2.0-rc3. It will work in all version of angular 1.2 and 1.3 up to but not including 1.3.0-beta10, where automatic promise unwrapping has been removed.
$scope.stocks.push(Stock.create(result));
In the line above you've created an array of promise objects on $scope. Then in index.html.erb you are referencing the promise directly via the stock iterator:
<li ng-repeat="stock in stocks">
<div id='symbol'>
{{stock.symbol}}
</div>
The non-deprecated way of handling promises does not allow you to bind directly to the promise like this.
How would this code respond to an error state?
The app is handling errors here:
}, function(error) {
$scope.error = true;
});
and here:
<div ng-show="error">
There was a problem with the Yahoo Finance API. Please try again later.
</div>
For error handling, you're not binding with a promise directly so this works fine in all versions of angular.
A better way?
First, shelf the javascript directory structure in the stockwatch example. Then, follow this directory structure instead. Finally, integrate Restangular into your project. Create a stockModel factory that internally instantiates a Restangular object, but returns the object that will be populated later after the promise resolves (model). Instead of binding a promise in your partial, bind the unpopulated result object.
.factory('stocksModel', function (Restangular) {
var model = {};
var rest_stocks = Restangular.all('stocks');
model.doSomethingRESTful = function (...) {
// return a promise in case the controller needs it
return rest_carts.some_restangular_method(...)
.then(function() {
model.some_data_which_was_acquired_RESTfully = ...;
});
};
return model;
});
In your controller:
$scope.stocks = stocksModel;
In your partial:
{{stocks.some_data_which_was_acquired_RESTfully}}
To be blunt
No. If possible, I would improve the code so that is it more maintainable and update to date with Angular. Let me explain why it is a good idea. . .
Why are you making your life so hard?
Angular is a wonderful framework that lets you tackle fairly complex problems with simple solutions. The dark side of Angular is it is easy to over engineer a solution if you go off the beaten path. Angular exposes a lot of the internals so it is tempting (and fun!) to muck around with it instead of going for the simple route.
Growing pains
I believe what you are dealing with is due to the growing pains Angular has had as it matured as project. A lot of side projects sprung up to fix the leaky holes that have since been plugged.
Rails and Angular, fast friends
So I am basing this off of how I have grown to use Rails with Angular. The examples are pulled from a pet project that is not going anywhere. Unfortunately, this is all in coffeescript, so hopefully that wont cause you problems. It is structured how I found works best with Rails, while keeping the spirit and fun of Angular.
* app/assets/javascripts
* app
* project_name_app.js.coffee.erb
* controllers
* controllers.js
* directives
* directives.js
* filters
* filters.js
* resources
* resources.js
* services
* services.js
Rails' asset pipeline wraps everything up using the application.js with the include:
//= require app/project_name_app
In the app/project_name_app.js.coffee.erb, it loads all of the directories with the includes
#= require_self
#= require app/controllers/controllers
#= require app/directives/directives
#= require app/filters/filters
#= require app/resources/resources
#= require app/services/services
Last, each of the sub directories js (controllers.js, directives.js, filters.js, resources.js, services.js) simply loads everything in that directory:
//= require_tree .
With this setup, the project_name_app.js.coffee.erb is loaded first, setting up Angular, the dependencies, and the app configuration. Then the controller, directives, filters, etc are loaded. One of the perks is new javascript added to a sub directory is automatically included thanks to the require_tree.
Keeping the $resource simple
The best $resources are RESTFUL. Meaning that it is the sample URL and the functionality changes based on the http method of the request. The downside is, if you have different URLs, you will probably need multiple resources. An example from the users_resource.js.coffee:
angular.module("DeployerApp.resources").factory "Users", ($resource) ->
$resource "/users.json", {},
index:
method: "GET"
isArray: true
type: "User"
angular.module("DeployerApp.resources").factory "User", ($resource) ->
$resource "/users/:user_id.json", {},
show:
method: "GET"
update:
method: "PUT"
angular.module("DeployerApp.resources").factory "CurrentUser", ($resource) ->
$resource "/users/current.json", {},
show:
method: "GET"
To get all users, you call Users.index(). To get a single user, you call User.show( user_id: 1 ). Last, a convenience $resource I that often use, to get the current authenticated user, CurrentUser.show().
Pretty straight forward and easy to read, avoiding have to have thick models. Each of the User $resources can be tested separately.
Angular is ready to do the work
You really only need to start mucking with $promise if you have some complicated juggling act when dealing with multiple responses. I have found it is simpler to just pass in the success and error callbacks to the $resource, for example:
CurrentUser.show success = (user) ->
$scope.currentUser = user
, error = (data,status) ->
# redirect to login
The variable names help make the code more readable, without them the coffeescript function definitions kind of blend together.
Simpler is always better
You do not need to worry about the $promise.then of the $resource, allowing you to tidying things up.

How to structure a single page app with knockout.js?

I am mostly wondering how to organize things like modal windows, and dynamic pages like profiles. Should the viewModel only contain one profile view or contain all profiles loaded? This here just doesnt seem very "clean".
viewModel = {
profile: ko.observableArray([
new ProfileViewModel()
//... any others loaded
])
, createPostModal: {
input: ko.observable()
, submit: //do something to submit...
}
}
<div data-bind="foreach: profile"><!-- profile html --></div>
<div data-bind="with: createPostModal"></div>
This way doesn't seem very consistent. Is there anybody who has built a single page app with knockout that can offer some advice? Code samples would be appreciated.
We are just starting down this path at work, and so are not quite sure what we're doing. But here's the idea we have.
The page should be composed of any number of "components," possibly nested. Each component has a view model and one public method, renderTo(el), which essentially does
ko.applyBindings(viewModelForThisComponent, el)
It also could have the ability to render subcomponents.
Constructing or updating a component consists of giving it a model (e.g. JSON data from the server), from which it will derive the appropriate view model.
The app is then created by nesting a bunch of components, starting with a top-level application component.
Here is an example for a "hypothetical" book-managing application. The components are LibraryUI (displays a list of all book titles) and DetailsUI (a section of the app that displays details on a book).
function libraryBookViewModel(book) {
return {
title: ko.observable(book.title),
showDetails: function () {
var detailsUI = new BookDetailsUI(book);
detailsUI.renderTo(document.getElementById("book-details"));
}
};
}
function detailsBookViewModel(book) {
return {
title: ko.observable(book.title),
author: ko.observable(book.author),
publisher: ko.observable(book.publisher)
};
}
function LibraryUI(books) {
var bookViewModels = books.map(libraryBookViewModel);
var viewModel = {
books: ko.observableArray(bookViewModels);
};
this.renderTo = function (el) {
ko.applyBindings(viewModel, el);
};
}
function BookDetailsUI(book) {
var viewModel = detailsBookViewModel(book);
this.renderTo = function (el) {
ko.applyBindings(viewModel, el);
};
}
Note how we could make the book details appear in a jQuery UI dialog, instead of in a singleton #book-details element, by changing the showDetails function to do
var dialogEl = document.createElement("div");
detailsUI.renderTo(dialogEl);
$(dialogEl).dialog();
There are 3 frameworks out there that help with creating SPAs using Knockoutjs.
Durandal
Pagerjs
KnockBack
I have used Durandal and I really like it. Easy to use and has a lot of nice configurations so you can plug-in your own implementations. Also, Durandal is created by the same creator of Caliburn which was an very popular framework for building Silverlight/WPF applications.
Now in 2014, you probably want to use Knockout's component feature and Yeoman to scaffold your initial ko project. See this video: Steve Sanderson - Architecting large Single Page Applications with Knockout.js
[update april 5, 2013] at time of writing this answer was valid. Currently I would also suggest the Durandal JS approach as the way to go. Or check John Papa's Hot Towel or Hot Towelette SPA templates if you are using ASP.NET MVC. This also uses Durandal.
Original answer below:
I would like to point out Phillipe Monnets 4 part series about Knockout.js to you. He is the first Blogger I encounterd who splits up his example project in multiple files. I really like most of his ideas. The only thing I missed, was how to handle ajax / rest retrieved collections by using some kind of Repository / Gateway pattern. It's a good read.
Link to part 1: http://blog.monnet-usa.com/?p=354
Good luck!
I just open-sourced the mini SPA framework I put together with Knockout being the major component.
knockout-spa
A mini (but full-fledged) SPA framework built on top of Knockout, Require, Director, Sugar.
https://github.com/onlyurei/knockout-spa
Live Demo:
http://knockout-spa.mybluemix.net
Features
Routing (based on Flatiron's Director): HTML5 history (pushState) or hash.
Highly composable and reusable: pick modules/components for a page in the page-specific JS and they will be auto-wired for the page's HTML template
SEO ready (prerender.io)
Fast and lightweight (85 KB of JS minified and gizpped)
Two-tier bundle build for JS for production: common module that will be used by most pages, and page-specific modules that will be lazy-loaded
Organized folder structure to help you stay sane for organizing and reusing JS, CSS, HTML
Using Knockout 3.3.0+ so ready for Knockout's flavor of web component and custom tags (http://knockoutjs.com/documentation/component-overview.html)
All documentation are in the major dependencies' own homepages, so that you don't need to completely learn a new framework
Knockout http://knockoutjs.com
Require http://requirejs.org
Director https://github.com/flatiron/director
jQuery http://jquery.com
Sugar http://sugarjs.com

Categories