Giter Site home page Giter Site logo

richmondgozarin / angular-es2015-styleguide Goto Github PK

View Code? Open in Web Editor NEW

This project forked from orizens/angular-es6-styleguide

0.0 1.0 0.0 21 KB

Angular (v 1.x) with ES2015 Style Guide: A starting point for Angular development teams to provide consistency through good practices. http://orizens.com

License: MIT License

angular-es2015-styleguide's Introduction

Angular ES2015 Style Guide

This is still a Work In Progress - Please Collaborate

Endorsements

The idea for this styleguide is inspired from john papa's angular style guide which is focused on angular version 1.x, written with ES5. Some sections are currently taken from john papa's styleguide and are subject to change in the future (as this stylguide grows). This styleguide is also inspired from @angularclass's boilerplates for angular & es2015.

Purpose

Opinionated Angular.js written with ES2015 and module loadeing style guide for teams by @orizens

If you are looking for an opinionated style guide for syntax, conventions, and structuring Angular.js applications v 1.x with ES2015 and module loading, then this is it. These styles are based on my development experience with Angular.js and the Echoes Player, Open Source Project Development (currently the es2015 branch).

The purpose of this style guide is to provide guidance on building Angular applications with ES2015 and module loading by showing the conventions I use and in order to prepare angular v 1.x code to angular v 2.

Inspirations

NG6-Starter Angular, Gulp, Browserify

See the Styles in a Sample App

This guide is based on my open source Echoes Player application that follows these styles and patterns. You can clone/fork the code at echoes repository.

##Translations TBD

Table of Contents

  1. Single Responsibility
  2. Modules
  3. Components
  4. Services

Single Responsibility

Rule of 1

  • Define 1 class per file.

The following example defines the several classes in the same file.

// now-playlist.controllers.js
/* avoid */
export class NowPlaylistCtrl {}
export class NowPlaylistFilterCtrl {}

The same classes are now separated into their own files.

/* recommended */

// now-playlist.ctrl.js
export default class NowPlaylistCtrl {}
/* recommended */

// now-playlist-filter.ctrljs
export default class NowPlaylistFilterCtrl {}

Back to top

Modules

Use Proposed Loader Specification (Former ES6/ES2015)

Why?: it assists in bundling the app and promotes the seperation of concerns. In Addition, Angular 2 is also based on Loader's standards.

import NowPlaylist from './now-playlist';
import { NowPlaylistComponent } from './now-playlist.component';

Module Loaders Tools

Module Folder Structure

  • each module directory should be named with a dash seperator (kebab notation).

Why?: it follows the web-component notation of seperating a tag name with a dash. It is easier to read and follow in the code editor.

// name of directory for <now-playlist></now-playlist> component
- now-playlist

Module files

  • each module should contain the following:
  1. index.js - it should contain:
  2. module-name.component.js - a component (directive) file defintion with class as a controller
  3. an html template file
  4. a spec file

index.js - module entry point

should contain:

  • the module defintion
  • components/directives angular wrappers
  • its dependencies
  • config phase & function
  • angular's entities wrappers - services, factories, additional components/directives, other..

Why?: this is the file where we can hook vanilla js files into angular. This is the main point to see what this module is composed of.

import angular from 'angular';
import AngularSortableView from 'angular-sortable-view/src/angular-sortable-view.js';
import { NowPlaylistComponent } from './now-playlist.component';

export default angular.module('now-playlist', [
      'angular-sortable-view'
    ])
    .config(config)
    .directive(NowPlaylistComponent.controllerAs, () => NowPlaylistComponent)
    // with angular 1.5, the component definition is as follows:
    .component(NowPlaylistComponent.controllerAs, NowPlaylistComponent)
;
// optional
/* @ngInject */
function config () {

}

module-name.component.js - component defintion with controller class

this file should contain:

  1. the component/directive definition as a literal object, with export.
  2. the "controller" property should be defined as a class.
  3. template should be imported from external file or inlined with template string es2015 syntax.

Why?: It's easy to understand the bigger picture of this component: what are the inputs and outputs retrieved from scope. Everything is in one place and easier to reference. Moreover, this syntax is similar to angular 2 component definion - having the component configuration above the "controller" class.

import template from './now-playlist.tpl.html';

export let NowPlaylistComponent = {
        template,
        // if using inline template then use template strings (es2015):
        template: `
          <section class="now-playlist">
              ....
          </section>
        `,
        controllerAs: 'nowPlaylist',
        // or "bindings" to follow ng1.5 "component" factory
        scope: {
            videos: '=',
            filter: '=',
            nowPlaying: '=',
            onSelect: '&',
            onRemove: '&',
            onSort: '&'
        },
        bindToController: true,
        replace: true,
        restrict: 'E',
        controller:
/* @ngInject */
class NowPlaylistCtrl {
    /* @ngInject */
    constructor () {
        // injected with this.videos, this.onRemove, this.onSelect
        this.showPlaylistSaver = false;
    }

    removeVideo($event, video, $index) {
        this.onRemove && this.onRemove({ $event, video, $index });
    }

    selectVideo (video, $index) {
        this.onSelect && this.onSelect({ video, $index });
    }

    sortVideo($item, $indexTo) {
        this.onSort && this.onSort({ $item, $indexTo });
    }
}
}

Components

  • Use ES2015 class for controller
  • Use Object.assign to expose injected services to a class methods (make it public)
/* @ngInject */
export default class YoutubeVideosCtrl {
	/* @ngInject */
	constructor (YoutubePlayerSettings, YoutubeSearch, YoutubeVideoInfo) {
		Object.assign(this, { YoutubePlayerSettings, YoutubeVideoInfo });
		this.videos = YoutubePlayerSettings.items;

		YoutubeSearch.resetPageToken();
		if (!this.videos.length) {
			YoutubeSearch.search();
		}
	}

	playVideo (video) {
		this.YoutubePlayerSettings.queueVideo(video);
		this.YoutubePlayerSettings.playVideoId(video);
	}

	playPlaylist (playlist) {
		return this.YoutubeVideoInfo.getPlaylist(playlist.id).then(this.YoutubePlayerSettings.playPlaylist);
	}
}

Services

angular.service

Use angular.service api with a class for a service.

Why?: Services in angular 2 are classes. it'll be easier to migrate the code.

angular.factory

use angular.service instead.

angular.provider

export a function as provider as in angular with ES5.

Application Structure

Overall Guidelines

[-] src
  [-] components
  [-] core
    [-] components
    [-] services
  [-] css
  * app.js
  * index.html

src/components

This directory includes smart components. it consumes the app.core services and usually doesn't expose any api in attributes. It's like an app inside a smart phone. It consumes the app's services (ask to consume it) and knows how to do its stuff.

Usage of such smart component is as follows:

<now-playing></now-playing>

Example definition in index.js can be:

import angular from 'angular';
import AppCore from '../core';
import nowPlaying from './now-playing.component.js';
import nowPlaylist from './now-playlist';
import nowPlaylistFilter from './now-playlist-filter';
import playlistSaver from './playlist-saver';
import YoutubePlayer from '../youtube-player';

export default angular.module('now-playing', [
      AppCore.name,
      nowPlaylist.name,
      nowPlaylistFilter.name,
      playlistSaver.name,
      YoutubePlayer.name
    ])
    .config(config)
    .directive('nowPlaying', nowPlaying)
;
/* @ngInject */
function config () {

}

Testing

Unit testing helps maintain clean code, as such I included some of my recommendations for unit testing foundations with links for more information.

Write Tests with Stories

  • Write a set of tests for every story. Start with an empty test and fill them in as you write the code for the story.

Why?: Writing the test descriptions helps clearly define what your story will do, will not do, and how you can measure success.

it('should have a collection of media items', function() {
    // TODO
});

it('should find fetch metadata for a youtube media', function() {
    // TODO
});

Testing Library

Why?: Both Jasmine and Mocha are widely used in the Angular community. Both are stable, well maintained, and provide robust testing features.

Note: When using Mocha, also consider choosing an assert library such as Chai. I prefer Mocha.

Test Runner

  • Use Karma as a test runner.

Why?: Karma is easy to configure to run once or automatically when you change your code.

Why?: Karma hooks into your Continuous Integration process easily on its own or through Grunt or Gulp.

Back to top

Organizing Tests

  • Place unit test files (specs) side-by-side within the component's code.
  • Place mocks in a tests/mocks folder

Why?: Unit tests have a direct correlation to a specific component and file in source code.

Why?: Mock files (json) should be agnostic to the component which is using them. Multiple components specs might use the same jsom mocks.

Back to top

Comments

TBD

ES Lint

Use an Options File

  • Use eslint.org to deifne es2015 support
  • Use .eslintrc file for linting and support es2015 features

Why?: Provides a first alert prior to committing any code to source control.

Why?: Provides consistency across your team.

{
    arrowFunctions: true,
    classes: true,
    modules: true,
    restParams: true,
    spread: true,
    defaultParams: true
}

More To Come...

Back to top

Routing

TBD

Contributing

  1. Open an issue for discussion
  2. Create a pull request to suggest additions or changes

License

Share your thoughts with an issue or pull request

Copyright

Copyright (c) 2015-2016 Oren Farhi

Back to top

angular-es2015-styleguide's People

Contributors

orizens avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.