Skip to content

Latest commit

 

History

History
248 lines (165 loc) · 9.15 KB

angular.md

File metadata and controls

248 lines (165 loc) · 9.15 KB

Angular workflow

Starting a project

Create new application project

Create a new Angular application project:

ng new ngx-myapp

Create a new library project using

Create a new empty Angular project:

ng new ngx-mylib --create-application=false

Add a library to the project:

ng generate library ngx-mylib

Add a showcase application to the project:

ng generate application showcase

Conventions

Structure and naming conventions

Project directory structure

Every application project should internally follow the following directory structure:

Directory Purpose
./app/ Main application module and component as pre-generated by ng cli
./app/components/ Reusable components and directives, shared between multiple routes and parent components
./app/pages/ Root components of application routes
./app/pages/:page/components/ Components and directives used only by the parent component and not reusable anything else
./app/pages/:page/components/:comp/components/ Components and directives used only by the parent component and not reusable anything else
./app/pipes/ All pipes
./app/pipes/:domain/ All pipes pertaining to a domain (for example "units", or "time")
./app/services/ All services
./app/services/:domain/ All services pertaining to a domain (for example "api", or "auth")
./app/data/ All application data models
./app/data/:domain/ All application data models pertaining to a domain (for example "auth", "users", etc ...)

Library projects should follow the same structure to the extent that it is applicable.

Directory Name Casing

When naming directories, by default all directories should be snake-cased. There are a large number of special cases addressed later in the Syntax Name Casing section.

Import/Export and directory structure

All directories, ./app and deeper, have to contain an index.ts file (re)exporting everything that should be accessible from the deeper structure of the directory so that other parts of the application can import while remaining agnostic of the internal structure.

EXAMPLE

./app/services/myservice/helpers/DoesInternalThing.ts

export class DoesInternalThing { ... }

./app/services/myservice/DoesUsefulThing.ts

export class DoesUsefulThing { ... }

./app/services/myservice/DoesAnotherUsefulThing.ts

export class DoesAnotherUsefulThing { ... }

... then we would need to have an index.ts file (re)exporting DoesUsefulThing and DoesAnotherUsefulThing:

./app/services/myservice/index.ts

// No need to (re)export the internal DoesInternalThing service
export * from "./DoesUsefulThing";
export * from "./DoesAnotherUsefulThing";

... and also an index.ts one level deeper (re)exporting all services:

./app/services/index.ts

export * from "./myservice";

... and also an index.ts directly inside ./app (re)exporting everything:

./app/index.ts

export * from "./services";

... so that when importing from another part of the application, we can just do:

./app/components/mycomponent/index.ts

import { DoesUsefulThing, DoesAnotherUsefulThing } from `../../`;

CodeStyle

Check VS code configuration

For details on how to set up VS code see here

Check JS/TS project setup

For details on how to set up a TypeScript project see here and here

Keeping versions in sync

To add tests which will make sure all the nested package.json files in your project's libraries stay in sync, download package.spec.ts into the project root directory, next to package.json. Run this test by running: npx jasmine ./package.spec.ts

General Syntax Name Casing

When coding, use the following name casing conventions:

Artifact Casing Example
function, variable, constant camelCase function myFunction, let myVar, const myConst
class, interface TitleCase class MyClass, interface IMyInterface
public [property or method]* camelCase public myProperty, public myMethod
private [property or method]* _camelCase private _myProperty, protected _myMethod
enum TitleCase enum MyEnum
enum value ALL_CAPS MyEnum.SOME_VALUE

Any public [property or method] that is only exposed as public to be used in that same component's template, but could otherwise be private should be cased as if they are private [property or method]!

There are additional rules for casing Angular specific, higher level artifacts:

Components

Names of directories containing components should be TitleCase. The name of the directory should match the name of the component with or (preferably) without the word "Component".

Names of component classes should be TitleCase and should end with the word "Component".

Selectors for components should be snake-case and start with a common prefix for the library/application, or (by default) ngx-.

Component's template and styling files should be named index.html and style.scss.

// Located in directory/file: "/Something/index.ts"
// ... alternatively "/SomethingComponent/index.ts"
// Accompanied by template and styling:
//  - index.html
//  - style.scss
@Component({
  selector: 'ngx-something',
  templateUrl: 'index.html',
  styleUrls: ['style.scss']
})
exports class SomethingComponent { ... }
Directives

Names of directories containing directives should be camelCase. The name of the directory should match the name of the directive class with or (preferably) without the word "Directive".

Names of directive classes should be TitleCase and should end with the word "Directive".

Selectors for directives should be camelCase and start with a common prefix for the library/application, or (by default) ngx.

// Located in directory/file: "/doSomething/index.ts"
// ... alternatively "/doSomethingDirective/index.ts"
@Component({ selector: 'ngxDoSomething' })
exports class DoSomethingDirective { ... }
Pipes

Names of directories containing pipes should be camelCase. The name of the directory should match the name of the pipe class with or (preferably) without the word "Pipe".

Names of pipe classes should be TitleCase and should end with the word "Pipe".

Selectors/Names for pipes should be camelCase and start with a common prefix for the library/application, or (by default) ngx.

// Located in directory/file: "/doSomething/index.ts"
// ... alternatively "/doSomethingPipe/index.ts"
@Pipe({name: 'ngxDoSomething'})
export class DoSomethingPipe { ... }
Services

All services need to be implemented as classes!

Names of directories containing services should be TitleCase. The name of the directory should match the name of the service class with or (preferably) without the word "Service".

Names of service classes should be TitleCase and should NOT end with the word "Service".

// Located in directory/file: "/Something/index.ts"
// ... alternatively "/SomethingService/index.ts"
@Injectable()
export class DoSomething { ... }
Data Models

Names of directories containing data models should be TitleCase. The name of the directory should match the name of the data model class with or (preferably) without the word "Modal".

Names of data model classes should be TitleCase and should end with the word "Model".

// Located in directory/file: "/Something/index.ts"
// ... alternatively "/SomethingModel/index.ts"
export class SomethingModel { ... }