Introduction
This paper proposes the architecture of a frontend project that uses the following technologies:
- Typescript
- Angular 1.*
- Testing (Mocka)
- Less/Sass
Typescript guidelines
We follow the excelmicro/typescript style guides that are based on the Airbnb JavaScript Style Guide.
File structure
app
├── sections
│ ├── search
│ │ ├── search.ts
│ │ ├── search-controller.ts
│ │ ├── search.html
│ │ ├── search.less
│ │ ├── search_test.ts
├── components
│ ├── performance-chart
│ │ ├── performance-chart.ts
│ │ ├── performance-chart-directive.ts
│ │ ├── performance-chart.html
│ │ ├── performance-chart.less
│ │ ├── performance-chart_test.ts
│ ├── ├── services
│ │ ├── ├── api-service.ts
│ │ ├── ├── services.ts
├── assets
├── app.ts
├── index.mustache
dist
less
typings
doc
Sections
It is very close to an entire page content. Section divides logically the main pages of the application. Section always set a basic url for the page content.
Components
A component is usually a mixture of the following:
- Angular Directive, name-directive.ts
- Angular module registration, name.ts
- Angular Html template, name.html
- Less only for the current Html, name.less
- Module testing, , name_test.ts
- Potentially helping assets like modpna, additionally logic functionality etc.
Services
A service is a mixture of the following:
- Angular module registration, name.ts
- The functionality of service, name-service.ts
A service could potentially consist of a business logic segment or an API communication module.
Less
Component less
Less code inside a component/section will only stylesheet the corresponding component and will namespace the stylesheet by the component name.
//performance-chart.less
(projectNameΑcronym)-performance-chart {
width: 1px;
span {
height: 2px;
}
}
Global less
Less code that is placed in the less
folder will stylesheet the entire application. We can spite the global less folder on 3 parts.
scope.less
scope.less
includes all the .less files from the services and components.
fonts.less
fonts.less
should include the fonts less files from third party providers, like fontawesome
and configure the information like the fonts location
@fa-font-path: "assets/fonts/";
app.less
includes the fonts.less. scope.less and the basic framework that we use, like bootstrap.
Code Styles
Namespaces
Namespaces should be prefixed by the project name acronyms (let’s say pna) and the name format should follow the file structure.
app.ts: pna
services/api-provider-service.ts: pna.services.apiProviderService
components/my-component.ts: pna.components.myComponent
Classes
Class names should begin with Capital letter. Class members should declared first. The ordering of private/public members/methods of each class is depicted from the tslinter that we use.
//services/api-provider.ts
namespace pna.services.apiProvider {
class ApiProvider {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet(): string {
return "Hello, " + this.greeting;
}
}
}
Typescript annotations for angular component registration
We take advantage of the typescript annotations in order to register an Angular component (service, directive, filter, config)
Service
@service('module.name', 'componentName')
class LsApi {
}
The @service
annotation registered a factory on the module module.name
with the name componentName
. During the registration we also prefix the componentName with the pna
.
Directive
@component('module.name', 'componentName', {
templateUrl: 'components/performance-chart/performance-chart.html',
... set values to default parameters
})
class componentClass {
}
The @component
annotation registers a directive on the module module.name
with the name componentName
. During the registration we also prefix the componentName with the pna
.
Component Annotation Default Parameters
directive name: pnaComponentClass
controller: ComponentClass
controller as: componentClassCtrl
bindToController: true
restrict: ‘E’
Conrtoller
@controller('module.name', 'componentName')
class ResultsController {
}
The @controller
annotation registers a directive on the module module.name
with the name componentName
. During the registration we also prefix the componentName with the pna
.
Config
@config('module.name')
class ConfigClass {
}
The @config
annotation registers a config on the module module.name
.
IDE
You are free to use any IDE/text editor. We recommend the sublime 3 editor with some additional packages.