| .\" Generated with Ronnjs 0.3.8 |
| .\" http://github.com/kapouer/ronnjs/ |
| . |
| .TH "NPM\-CODING\-STYLE" "7" "December 2013" "" "" |
| . |
| .SH "NAME" |
| \fBnpm-coding-style\fR \-\- npm\'s "funny" coding style |
| . |
| .SH "DESCRIPTION" |
| npm\'s coding style is a bit unconventional\. It is not different for |
| difference\'s sake, but rather a carefully crafted style that is |
| designed to reduce visual clutter and make bugs more apparent\. |
| . |
| .P |
| If you want to contribute to npm (which is very encouraged), you should |
| make your code conform to npm\'s style\. |
| . |
| .P |
| Note: this concerns npm\'s code not the specific packages at npmjs\.org |
| . |
| .SH "Line Length" |
| Keep lines shorter than 80 characters\. It\'s better for lines to be |
| too short than to be too long\. Break up long lists, objects, and other |
| statements onto multiple lines\. |
| . |
| .SH "Indentation" |
| Two\-spaces\. Tabs are better, but they look like hell in web browsers |
| (and on github), and node uses 2 spaces, so that\'s that\. |
| . |
| .P |
| Configure your editor appropriately\. |
| . |
| .SH "Curly braces" |
| Curly braces belong on the same line as the thing that necessitates them\. |
| . |
| .P |
| Bad: |
| . |
| .IP "" 4 |
| . |
| .nf |
| function () |
| { |
| . |
| .fi |
| . |
| .IP "" 0 |
| . |
| .P |
| Good: |
| . |
| .IP "" 4 |
| . |
| .nf |
| function () { |
| . |
| .fi |
| . |
| .IP "" 0 |
| . |
| .P |
| If a block needs to wrap to the next line, use a curly brace\. Don\'t |
| use it if it doesn\'t\. |
| . |
| .P |
| Bad: |
| . |
| .IP "" 4 |
| . |
| .nf |
| if (foo) { bar() } |
| while (foo) |
| bar() |
| . |
| .fi |
| . |
| .IP "" 0 |
| . |
| .P |
| Good: |
| . |
| .IP "" 4 |
| . |
| .nf |
| if (foo) bar() |
| while (foo) { |
| bar() |
| } |
| . |
| .fi |
| . |
| .IP "" 0 |
| . |
| .SH "Semicolons" |
| Don\'t use them except in four situations: |
| . |
| .IP "\(bu" 4 |
| \fBfor (;;)\fR loops\. They\'re actually required\. |
| . |
| .IP "\(bu" 4 |
| null loops like: \fBwhile (something) ;\fR (But you\'d better have a good |
| reason for doing that\.) |
| . |
| .IP "\(bu" 4 |
| \fBcase "foo": doSomething(); break\fR |
| . |
| .IP "\(bu" 4 |
| In front of a leading \fB(\fR or \fB[\fR at the start of the line\. |
| This prevents the expression from being interpreted |
| as a function call or property access, respectively\. |
| . |
| .IP "" 0 |
| . |
| .P |
| Some examples of good semicolon usage: |
| . |
| .IP "" 4 |
| . |
| .nf |
| ;(x || y)\.doSomething() |
| ;[a, b, c]\.forEach(doSomething) |
| for (var i = 0; i < 10; i ++) { |
| switch (state) { |
| case "begin": start(); continue |
| case "end": finish(); break |
| default: throw new Error("unknown state") |
| } |
| end() |
| } |
| . |
| .fi |
| . |
| .IP "" 0 |
| . |
| .P |
| Note that starting lines with \fB\-\fR and \fB+\fR also should be prefixed |
| with a semicolon, but this is much less common\. |
| . |
| .SH "Comma First" |
| If there is a list of things separated by commas, and it wraps |
| across multiple lines, put the comma at the start of the next |
| line, directly below the token that starts the list\. Put the |
| final token in the list on a line by itself\. For example: |
| . |
| .IP "" 4 |
| . |
| .nf |
| var magicWords = [ "abracadabra" |
| , "gesundheit" |
| , "ventrilo" |
| ] |
| , spells = { "fireball" : function () { setOnFire() } |
| , "water" : function () { putOut() } |
| } |
| , a = 1 |
| , b = "abc" |
| , etc |
| , somethingElse |
| . |
| .fi |
| . |
| .IP "" 0 |
| . |
| .SH "Whitespace" |
| Put a single space in front of ( for anything other than a function call\. |
| Also use a single space wherever it makes things more readable\. |
| . |
| .P |
| Don\'t leave trailing whitespace at the end of lines\. Don\'t indent empty |
| lines\. Don\'t use more spaces than are helpful\. |
| . |
| .SH "Functions" |
| Use named functions\. They make stack traces a lot easier to read\. |
| . |
| .SH "Callbacks, Sync/async Style" |
| Use the asynchronous/non\-blocking versions of things as much as possible\. |
| It might make more sense for npm to use the synchronous fs APIs, but this |
| way, the fs and http and child process stuff all uses the same callback\-passing |
| methodology\. |
| . |
| .P |
| The callback should always be the last argument in the list\. Its first |
| argument is the Error or null\. |
| . |
| .P |
| Be very careful never to ever ever throw anything\. It\'s worse than useless\. |
| Just send the error message back as the first argument to the callback\. |
| . |
| .SH "Errors" |
| Always create a new Error object with your message\. Don\'t just return a |
| string message to the callback\. Stack traces are handy\. |
| . |
| .SH "Logging" |
| Logging is done using the npmlog \fIhttps://github\.com/isaacs/npmlog\fR |
| utility\. |
| . |
| .P |
| Please clean up logs when they are no longer helpful\. In particular, |
| logging the same object over and over again is not helpful\. Logs should |
| report what\'s happening so that it\'s easier to track down where a fault |
| occurs\. |
| . |
| .P |
| npm help Use appropriate log levels\. See \fBnpm\-config\fR and search for |
| "loglevel"\. |
| . |
| .SH "Case, naming, etc\." |
| Use \fBlowerCamelCase\fR for multiword identifiers when they refer to objects, |
| functions, methods, members, or anything not specified in this section\. |
| . |
| .P |
| Use \fBUpperCamelCase\fR for class names (things that you\'d pass to "new")\. |
| . |
| .P |
| Use \fBall\-lower\-hyphen\-css\-case\fR for multiword filenames and config keys\. |
| . |
| .P |
| Use named functions\. They make stack traces easier to follow\. |
| . |
| .P |
| Use \fBCAPS_SNAKE_CASE\fR for constants, things that should never change |
| and are rarely used\. |
| . |
| .P |
| Use a single uppercase letter for function names where the function |
| would normally be anonymous, but needs to call itself recursively\. It |
| makes it clear that it\'s a "throwaway" function\. |
| . |
| .SH "null, undefined, false, 0" |
| Boolean variables and functions should always be either \fBtrue\fR or \fBfalse\fR\|\. Don\'t set it to 0 unless it\'s supposed to be a number\. |
| . |
| .P |
| When something is intentionally missing or removed, set it to \fBnull\fR\|\. |
| . |
| .P |
| Don\'t set things to \fBundefined\fR\|\. Reserve that value to mean "not yet |
| set to anything\." |
| . |
| .P |
| Boolean objects are verboten\. |
| . |
| .SH "SEE ALSO" |
| . |
| .IP "\(bu" 4 |
| npm help developers |
| . |
| .IP "\(bu" 4 |
| npm help faq |
| . |
| .IP "\(bu" 4 |
| npm help npm |
| . |
| .IP "" 0 |
| |