11.25.2016

Коротко о логике авторизации и роутинге используя Angular 2

Для решения данного вопроса вполне достаточно документации на официальном сайте Angular 2

Однако!

В разделе описано много больше информации и если английский текст вы воспринимаете медленно, то данная небольшая статья поможет быстро вникнуть в суть происходящего.

А,  я лишь хочу обрисовать общую логику процесса и некоторые моменты авторизации так, чтобы вы (и я) могли максимально быстро настроить роутинг для своего проекта.

Простая навигация по ссылкам не самый интересный вариант с точки зрения реального применения. В реальности мы имеем приватную и публичную часть приложения. А иногда, только приватную, которая доступна только после авторизации. Весь роутинг после авторизации будет представлять собой самый простой вид роутинга т.е. написал путь и привязал к нему компонент который будет отображаться.

Мне удобно представлять "картину целиком" прежде чем приступать к работе.

Итак! У нас будет главный роутинг приложения, и модуль роутинга для приватной части. В роутинге приватной части используются дочерние пути. Дочерние пути будут защищаться при помощи сервисов авторизации. Авторизироваться можно будет при помощи компонета входа (login). Сервисы авторизации авторизируют пользователя и запоминают состояние.

Итого:
  • Главный роутинг
  • Дочерний роутинг приватной части
  • Сервисы авторизации
  • Компонент входа (форма входа)

Теперь логика процесса авторизации. Пользователь заходит на главную страницу сайта, главный роутнг отправляет его на приватную часть сайта. Пути приватной части сайта обрабатывает роутинг приватной части. Для проверки нужно ли отображать дочерние пути он использует сервис авторизации. Если сервис подтвердит, что у пользователя есть права то роутинг обработает запрос к дочерним путям. Если нет, то будет вызван роут для несуществующего пути (404 страница). Если роутинг приватной части не обрабатывает 404 ошибку то, это попытается сделать главный роутинг. Если и он не справится то выпадет ошибка:
Unhandled promise rejection
Error: Permission denied to access property "rejection"
Поэтому сервис авторизации в случае если пользователь не авторизован должен сам направить его на нужный маршрут по которому запрос обработает модуль входа. А так же не забывайте ставить обработку несуществующего пути:
{
    path: "**",
    component: NotFoundComponent
}

Теперь по сути и с кусками кода.
Пользователь заходи на главную страницу и это обрабатывает главный роутинг:
const routes: Routes = [
    {
        path: '',
        redirectTo: '/panel',
        pathMatch: 'full'    },
    {
        path: 'login',
        component: LoginComponent
    },
    {
        path: "**",
        component: NotFoundComponent
    }
];
Так же не забываейте, что для роутинга приватной части нужен свой тег
<router-outlet></router-outlet>который будет находиться в главном компоненте приватной части, так же как и для всего приложения он находится в app.component.

Пользователь перенаправляется на приватную часть сайта, это обрабатывает роутинг приватной части:
const routes: Routes = [
    {
        path: 'panel',
        canActivate: [AuthGuard],
        component: AdminComponent,
        children: [
            {
                path: '',
                canActivateChild: [AuthGuard],
                children: [
                    {
                        path: '',
                        component: DashboardComponent,
                    },
                    {
                        path: 'dashboard',
                        component: DashboardComponent
                    },
                    {
                        path: 'logs',
                        component: LogsComponent
                    },
                    {
                        path: 'configs',
                        component: ConfigsComponent
                    }
                ]
            }
        ]
    }
];
Для проверки авторизации роутинг использует AuthGuard подключенный в роуты такой строчкой:
canActivate: [AuthGuard],
Сам сервис авторизации должен реальзовывать два метода canActivate и canActivateChild. Выглядит следующим образом:
import { Injectable }       from '@angular/core';
import {
    CanActivate, Router,
    ActivatedRouteSnapshot,
    RouterStateSnapshot,
    CanActivateChild
}                           from '@angular/router';
import { AuthService }      from './auth.service';

@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {

    canActivate(): boolean {
        return this.checkLogin();
    }

    canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        return this.canActivate();
    }
    checkLogin(url: string): boolean {
        // используем сервис this.authService 
        // чтобы проверить авторизован ли пользователь 
        // выполнить редирект на компонент входа можно тут
    }
}
Для выполнения редиректа нужно подключать модуль Router
import { Router } from '@angular/router';
Добавлять его в класс который будет выполнять редирект
constructor(
    private authService: AuthService,
    private router: Router
) {}
И вызывать редирект следующим образом:
this.router.navigate(['/login']);
Компонент входа (/login) использует сервис авторизации authService, который может иметь любую логику на ваше усмотрение, например в таком виде:
import { Injectable } from '@angular/core';

@Injectable()
export class AuthService {
    isLoggedIn: boolean = false;

    // store the URL so we can redirect after logging in    redirectUrl: string;

    login(): Observable<boolean> {
        return this.isLoggedIn = true;
    }

    logout(): void {
        this.isLoggedIn = false;
    }
}

Остальное и более подробно читайте в официальной документации:
https://angular.io/docs/ts/latest/guide/router.html
Angular 2 Router:
https://vsavkin.com/angular-2-router-d9e30599f9ea

11.18.2016

Angular 2 Архитектура

Как только вышла стабильная версия Angular 2 я решил, что пришло время уделить время переводу статьи по архитектуре данного фреймворка. Но, что-то я отвлекся от перевода на некоторе время и вот уже версия 2.2 вышла в свет. Конечно, "некоторое" время было потрачено в том числе и на эксперименты, прочтение и осмысление базового гайда и тура героев, но оно того стоило. Так что получился перевод с моими дополнениями или пояснениями.

В конце статьи смотрите видео по всему фрейворку. Очень познавательное!

Все кто заглядывал на официальный сайт фреймворка в разделе архитектура видели ее схематическое изображение, а как говорится повторение - мать учения!



Можно выделить 8 основных архитектурных блоков в приложениях на Angular 2:

    Модули (Modules)


    Приложения на Angular являются модульными, а сам фрейм-ворк предоставляет свою систему модульности - NgModules. В терминах JavaScript NgModule, именно без окончания "s" это обычная функция, функция декоратор. Так как Angular 2 использует TypeScript то правильно будет назвать NgModule - функцией декоратором.

    Каждое приложение написанное на Angular имеет как минимум один модуль. Внутри модуля находятся компоненты приложения. 

    Например, список товаров или героев может быть одним компонентом, а детальная информация о герое, которая открывается по нажатию на конкретного героя будет вторым компонентом.
      Ситуация с одним модулем характерна для простых приложений тогда как в больших приложениях имеется много модулей объединяющих в себе определенный набор возможностей.

      Модули в Angular, это class обернутый в декоратор @NgModule.

      Декораторы модифицируют поведение пользовательских классов. Функция-декоратор, используя переданный ей класс и метаданные создает его экземпляр, а так же устанавливает дополнительные связи требуемые самому фрейм-ворку. В итоге, написав свой класс обернув его в декоратор и импортировав его для дальнейшего использования мы импортируем не тот класс который мы написали, а функцию которую вернул декоратор Angular.

      NgModule - это функция декоратор, которая принимает один объект метаданных. Наиболее важными свойствами являются:
      • declarations - Принимает массив компонентов приложения. По мимо компонентов можно передавать свои директивы и трубы (под трубами можно понимать потоки событий реализованных с помощью EventEmitter) .
      • exports - С помощью этого свойства мы можем сделать текущий модуль доступным (видимым) для использования снаружи другими модулями. Т.е. через exports сделали видимым, а через imports подключили текущий модуль к другому.
      • imports - Массив модулей которые используются в текущем модуле. Например, при работе с формами мы подключаем соответствующий модуль самого фрейм-ворка и подключаем его к своему модулю через указание его в массиве imports.
      • providers - Массив сервисов или услуг, которые предоставляют компонентам расширенную функциональность. Типичным примером сервисов может быть функция логирования или функции выполняющие запросы данных по сети (httpRequest).
      • bootstrap - Главный компонент приложения (корневой). Можно сказать, что это точка входа в приложение. Только для корневого модуля устанавливается свойство само загрузки.
      import { NgModule }      from '@angular/core';
      import { BrowserModule } from '@angular/platform-browser';
      @NgModule({
        imports:      [ BrowserModule ],
        providers:    [ Logger ],
        declarations: [ AppComponent ],
        exports:      [ AppComponent ],
        bootstrap:    [ AppComponent ]
      })
      export class AppModule { }
       

      Angular модули vs JavaScript модули

      Как уже было сказано ранее. Модули в Angular, - это декорированные классы. В свою очередь JavaScript имеет свою модульную структуру, которая не как не связанна с Angular.

      В JavaScript каждый файл представляет собой модуль. В модуле может содержаться разное количество объектов, классов или функций, каждый из которых может быть помечен специальным словом export, а другие модули используют операторы import для доступа к ранее экспортированным объектам.


      import { NgModule }     from '@angular/core';
      import { AppComponent } from './app.component';
      export class AppModule { }

      Библиотеки Angular (Angular Libraries)

      Angular представляет собой набор модулей JavaScript. Официальная документация предлагает читателю думать о них как о библиотеке модулей. Если перейти на репозиторий Angular то можно найти все модули которые входят в состав фрейм-ворка.
      https://github.com/angular/angular/tree/master/modules/%40angular


      Модулей довольно много для того, чтоб запомнить их все сразу. Первые модули с которыми сталкивается разработчик, это модуль ядра core, модуль для платформы platform-browse
      r и модуль для работы с формами forms.

      Каждая библиотека начинается с префикса @angular

      Вы устанавливаете их с помощью npm менеджера пакетов и импортируете нужные вам модули в свое приложение с помощью оператора import.


      Например:

      import { Component } from '@angular/core';
      import { BrowserModule } from '@angular/platform-browser';


      После того как вы импортировали нужный вам функционал остается привязать его к классам которые вы будете писать в своем приложении. Иначе как ваши классы смогут пользоваться магией Angular? Конечно при помощи декораторов, которые расширят ваши классы и добавят им функции из импортированных вами модулей. Для этого достаточно написать следующий код:


      imports:      [ BrowserModule ],

      Надеюсь вы еще помните где нужно писать данную строчку? Конечно в метаданных декоратора класса. 

      import { NgModule }      from '@angular/core';
      import { BrowserModule } from '@angular/platform-browser';
      @NgModule({
        imports:      [ BrowserModule ],
        providers:    [ Logger ],
        declarations: [ AppComponent ],
        exports:      [ AppComponent ],
        bootstrap:    [ AppComponent ]
      })
      export class AppModule { }

      Компоненты (Components)

      Компонент представляет собой какую-либо визуальную часть интерфейса.

      Например:
      • Корень приложения с навигационными ссылками - appComponent
      • Список героев - HeroListComponent
      • Редактор героев - HeroEditorComponent
      В классе компонента вы определяете его логику, а взаимодействие с интерфейсом (view) происходит по средствам API свойств и методов.

      Например, HtroListComponent имеет свойство heroes, которое содержит массив героев полученный от службы (Служба или сервис - это функция возвращающая массив героев, обычно внутри функции происходит ajax запрос на получение списка героев). HeroListComponent так же имеет метод selectHero(), который устанавливает свойство selectedHero, в момент нажатия пользователем на кнопку, для того, чтобы выбрать героя из списка.

      export class HeroListComponent implements OnInit {
        heroes: Hero[];
        selectedHero: Hero;
      
        constructor(private service: HeroService) { }
      
        ngOnInit() {
          this.heroes = this.service.getHeroes();
        }
      
        selectHero(hero: Hero) { this.selectedHero = hero; }
      }

      У каждой директивы, компонента есть жизненный цикл т.е. время от начала взаимодействия с компонентом до окончания этого взаимодействия. Предположим, пользователь открывает список героев с этого начинается жизненный цикл компонента HeroListComponent. Дальше пользователь хочет отредактировать определенного героя и на этом закончить. Когда пользователь выберет героя и отправиться редактировать его, то это можно считать окончанием жизненного цикла для компонента HeroListComponent. 

      Но как пользователь сможет выбрать требуемого героя если не произошла загрузка списка героем? Одним из решений может быть создание кнопки Load, которую должен будет нажать сам пользователь. Но есть и другой способ!

      Angular предоставляет lifecycle hook, это события которые происходят в течении жизненного цикла компонента. Для того, чтобы ими воспользоваться нужно лишь добавить в свой класс метод со специальным именем, дальше Angular сам вызовет данный метод, когда придет время. 

      В примере выше таким хуком жизненного цикла (lifecycle hook) был метод ngOnInit.


      Шаблоны (Templates)

      Описывая компонент интерфейса вы добавляете к нему шаблон для отображения в интерфейсе. Шаблон представляет собой html который определяет как компонент будет выглядеть в интерфейсе.

      Шаблон выглядит как обычный HTML, за исключением нескольких отличий. Вот шаблон для нашего списка героя компонента:
       
       
      <h2>Hero List</h2>
       
      <p><i>Pick a hero from the list</i></p>
      <ul>
      <li *ngFor="let hero of heroes" (click)="selectHero(hero)">
          {{hero.name}}
        </li>
      </ul>
       
      <hero-detail *ngIf="selectedHero" [hero]="selectedHero"></hero-detail>
      
      
      Хотя этот шаблон использует типичные HTML-элементы, такие как <h2> и <р>, он также имеет некоторые отличия. Код, как *ngFor, {{hero.name}}, (click), [hero], а <hero-detail> использует синтаксис шаблонов Angular.

      В последней строке шаблона тег <hero-detail> является пользовательским элементом, который представляет собой новый компонент, HeroDetailComponent.

      HeroDetailsComponent  является еще одним компонентом по мимо HeroListComponent и представляет факты о конкретном герое выбранном из списка героев. Так же HeroDetailsComponent является потомком HeroListComponent.

      Обратите внимание на то, как органично <hero-detail> компонент вписывается в обычные html элементы. Пользовательские шаблоны легко смешиваются с обычным html.


      Мета данные (Metadata)

      Мета данные рассказывают Angular как обрабатывать class.

      Оглядываясь назад на код HeroListComponent, вы можете увидеть, что это просто класс. Внутри класса нет ничего чтобы относилось к самому Angular.

      На самом деле, HeroListComponent это просто класс, и он не является компонентом, пока вы не скажете Angular об этом.

      Сказать, что HeroListComponent является компонентом Angular, можно прикрепив метаданные к классу.

      В TypeScript, прикреплении метаданные можно с помощью декоратора. Вот некоторые метаданные для HeroListComponent:


      @Component({
        moduleId: module.id,
        selector:    'hero-list',
        templateUrl: 'hero-list.component.html',
        providers:  [ HeroService ]
      })
      export class HeroListComponent implements OnInit {
      /* . . . */
      }

      Вот декоратор @Component, который идентифицирует класс непосредственно под ним как класс компонента.

      @Component Декоратор принимает необходимые объекты конфигурации с информацией, Angular необходимо создать и представить компонент и его вид.

      Вот некоторые из возможных вариантов конфигурации @Component:

      • moduleId - устанавливает источник базового адреса (module.id) для относительно модуля URL-адресов, таких как templateUrl.
      • selector - CSS селектор который определяет в какой элемент будет вставлен содержимое компонента т.е. шаблон компонента.
      • templateUrl - относительный адрес для получения шаблона компонента
      • providers - массив провайдеров зависимости, инъекций услуг, которые нужны компоненту. Это один из способов сказать, что Angular конструктор компонента требует HeroService, для того чтобы получить список и отобразить список героев.
      Метаданные в @Component определяют, где получить основные строительные блоки, заданные для компонента.

      Шаблон, метаданных и компонент вместе описывают вид.

      Так же существуют другие декораторы.
      @Injectable, @Input и @output - это наиболее используемые виды декораторов.

      Архитектурный идея Angular2 состоит в том, что вы должны добавить метаданные в ваш код используя декораторы, таким образом Angular2 поймет, что нужно делать. 



      Связывание данных (Data binding)

      Без фреймворка вам бы пришлось вручную обновлять данные в HTML и так же вручную обрабатывать действия пользователей. Написание такой логики вручную утомляет, итоговый код трудно читать и он подвержен ошибкам, любой опытный программист на jQuery может это подтвердить ;)


      Связывание данных в Angular, это механизм координации данных между JavaScript (Компонентом) кодом и Html (Шаблоном) кодом. Добавляя в html разметку связывания мы определяем как соединить компонент и шаблон.

      Как показано на схеме, существует четыре формы данных синтаксиса связывания. Каждая форма имеет направление - к DOM, из DOM, или в обоих направлениях.



      Пример, HeroListComponent шаблон имеет три формы:

      <li>{{hero.name}}</li>
      <hero-detail [hero]="selectedHero"></hero-detail>
      <li (click)="selectHero(hero)"></li>

      1. {{hero.name}} значит, что значение свойства hero.name будет взято из компонента HeroListComponent и отображено внутри тегов <li>. Это одностороннее связывание при котором изменение значения свойства hero.name приведет к изменению отображаемого значения.
      2. [hero] Со вторым случаем все немного сложнее, так было сказано: каждая форма имеет направление - к DOM, из DOM, или в обоих направлениях. А о направлении от компонента к компоненту нечего сказано не было. Поэтому, нужно сказать, что коммуникация происходит между компонентами. Почему именно так? Потому что свойство hero компонента HeroDetailsComponent связывается со значением selectedHero компонента HeroListComponent. Таким образом происходит коммуникация между дочерним и родительским компонентом. Как только изменится значение свойства selectedHero, это значение попадет в свойство hero компонента HeroDetailsComponent и последний сможет отобразить детальную информацию о герое. Отмечу, что такой код сам по себе работать не будет так как свойство hero внутри компонента HeroDetailsComponent должно быть помечено специальным декоратором @Input.
      3. (click) обработчик события onClick.
      Четвертым видом связывания является двухстороннее связывание, совмещающее в себе привязку по событию и привязку к свойству. Для двухстороннего связывания используется директива ngModel. Вот пример из шаблона HeroDetailComponent.

      <input [(ngModel)]="hero.name">

      При изменении значения пользователем в поле ввода изменится значение свойства hero.name, так же и при изменении значения свойства результат сразу отобразится в html.

      Один раз за цикл событий JavaScript Angular обрабатывает все привязки данных, от корня дерева компонентов приложения до всех дочерних компонентов.



      Привязка данных играет важную роль в общении между шаблоном и ее компонентом.


       





      Привязка данных также имеет важное значение для связи между родительскими и дочерними компонентами.




       

      Директивы (Directives)

      Шаблоны в Angular являются динамическими. Angular обрабатывает их и превращает в DOM в соответсвии с инструкциями указанными в директивах.



      Директива - это класс и ее метаданные. В TypeScript, используется декоратор @Directive для класса директивы.







      Компонент является директивой с шаблоном, @Component декоратор, это фактически @Directive декоратор расширеный функциями ориентированными на работу с шаблонами.

      На самом деле компонент технически является директивой, но компоненты настолько важны в приложениях построенных на Angular, что в данном обзоре архитектуры мы отделяем компоненты от директив.

      Существует два вида директив:
      • Структурные
      • И директивы атрибутов
      Они, как правило, появляются в пределах элемента тега так же как атрибуты, иногда по имени, но чаще в качестве цели присвоения или привязки.

      Структурные директивы изменяют макет путем добавления, удаления и замены элементов в DOM.

      Пример шаблона использующего две встроенные структурные директивы:


      <li *ngFor="let hero of heroes"></li>
      <hero-detail *ngIf="selectedHero"></hero-detail>
       
      • *ngFor указывает Angular, что для каждого элемента массива heroes нужно создать отдельный тег <li>. 
      • *ngIf указывает Angular, что добовлять элемент HeroDetail нужно только в том случае если свойство selectedHero возвращает правду.

      Директивы атрибутов изменяют внешний вид или поведение существующего элемента. В шаблонах они выглядят как обычные HTML атрибуты, отсюда и название.

      Директива ngModel, которая реализует двустороннюю привязку данных, является примером директивы атрибута. Директива ngModel изменяет поведение существующего элемента, устанавливает для свойства input.value значение из hero.name, а так реагирует на изменения пользователем значения input.value используя события.

      <input [(ngModel)]="hero.name">

      Angular имеет несколько директив, которые либо изменяют структуру макета (например, ngSwitch) или модифицируют аспекты элементов и компонентов DOM (например, ngStyle и ngClass).

      Конечно, вы можете также написать свои собственные директивы. Такие компоненты, как HeroListComponent один вид пользовательской директивы.


      Сервисы (Services) 

      Сервис, это очень широкое понятие, но по сути сервис является функцией, которая удовлетворяет некоторые потребности. 

      Обычно сервис представляет собой класс с узко и четко обозначенной целю, например получать данные с сервера или вычислять координаты фигуры svg. Сервис должен делать, что-то конкретное и делать это хорошо!

      Примеры сервисов:

      •      сервис логирования
      •      сервис получения данных с удаленного сервера
      •      сервис сообщение о багах
      •      калькулятор
      •      конфигурация приложения
      Angular не содержит внутри себя сервисов как  таковых т.е. в них нет нечего специфического с точки зрения фреймворка. Для сервисов не существует специального декоратора и их не нужно регистрировать как например компоненты. Однако, чтобы использовать один и тот же сервис в разных компонентах используется декоратор @Injectable(). Об этом будет сказано в следующем разделе статьи.

      Тем не менее, сервисы имеют большое значение для любого Angular приложения. Компоненты являются основными потребителями сервисов.

      Вот пример класса
      сервиса логирования, который регистрируется в консоли браузера .
      export class Logger {
        log(msg: any)   { console.log(msg); }
        error(msg: any) { console.error(msg); }
        warn(msg: any)  { console.warn(msg); }
      }
      Еще пример сервиса который завист от двух других сервисов Logger и BackendService.
      export class HeroService {
        private heroes: Hero[] = [];

        constructor(
          private backend: BackendService,
          private logger: Logger) { }

        getHeroes() {
          this.backend.getAll(Hero).then( (heroes: Hero[]) => {
            this.logger.log(`Fetched ${heroes.length} heroes.`);
            this.heroes.push(...heroes); // fill cache
          });
          return this.heroes;
        }
      }
      Сервисы просто повсюду!

      Цель сервисов вынести часть кода из компонентов. Компоненты не должны сами получать данные с сервера, проверять пользовательский ввод или выводить сообщения в консоль. Такие задачи они делегируют сервисам.

      Компонент является связующим звеном между шаблоном (видом) и логикой приложения. Хороший компонент представляет собой свойства и методы для связывания данных. Все остальное он делегирует сервисам.


      Angular не будет жаловаться если вы напишите компонент в  3000 строк без использования сервисов. Но, Angular действительно помогает нам правильно организовать код отделяя логику приложения в отдельные сервисы, с целью получить к ним доступ из любого компонента используя внедрения зависимостей (dependency injection). 


      Внедрение зависимостей (Dependency injection) 

      Внедрение зависимостей, это способ создания класса с уже готовыми зависимостями, которые ему нужны. Большинство зависимостей, - это сервисы. Angular использует внедрение зависимостей, чтобы отделить создание класса сервиса от кода компонента, таким образом новые компоненты сразу получают те сервисы которые им необходимы. Забегая вперед, скажу, что такой подход призван упростить тестирование.

      Angular может определить какие сервисы нужны компоненты глядя на типы его параметров в конструкторе. На самом деле, это делает транспилятор TypeScript. В этом легко убедиться если открыть данные код в разделе playground на сайте TypeScript

      class HeroService { }

      class HeroesComponent {
          constructor(
              private heroService: HeroService
          ) {}
      }


      Перед тем как создать компонет Angular спрашивает инжектор какие сервисы требуются компоненту. 

      Инжектор имеет контейнер с экземплярами класса сервисов созданых ранее. Если запрошенные экзепляр сервиса не найден в контейнере, то инжектор сделает данный экземпляр сервиса и отправит его в контейнер перед тем как вернуть экзепляр сервиса запросившему его компоненту. Когда все запрошенные сервисы были помещены в контейнер и отправлены в нужные компоненты, Angular помещает экземпляры сервисов в качестве аргументов компонента и вызывает конструктор. Это и есть внедрение зависимостей.

      Процесс внедрения зависимости HeroService выглядит так:


      Если инжектор не имеет экземпляра HeroService в контейнер, как он должен сделать его экземпляр?
      Нужно зарегистрировать сервис у поставщика (provider). Поставщик может создать или вернуть экземпляр услуги, часто он позвращает сам класс сервиса.

      Можно зарегистрировать поставщиков в модулях или в компонентах.

      В общем случае, добавьте поставщиков в корневой модуль таким образом, экземпляр службы станет доступен везде.

      providers: [
        BackendService,
        HeroService,
        Logger
      ],
       
      Если же вам нужен новый экземпляр сервиса в каком-то компоненте то можно зарегистрировать его именно в декораторе @Component нужного комонента.
       @Component({
        moduleId: module.id,
        selector:    'hero-list',
        templateUrl: 'hero-list.component.html',
        providers:  [ HeroService ]
      })
      Помните, что регистрация на уровне компонентов означает, что вы получите новый экземпляр сервиса с каждым новым экземпляром этого компонента.
      Внедрение зависимостей подключается в Angular и используются повсеместно.

      И в заключении всего хочу поделиться видео лекцией по Angular 2:

       

        9.08.2016

        Как сделать кубическую кнопку css3

        Как говорится, начнем с начала! А рассказывать буду о верстке классных кубических кнопок. Специально для данного урока подключил подсветку кода на сайт, так что you are welcome!


        Давайте сразу начнем с результата работы. https://jsfiddle.net/t59o2rso/

         Демо


        Submit
        Submit

        Начинаем с идеи

        А идея заключается в создании ощущения трехмерного пространства за счет вращения кнопки вокруг оси абсцисс (X). Если вообразить кнопку в виде трехмерного бруса и представить как он поворачивается на 90 градусов, то мы увидим две его грани. Следовательно потребуется два html элемента для отображения этих граней. Чтобы достичь эффекта трехмерности и вращения понадобятся css3 свойства.

        Две грани куба представляют собой кнопку так что обернем их в div с классом btn-cube_button
            Submit     Submit

        А для достижения эффекта трехмерности и анимации css3  предоставляет специальные свойства.
        transform-style: preserve-3d;
        transition: all 0.3s ease 0s;
        transform-origin: 50% 0 0; 
        

        Первое свойство, - transform-style создает внутри тега которому присвоено трехмерное пространство. Второе свойство, - transition задает правила анимации. И последнее свойство, - transform-origin смещает ось абсцисс (X) к верхней границе нашей кнопки (это ось вокруг которой будет вращаться кнопка).

        Теперь когда вращающаяся часть готова нужно подумать о запуске нашей анимации. Запуск будет происходить по наведения (hover). Здесь существует первый нюанс. Нельзя повесить правила наведения прямо на <div class="btn-cube_button"> потому что в процессе трансформации дочерние элементы изменяются в размере. В итоге будет получено некорректное поведение в некоторых браузерах. Решит эту проблема обертка вокруг кнопки.

        Опишем компонент по БЭМ

        Определившись с идеей легко описать кнопку в html. Назовем компонент btn-cube, внутри него находится первый компонент - обертка btn-cube__wraper, внутри обертки сама конпка btn-cube__button и еще глубже грани кнопки btn-cube__btn-def и btn-cube__btn-act.

        btn-cube
            btn-cube__wraper 
                btn-cube__button 
                    btn-cube__btn-def 
                    btn-cube__btn-act 

        Submit Submit

        В итоговом HTML помимо описанных выше элементов есть специальные бамперы btn-cube__bumper. Они нужны для устранения "дергатни" кнопки при попадании мыши на верхнюю или нижнюю границу кнопки и по большому счету не обязательны к использованию.

        Добавим CSS

        Перед тем как показать итоговый css осталось отметить одну деталь. Как уже было сказано ранее, специальное свойство css3 transform-style: preserve-3d создает внутри контейнера 3d пространство. Для правильного отображения нашего куба нужно поместить одну грань под другой и нижнюю грань повернуть на 90 градусов. Таким образом она станет невидимой до тех пор пока куб не начнет поворачиваться.
        .btn-cube .btn-cube__btn-act {
            background: #000 none repeat scroll 0 0;
            color: #fff;
            left: 0;
            position: absolute;
            top: 100%;
            transform: rotateX(-90deg);
            transform-origin: 50% 0 0;
        }
        

        Итоговый HTML и CSS

        HTML:
        Submit Submit
        CSS:
        .btn-cube {
            display: inline-block;
            position: relative;
        }
        .btn-cube__bumper {
            position: absolute;
            z-index: 1000;
        }
        .btn-cube__bumper-bottom {
            background: transparent;
            height: 6px;
            left: 0;
            right: 0;
        }
        .btn-cube__bumper-top {
            background: transparent;
            height: 6px;
            left: 0;
            right: 0;
            top: -6px;
        }
        .btn-cube__wraper {
            display: inline-block;
            cursor: pointer;
        }
        .btn-cube__button {
            display: inline-block;
            position: relative;
            transform: rotateX(0deg) translateY(0%);
            transform-style: preserve-3d;
            transition: all 0.3s ease 0s;
            transform-origin: 50% 0 0;
        }
        .btn-cube > .btn-cube__wraper > .btn-cube__button > .btn-cube__btn {
            padding: 10px 15px;
            display: inline-block;
            cursor: pointer;
        }
        .btn-cube .btn-cube__btn-def {
            transform: rotateX(0deg);
            background: #fff;
            color: #000;
        }
        .btn-cube .btn-cube__btn-act {
            background: #000 none repeat scroll 0 0;
            color: #fff;
            left: 0;
            position: absolute;
            top: 100%;
            transform: rotateX(-90deg);
            transform-origin: 50% 0 0;
        }
        .btn-cube__wraper:hover > .btn-cube__button, 
        .btn-cube.btn-cube__active > .btn-cube_wraper {
            transform: rotateX(90deg) translateY(-50%);
        }
        

        В заключении

        Ссылка на полный код https://jsfiddle.net/t59o2rso/
        и ссылка на сайт для вдохновения, как можно применить данный эффект http://livedemo00.template-help.com/joomla_51399/

        8.30.2016

        Для чего нужен TypeScript

        Совсем недавно познакомился с TypeScript на курсах. Язык оставил приятное впечатления и теперь я с удовольствием углубляю свои знания языка и пользуюсь им в работе.

        В данной заметке решил под итожить в целом для чего нужен TypeScript.

        TypeScript компилируется в JavaScript и в общем синтаксически очень похож на JavaScript в его текущем стандарте ES6. Если исключить из TypeScript все новшества ES6, такие как функции-стрелки, promise и т.д. то у нас останется лишь то, что TypeScript позволяет нам описывать типы переменных.

        Например, так:
        let num: number;
        num = 2;

        На самом деле, конечно же, описываются не переменные, а типы данных. TypeScript дает возможность описывать больше типов данных чем существует в JavaScript.

        В TypeScript появляются такие типы данных как Кортежи (Tuple), Перечисления (Enum), Обобщенные типы <T> и некоторые "плюшки" (назовем их так) которые позволяют работать с описанием типов (если коротко то есть конфигурационные файлы, есть файлы описания типов, есть синтаксис подключения файлов с описанием типов и т.д. ). 

        Кстати, Class тоже является типом данных, он так же как и все остальные типы данных призван выразить, описать, передать идеи, концепции, мысли программиста. Другими словами типы данных, это инструменты выразительного искусства под названием программирование. И в этом отношении TypeScript конечно превосходит JavaScript. Так как дает нам больше средств выражения, способов передачи смысла программы, благодаря чему TypeScript и принято использовать в больших приложениях.

        Получается одинаково грамотно написанный код на TypeScript будет легче понять чем такой же на JavaScript. Можно сказать, что код на TypeScript имеет большее разрешение и детальнее описывает программу, не говоря о предотвращении ряда ошибок на этапе компиляции.

        К слову говоря TypeScript обладает хорошей документацией, хоть и на английском, и средой выполнения кода в браузере. Все тут http://www.typescriptlang.org/docs/handbook/basic-types.html

        8.25.2016

        Асинхронный бесконечный цикл на NodeJS

        Всем привет. Решил сделать небольшую памятку по следам недавних событий. 

        Живой пример: https://jsfiddle.net/popy8apd/

        Неделю назад мой коллега решил сделать парсер поисковой выдачи на NodeJS и selenium, натолкнулся на трудности работы с асинхронным кодом, "плюнул" и написал на Python. 

        А проблема заключалась вот в чем. Он пытался, по старой PHP привычке, писать код в синхронном стиле. Выполнял поисковой запрос в google потом запускал цикл for и на каждой итерации собирал ссылки с первой страницы поиска, на второй итерации на второй странице и так далее. 

        Все было бы прекрасно за исключением того, что переход на следующую страницу поиска событие асинхронное и выполнится оно только после текущего js кода. А это значит, что цикл не будет ждать пока мы перейдем на следующую страницу поиска. Он просто прогонит весь цикл (весь текущий js) потом вызовет C++ код который выполнит переход на следующую страницу выдачи и когда закончит вызовет соответствующие обработчики в js.

        Решил набросать небольшое решение данной задачи. Для этого понадобится генератор, который будет запускать асинхронный код и ждать от него ответа. Когда ответ придет генератор проверит нужно ли прервать цикл. Если нет, то выполнит следующую итерацию цикла.

        Пусть переход на новую страницу выдачи занимает секунду и еще две секунды занимает сохранение результатов в базу (ну чтоб было заметнее).

        Пример на jsfiddle => https://jsfiddle.net/popy8apd/

        function* generateSequence() {
            for (let i = 0; i < 5; i++) { //
        for (let i = 0; true; i++ ) - бесконечный
                 let action = yield new Promise(function (resolve, reject) {
                    // click on button in browser and wait load
                    setTimeout(function () {
                        resolve(i);
                    }, 1000);
                });
                if (action === "break") break;
            }
        }

        let generator = generateSequence();

        function go(action) {
            let promise = generator.next(action).value;
            promise.then((res) => {
                // page loaded save links to db
                alert(res);
                return new Promise(function (resolve, reject) {
                    setTimeout(function () {
                        resolve(res + "SAVE");
                    }, 2000);
                });
            }).then((res) => {
                // data from link saved in db go next page
                alert(res);
                // check condition break move or not
                go("break");
            });
        }

        go();

        7.03.2016

        Как я учился программировать. Нужны ли курсы? (Часть 1)

        Давно хотелось рассказать про свой опыт посещения IT курсов. И вот наконец! Сразу скажу, что основное внимание буду уделять онлайн курсам в группе. Освещать буду 3 курса, один по Ruby on Rails и еще два по JavaScript, а конкретно NodeJS и AngularJS.

        Заголовок говорит: "Как я научился программировать..." , это очень широкая тема и одних курсов тут мало. Поэтому давайте договоримся о том, что в этот раз я буду уделять 90% внимания именно курсам в процессе обучения, а в оставшиеся 10% я тезисно расскажу, что еще такого я делал чтоб научиться программировать.

        Итак, давайте начнем с начала. Любой курс по программированию предполагает определенный уровень знаний в предметной области. И мне как человеку с гуманитарным образованием пришлось получать эти знания на своей первой работе. Работал я интерент-маркетологом, много времени уделял контекстной рекламе и сайтам компании вообще. С 2012 по конец 2014, приходилось делать типовые сайты на WordPress и OpenCart, а так же верстать страницы под рекламные кампании. Именно в то время я всерьез заинтересовался программированием, а в 2013 году начал изучать javascript.

        И вот наконец 27 ноября 2014 года начались мои первые курсы по Ruby On Rails.

        Итак, на этапе выбора у меня возник целый ряд вопросов. Например, какой язык выбрать? К какому организатору курсов пойти? А хватит ли мне знаний? А смогу ли я? А деньги возвращаете? и другие...

        В конце концов благодаря тому, что мне всегда нравилась Япония, плюс время начала этих курсов мне подошло больше чем на других я выбрал Ruby и RubyOnRails от организатора компании Sloboda Studio.

        Да, это не самые весомые и обдуманные причины! Но, это единственные которые я мог четко осознать на момент выбора. Уже окончив курсы и начав работать я начал узнавать как много всего в мире программирования было сделано под впечатлением от Ruby On Rails. Оказалось, что Ruby On Rails, это такой эталон MVC архитектуры и вообще сборник хороших практик. В мире JavaSript он повлиял на CoffeeScript, Sails - аналог Rails, Jade (теперь Pug) шаблонизатор и т.д. Может быть вы знаете еще примеры :)
        Ах да! Интересно, что с такими нововведениями в JavaScript как генераторы, итераторы и ключевое слово yield впервые я познакомился в Ruby. То что для JavaScript новый стандарт от середины 2015 года для Ruby уже вчерашний день :)

        А теперь коротко о плюсах и минусах курса

        Ruby On Rails

        Минусы:
        1. Много маркетинга. Курсы больше направленны на получение прибыли.
          У компании было три курса, по ruby, python и javascript у каждого свой лендин-пэйдж с графиком популярности языков программирования, а самое интересное у каждого лендинга был свой сфабрикованный рейтинг.
        2. Отсутствие видео записей занятий для минимального пакета.
          На выбор предоставлялось три пакета: мини, стандарт и премиум со стажировкой. Я купил минимальный пакет и остался доволен.
        3. Слабо подается теория.
          В описание к курсу говорится, что по окончанию будет освоено достаточно много технологий, а хорошая подготовка не обязательна. При этом теории уделяется очень мало времени, поэтому трудиться приходилось много. Справедливости ради отчему, что соотношение теории и практики в курсе было заявлено до начала, и соответствовало действительности.
        4. Слабый преподаватель.
          От части это можно объяснить возрастом 22 года. Объяснение нового материала происходило быстро ориентируясь на план, а не на понимание учеников и было обильно сдобрено сленгом, который усугублял сложность восприятия материала.
        5. Слайды к лекциям на английском.
          Сложно комментировать этот пункт. Просто риторический вопрос остался у меня в голове. Зачем?
        Плюсы:
        1. Много практики.
          Это главный плюс данных курсов так как позволяет максимально почувствовать реальную рабочую обстановку только на курсах. Конечно если не отлынивать.
        2. Система рейтинга.
          Данный пункт логично продолжает первый потому, что мотивирует для активной работы.
        3. Работа в команде.
          На второй месяц всех студентов разбивают на группы по 3 человека, кто-то назначается главным и несет ответственность за организацию работы группы. Мне посчастливилось быть своего рода тим-лидом команды благодаря своим баллам. Работа над проектом происходит на github репозитории и это пожалуй самое интересное. Работать первый раз в git, под linux при том, что и то и другое в новинку очень интересно! А главное полезно для профессионального роста.
        Итог:
        Перед началом курсов нужно подготовить базу по работе с файлами, базами данных (SQL) и лучше знать ООП. Либо компенсировать все это безбожным трудом! :)
        Мои личные впечатления остались положительными, так как успешно была проделана большая работа. Для того, чтоб вы понимали, до курсов я даже файл читать не умел, не говоря уже про работу с базой данных, github и linux, а за две недели до конца сдачи проекта понятия не имел как его закончить. На секунду, от меня зависели еще два человека и не сдать проект, это значит проучиться в пустую. Но мы сдали!!


        По Ruby у меня все! Если вы еще не устали давайте перейдем к JavaScript и начнем с NodeJS

        продолжение следует ...

        5.30.2016

        Подборка интересного из мира Front-End за год(2015-2016) и не только

        Я имею такую практику, что когда нахожу что-то интересное или полезное для себя в области программирования то сохраняю ссылку на материалы у себя на стене в вк.

        Конечно на стене скапливается не только материал по программированию, поэтому я решил собрать весь материал в одну сборку.

        Добро пожаловать ...

        AngularJS для новичка:
        https://www.youtube.com/watch?v=RBXGOK6hLMg
        Работа с базами данных MySQL
        https://www.youtube.com/watch?v=8c9ZMeiwoS4&list=PL5KGx5_ykLX8NrmlQTutJ__TH7pnC4qXB
        Учебник по информатике:
        https://www.youtube.com/watch?v=lnFeG4DOMcE&list=PL66kIi3dt8A5sa_qBur8uxmtuuwuJQGS1
        Руководства по NodeJS
        http://nodeguide.ru/doc/
        Crazy Russian compiler engineer that talks.
        http://mrale.ph/
        WebSokets
        https://habrahabr.ru/post/79038/
        Microsoft JScript Compiler
        http://www.phpied.com/make-your-javascript-a-windows-exe/
        Хорошая подборка материалов по Node.js
        https://nodejs.zeef.com/julio.castillo.anselmi
        Визуализация данных, SVG, D3JS
        http://infogra.ru/infographics/vizualizatsiya-osnovy-chast-1-dizajnerskie-printsipy
        http://infogra.ru/infographics/vizualizatsiya-osnovy-chast-2-osnovy-d3-js
        https://habrahabr.ru/post/189838/
        Карусели:
        1. http://www.idangero.us/swiper/#.VgKjt_SpO-c
        2. http://kenwheeler.github.io/slick/
        3. http://owlgraphic.com/owlcarousel/demos/lazyLoad.html
        4. http://dev7studios.com/caroufredsel-old/
        Скроллеры:
        1. http://scrollerjs.com/#playground
        2. http://johnpolacek.github.io/scrollorama/
        Библиотеки SVG:
        1. http://www.internet-technologies.ru/articles/article_..
        2. http://habrahabr.ru/post/123793/
        Анимация SVG:
        1. http://css-live.ru/articles/rukovodstvo-po-svg-animac..
        2. http://codepen.io/noahblon/blog/an-intro-to-svg-anima..
        3. http://codyhouse.co/gem/animate-svg-icons-with-css-an..
        4. https://uwebdesign.ru/svg-animation/
        Библиотеки SVG:
        1. http://www.internet-technologies.ru/articles/article_..
        2. http://habrahabr.ru/post/123793/
        Анимация SVG:
        1. http://css-live.ru/articles/rukovodstvo-po-svg-animac..
        2. http://codepen.io/noahblon/blog/an-intro-to-svg-anima..
        3. http://codyhouse.co/gem/animate-svg-icons-with-css-an..
        4. https://uwebdesign.ru/svg-animation/
        Nginx.
        Конфигурячим и настраиваем реверс-прокси:
        1. http://nginx.org/ru/docs/beginners_guide.html
        2. http://devacademy.ru/posts/razbiraemsya-v-http-proksi..
        3. http://nginx.org/ru/docs/http/configuring_https_serve..
        4. http://webo.in/articles/habrahabr/58-nginx-reverse-pr..
        5. http://rootadmin.org.ua/?p=10

        Apach & Nginx
        http://habrahabr.ru/post/267721/
        Javascript & Nginx
        http://habrahabr.ru/post/267955/
        Курс «Алгоритмы и структуры данных поиска» Часть 1
        https://vk.com/talalaev_mikhail?w=wall11767849_1653%2Fall

        SVG animation whit d3JS
        1. http://blog.visual.ly/creating-animations-and-transit..
        2. https://github.com/mbostock/d3/wiki/API-Reference-(ру..

        Example mootools
        1. http://jsfiddle.net/SHF2M/
        2. http://jsfiddle.net/SHF2M/

        Достаточно интересная статья про Promise
        http://habrahabr.ru/company/mailru/blog/269465/

        Javascript от Monsterlessons

        1-Прототипное наследование в Javascript
        2-Примеси в Javascript. Функция extend.
        3-Функции в Javascript
        4-This в Javascript
        5-Singleton паттерн в Javascript
        6-Module паттерн в Javascript
        7-Сборщик модулей webpack Часть 1
        8-Сборщик модулей webpack Часть 2
        9-Сборщик модулей webpack Разбираемся с css Часть 3
        10-Сборщик модулей webpack Разбираемся с шаблонами
        https://vk.com/talalaev_mikhail?w=wall11767849_1679%2Fall

        1. Принципы анимации веба.
        http://habrahabr.ru/company/htmlacademy/blog/255583/

        2. Что дизайнеру нужно знать о SVG: за и против
        http://habrahabr.ru/company/htmlacademy/blog/257039/

        Немного mongodb с mongoose. как связать коллекции:
        1. https://alexanderzeitler.com/articles/mongoose-refere..
        2. http://metanit.com/nosql/mongodb/1.2.php
        3. http://mongoosejs.com/
        4. http://habrahabr.ru/post/144798/

        Криптографические протоколы
        https://www.youtube.com/watch?v=1EmtgmenLtI

        Метод бинарного поиска
        1. https://ru.wikipedia.org/wiki/Двоичный_поиск
        2. http://www.weblibrary.biz/delphi/array/binary
        3. http://mathhelpplanet.com/static.php?p=javascript-algoritmy-poiska

        Техника создания скошенных краёв у секций, основанная на псевдоэлементах и CSS-трансформациях.
        http://www.hongkiat.com/blog/skewed-edges-css/

        Огромная подборка из 50 CSS инструментов, фреймворков и библиотек за 2015 год.
        https://speckyboy.com/2015/12/06/css-tools-frameworks-libraries-2015/

        Урок 5 HTTP запросы, параметры URL
        https://vk.com/talalaev_mikhail?w=wall11767849_1705%2Fall

        Material UI icons
        http://www.material-ui.com/#/

        CSS3 Flexbox:
        1. http://html5.by/blog/flexbox/
        2. http://css.yoksel.ru/flexbox/
        3. http://habrahabr.ru/post/242545/
        4. http://css-live.ru/articles/vizualnoe-rukovodstvo-po-..
        5. https://css-tricks.com/snippets/css/a-guide-to-flexbox/

        Крутая интерактивная обучалка по Git, с фокусом на ветвление. Сделана очень круто, даёт наглядное представление о вопросе.
        http://learngitbranching.js.org/

        Коллекция JS-библиотек для построения графиков с сортировкой по различным критериям.
        http://www.jsgraphs.com/

        Виджеты
        http://webix.com/ru/

        SlideOut — библиотека для создания бокового выпадающего меню
        Работает открытие свайпом, нету зависимостей, поддержка IE 10+, красивая анимация и легкая настройка! На наш взгляд, необходимый компонент в любой мобильной версии сайта. 
        https://mango.github.io/slideout/

        Тысячи крутых бесплатных иконок в 4 форматах
        https://www.behance.net/gallery/30421381/2000-Free-Thousands-icons-bundle-Colored-and-wired

        Taucharts — гибкая JavaScript библиотека для создания диаграмм.
        https://www.taucharts.com/

        Информационная безопасность
        10. DoS
        11. Перехват сеанса
        12. Взлом веб серверов
        13. Взлом веб приложений
        14. SQL инъекция
        15. Взлом беспроводных сетей
        16. Уклонение от систем обнаружения вторжений
        17. Переполнение буфера
        18. Криптография
        19. Тестирование на проникновение
        https://vk.com/talalaev_mikhail?w=wall11767849_1733%2Fall

        Три доклада со шестой встречи PiterJS.
        #1 — JavaScript в большом проекте
        #2 — Полный стек технологий БЭМ
        #3 — React Native Desktop
        https://vk.com/talalaev_mikhail?w=wall11767849_1735%2Fall

        Почему я больше не использую MVC-фреймворки
        https://habrahabr.ru/post/277113/

        1. markdown-it — парсер markdown
        https://habrahabr.ru/post/241766/
        https://github.com/markdown-it/markdown-it

        2. Быстрый gzip на javascript для браузера и node.js
        https://habrahabr.ru/post/216641/
        https://github.com/nodeca/pako
        http://stuk.github.io/jszip/

        Библиотека для упрощения ломаных линий
        1. https://habrahabr.ru/post/137852/

        Что такое виртуальный DOM
        2. https://habrahabr.ru/post/256965/

        Онлайн демонстрация криптографических алгоритмов. Список
        http://emn178.github.io/online-tools/sha3_224.html

        APIs for Data-Driven Marketers
        https://moz.com/blog/apis-for-datadriven-marketers

        Параллельное программирование как образ мышления - Станислав Протасов

        Как развивались многоядерные процессоры? Все ли алгоритмы легко адаптируемы к параллельному масштабированию? Об этом рассказывает кандидат физико-математических наук Станислав Протасов.
        https://vk.com/talalaev_mikhail?w=wall11767849_1755%2Fall

        Стоит приобрести! (Я приобрел, книга супер. Да. Есть опечатки. Но это мелочи)
        https://habrahabr.ru/company/piter/blog/279289/

        New JavaScript UI Library
        http://w2ui.com/web/home

        AnyAPI — коллекция API популярных сервисов.
        https://any-api.com/

        Работа с файлом .htaccess
        Файл htaccess. Начинаем знакомство
        Файл htaccess. Страницы ошибок
        Файл htaccess. Управление доступом
        Файл htaccess. Редирект
        https://vk.com/talalaev_mikhail?w=wall11767849_1766%2Fall

        Очень много интересных проектов сделанных на backbobe
        https://github.com/jashkenas/backbone/wiki/Projects-and-Companies-using-Backbone

        Best Articles on the RisingStack Engineering Blog. Учебные материалы
        1. https://blog.risingstack.com/articles/
        2. https://blog.risingstack.com/from-angularjs-to-react-..
        3. https://blog.risingstack.com/node-js-best-practices/

        Node.js Tutorials: From Zero to Hero with Nodejs
        https://www.youtube.com/watch?v=czmulJ9NBP0

        Грабли Mongoose Позновательно :)
        https://habrahabr.ru/post/253395/

        Организация структуры проекта. scaffolding
        1. https://toster.ru/q/197891
        2. http://yeoman.io/

        Автоматическое генерирование документации:
        1. http://www.jetbrains.com/help/webstorm/2016.1/creatin..
        2. https://www.npmjs.com/package/jsdoc

        Пару интересных статей:
        Шесть мифов разработки продукта
        1. https://habrahabr.ru/post/301230/

        Управляем компьютером с Android устройства
        2. https://habrahabr.ru/post/301190/

        Каково это — быть разработчиком, когда тебе сорок
        3. https://habrahabr.ru/post/282674/

        Canvas:
        1. http://code.tutsplus.com/articles/21-ridiculously-imp..
        2. http://tympanus.net/codrops/2014/09/16/off-canvas-men..
        3. https://github.com/raphamorim/awesome-canvas
        4. http://perfectionkills.com/exploring-canvas-drawing-techniques/

        Все плагины сразу javascript:
        https://github.com/sorrycc/awesome-javascript

        Школа NodeJS
        http://nodeschool.io/ru/

        1. http client
        https://github.com/request/request
        https://github.com/tomas/needle

        2. Асинхронные очереди заданий
        https://github.com/astur/tress

        3. Поиск по html для сервера, типо jQuery
        https://github.com/cheeriojs/cheerio

        Web scraping при помощи Node.js
        1. https://habrahabr.ru/post/301426/
        2. https://habrahabr.ru/post/302766/

        Построй свою интерактивную историю
        http://cartodb.github.io/odyssey.js/