Skip to content

Instantly share code, notes, and snippets.

@rayshan
Last active June 12, 2018 21:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rayshan/1ac3fd6329c03124e483 to your computer and use it in GitHub Desktop.
Save rayshan/1ac3fd6329c03124e483 to your computer and use it in GitHub Desktop.
Montage Framework Style Guide (draft)

Montage Framework Style Guide (draft)

This style guide includes recommended practices for consistency. If any of the rules conflicts with readability in a particular case, ignore the rules and chose readability.

Table of Contents

General Code Format

Set your editor to use below settings. Optionally use http://EditorConfig.org.

  • Character set UTF-8
  • Indent: 4 spaces (there should be no tabs in the codebase)
  • Line ending: LF (Unix-style)
  • Trim trailing whitespace
  • Max line length: keep it reasonable

Not settable by EditorConfig:

  • Function declaration
    • Anonymous: function () {}, not function() {}
    • Named: function foo() {}, not function foo () {}
  • Function invocation func(arg), not func (arg)
  • No leading or trailing spaces, for example, (arg) not ( arg )
  • Space after , & ; unless end of line. For example:
    • [1, 2, 3, 4, 5, 6]
    • for (i = 0; i < length; i++)
  • 1 + 1, not 1+1
  • Space before & after comment blocks
    • // comment not //comment
    • /* comment */ not /*comment*/
  • Serialization bracing in HTML template, as generated by minit:
<script type="text/montage-serialization">
{
    "owner": {
        "properties": {
            "element": {"#": "main"}
        }
    }
}
</script>

Commit Message Format

50 1st line, 1st word capitalized, no period

(blank line)

72 3rd & following lines
  • Use imperative verbs - "add", not "adds" / "added" / "adding"

Naming Conventions

General

  • Do not abbreviate unless if it's a well known term, for example, abbreviate min, max, config, don't abbreviate EarthquakeOverlay into EQOverlay

JavaScript

  • Components & prototypes - must be upper CamelCase, for example, ComponentFoo; prototype name in serialization block auto converted to such case
  • Boolean flags - prefix with is or has, for example, isFoo
  • Private variable name - prefix with _, for example, _foo
  • Constant variable name - EMPTY_ARRAY
  • Prefer self over that or me, etc., for example, var self = this;

CSS

  • For components in Montage Framework & associated UI sets, always prefix with a namespace. For example, .montage-ComponentFoo, .digit-ComponentFoo.
  • For apps using Montage Framework, we also recommend to optionally prefix with app name to distinguish source of components. For example, .myApp-ComponentFoo.

Files & Directories

  • component-foo.reel

TODO: to be merged in: https://github.com/montagejs/montage/wiki/Naming-Conventions

Order

  • Prefer alphabetical ordering, unless the natural order of a sequence would be immediately obvious to anyone reading the code. For requires, switch cases, etc.

JavaScript

  • Terminate statements with ;
  • Declare variables at top of block
  • Declare multiple variables with single var statement & commas; can do in 1 line if not many variables
  • Define constructor function at top of block
  • Use K&R style braces, { at end of line, for example,:
return {
   status: 'ok'
};
  • No braces for 1-line if statements
  • Prefer === and !== unless need == or != behaviour
  • strict mode - TBD
  • Multiline string
var longString = 'A rather long string of English text, an error message ' +
        'actually that just keeps going and going';
  • Getters before setters
  • Indent method chains, for example:
loadFile
    .then()
    .then()
    .catch()

Error handling

TBD

Performance

  • Async - prefer callback over promises in implementation, where performance matters; prefer promises in MontageJS APIs
  • Prefer for or do-while loops over forEach
  • Avoid closures

QA

  • Hinting - TBD
  • Testing - Jasmine + montage-testing

Docs

  • Write in JSDoc + markdown
  • Prefer standard tags over synonyms, for example, @function, not @func or @method
  • Prefer .prototype over # due to lack of JSDoc documentation on # and lack of support for it in certain editors, such as WebStorm

Comment style

/**
 * @private
 * @property {Object[]} value
 */

// not

/**
 @private
 @property {Object[]} value
 */

Getter / setters

If setting a private variable, document everything on getter / setter; if not, document on private variable.

/**
 * Description
 *
 * @property {PressComposer} value
 * @default null
 * @private
 */
_pressComposer: {
    value: null
},

/**
 * @private
 */
_active: {
    value: false
},

/**
 * Description
 *
 * @property {boolean}
 * @default false
 */
active: {
    get: function () {
        return this._active;
    },
    set: function (value) {
        this._active = value;
        this.needsDraw = true;
    }
},
@lordbron
Copy link

In "General" section:

Do not abbreviate unless if it's a well known term, for example, abbreviate min, max, config, don't abbreviate EarthquakeOverlay into EQOverlay

break it up a bit like:

Do not abbreviate, unless if it's a well known term. For example, abbreviate min, max, config; don't abbreviate EarthquakeOverlay into EQOverlay

I also find it odd you use "Do not abbreviate" at he start, but "don't abbreviate" later on. Abbreviate or do not. ;)

@lordbron
Copy link

Space before & after comment blocks
// comment not //comment
/* comment _/ not /_comment*/

speaks to single lines but what about multiple lines. In the getter/setter section you have the following:
/**

Yet you never mention the /** is proper to start a multiline nor do you mention why the */ ends it. So that should be an entry

Also, is there a preference between the following:

/**

  • Foo exists because Bar, X, Y extend it but Foo maintains core methods;
  • The core methods are common regardless of the subclass for internal monitoring
    */

versus

// Foo exists because Bar, X, Y extend it but Foo maintains core methods;
// The core methods are common regardless of the subclass for internal monitoring

What about header block comments such as:

/************************************
****** Animation Methods *******
************************************/

Is that frowned upon? If so, give guidance on how to handle such items.

@rayshan
Copy link
Author

rayshan commented Mar 10, 2015

@lordbron

Do not abbreviate, unless if it's a well known term. For example, abbreviate min, max, config; don't abbreviate EarthquakeOverlay into EQOverlay

Will fix

Do not

Will fix

/**

/** is required by JSDoc, we don't have a choice. But I see no reason to use double * if it's not a JSDoc comment. Will clarify.

preference between // & /**/

I think this is a tough one. // is usually more for single, full-line comments, but I don't see why double line comments can't use it. If it's 20 lines, then it may be a bad idea. Maybe we can do "what's reasonable" like line length, e.g. 1~3 lines use //, anything longer use /**/.

header block comments (the flower box)

This could help readability. I recommend not restricting it as long as it's reasonable.

@pchaussalet
Copy link

I am not a big fan of the one-line if without braces. It's a statements block (even if it's a very short one) and as such, I would expect it to be written as all others blocks (as JSHint does).

Regarding the header block comments, could we leave ascii art where it belongs (in the 90's...) ? 😃

Last point, the anonymous functions declarations. I can live with a space before the opening parenthesis (even if I generally avoid it, I'll configure my editor to do that for me), but what about going one step further and promoting named closures. It makes the developer give clues about its intentions in the function and helps debugging (no more "in Anonymous function" lines in stacktraces). Of course, that should be a loose rule (for map or filter parameters, by example).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment