Skip to content

Conventions

Chris Berry edited this page May 17, 2017 · 22 revisions

TOC

New Development

We are in the process of migrating Deck from Angular 1 to React. You're welcome to write React for any new features, although it's not a well established or documented process yet.

If you're working on a new feature and would like to stick with Angular, that's okay. We strongly encourage writing new Angular code in Typescript. There are plenty of examples in the codebase.

Imports

Imports should be ordered as follows:

  • 'angular' should always be the first thing imported (TS, TSX) or required as a const (JS)
  • any third-party imports should follow 'angular'
  • a blank line
  • a single import from @spinnaker/core, if applicable
  • a blank line
  • any imports from the current module
  • a blank line
  • any .less files, which should be imported, not required.

When importing, there should be a space between curly brackets, e.g. { module }, not {module}. Like most things in the codebase (including the import styles above), you'll see a mix of both styles, as we often do not settle on a convention until we've written quite a bit of code, and we often do not update existing code unless we're already in a file making changes.

Style Guide

Use Todd Motto's Angular Style Guide as a starting point

Naming Conventions

Directories

All files that have a close relation should reside in the same file structure. This includes html, js/ts/tsx, less/css, and unit test files.

Example
We have a module that is responsible for viewing a cluster. This would probably be called the cluster module. The file structure would look something like this:

app/scripts/modules/core
├── cluster 
│   ├── cluster.module.ts
│   ├── cluster.service.ts
│   ├── cluster.service.spec.ts
│   ├── clusterToggles.directive.html
│   ├── clusterToggles.component.ts
│   └── index.ts

Javascript/Typescript Files

[moduleName].[artifactType].js

Artifact Types:

  • controller
  • service
  • component
  • directive (deprecated - favor use of components)
  • provider
  • values
  • constants

Examples
pipeline.controller.ts
pipeline.service.ts
pipelineSelector.component.ts
feedback.modal.controller.ts (slight deviation from other examples)

Unit Test Files

Name the tests the same as the file under test and append .spec.ts

Example

File under test:
pipeline.controller.ts

Test name:
pipeline.controller.spec.ts

React Components

React component files should have the same name as the component, e.g. ExecutionGroup.tsx, LoadBalancerPod.tsx

HTML Files

[moduleName].[templateType].html

Template Types:

  • component: if the template is included in a component via templateUrl
  • modal: if the template is used in a modal
  • view: if the template is used in a ui-router's ng-view

Examples
pipeline.component.html
pipeline.modal.html

Angular Modules Names

The angular module names should loosely follow the file naming rules for the JS/TS files.

[namespace].[module].[artifactType]

Namespace:

  • spinnaker.core: core Spinnaker code
  • spinnaker.aws: AWS-specific code
  • spinnaker.gce: GCE-specific code

Example
File Name: pipeline.controller.ts

import { module } from 'angular';

export class PipelineController {
  // ...
}

export const PIPELINE_CONTROLLER = 'spinnaker.core.pipeline.controller';
module(PIPELINE_CONTROLLER, [])  
  .controller('pipelineController', PipelineController)

CSS

Deck uses LESS to generate CSS. If you need to customize the CSS for a component, create a LESS file with the same name as the component, e.g. pipeline.component.less. Favor BEM for class names, and restrict the CSS to the component:

@import "../less/imports/commonImports.less";

pipeline {
  display: block;
  background-color: @light_blue_background;
  h3 {
    font-size: 90%;
  }
  .pipeline-stage {
    padding: 10px;
  }
  .pipeline-stage-active {
    font-weight: 600;
  }
}

Webpack Conventions

With the introduction of webpack to the deck application we now have 2 module systems in play:

  1. The angular module system which is used for Dependency Injection (DI).
  2. The CommonsJS style that is used for file system level dependency resolution.

These 2 systems play nicely together as long as you follow a few conventions.

ES2015

Prefer ES2015 features when possible; avoid using lodash for things like iteration, map, filter unless it results in cleaner, easier to read code.

ES2015 features we strongly favor:

  • let: for block scoped variables
  • const: for constant variables
  • arrow functions
  • object destructuring, e.g. let { bar, baz } = foo; // where foo is an object with "bar" and "baz" as fields
  • spread/rest operators
  • default params for functions
  • string templates for multi-line strings or simple substitutions
Clone this wiki locally