{"id":22860030,"url":"https://github.com/reelyactive/node-style-guide","last_synced_at":"2025-04-30T17:46:51.085Z","repository":{"id":29859351,"uuid":"33404321","full_name":"reelyactive/node-style-guide","owner":"reelyactive","description":"Our guide to creating, maintaining and testing JavaScript for NodeJS.  We believe in an open Internet of Things.","archived":false,"fork":false,"pushed_at":"2024-11-03T22:50:53.000Z","size":9,"stargazers_count":3,"open_issues_count":1,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-30T18:34:25.274Z","etag":null,"topics":["nodejs","style-guide"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reelyactive.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-04-04T12:11:59.000Z","updated_at":"2021-02-23T14:14:32.000Z","dependencies_parsed_at":"2022-08-03T12:30:21.889Z","dependency_job_id":null,"html_url":"https://github.com/reelyactive/node-style-guide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reelyactive%2Fnode-style-guide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reelyactive%2Fnode-style-guide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reelyactive%2Fnode-style-guide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reelyactive%2Fnode-style-guide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reelyactive","download_url":"https://codeload.github.com/reelyactive/node-style-guide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251754368,"owners_count":21638501,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nodejs","style-guide"],"created_at":"2024-12-13T09:08:47.094Z","updated_at":"2025-04-30T17:46:51.062Z","avatar_url":"https://github.com/reelyactive.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# reelyActive's Node.js Guide\n\nHere we summarise the best practices, coding standards and tools for all our Node.js development.\n\n\n## Existing Standards\n\nFortunately, we aren't the first to code for Node.js, and there are some good style guides out there from which to draw inspiration.  Remember, the reason for following (de facto) standards is to facilitate both collaboration and consistency.\n\n\n### Felix's Node.js Style Guide\n\n[Read it on GitHub](https://github.com/felixge/node-style-guide).  Read _all_ of it.  Seriously.  All of it.  We'll wait patiently.  Now that you've read it you'll recall and appreciate the _select_ highlights below:\n\n#### Two Spaces\n\n\u003e Use 2 spaces for indenting your code and swear an oath to never mix tabs and spaces - a special kind of hell is awaiting you otherwise.\n\n#### 80 Characters Per Line\n\n\u003e Limit your lines to 80 characters. Yes, screens have gotten much bigger over the last few years, but your brain has not. Use the additional room for split screen, your editor supports that, right?\n\n#### Case\n\n- Use lowerCamelCase for variables, properties and function names\n- Use UpperCamelCase for class names\n- Use UPPERCASE for Constants\n\n\n### Google's JavaScript Style Guide\n\n[Read it](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml).  You can skim through the bits that Felix already touched upon, because in the event of a conflict, Felix's Style Guide shall prevail.  Please take extra care in reading the following three sections:\n\n#### Naming\n\nThe very explicit [Naming Style Rules](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Naming#Naming) provide more than simple DOs and DONTs, they also explain why the given practices are encouraged.  They also reinforce Felix's naming guidelines, for example:\n\n- functionNamesLikeThis,\n- variableNamesLikeThis,\n- ClassNamesLikeThis,\n- EnumNamesLikeThis,\n- methodNamesLikeThis,\n- CONSTANT_VALUES_LIKE_THIS,\n- foo.namespaceNamesLikeThis.bar, and\n- filenameslikethis.js\n\n#### Code Formatting\n\nThe very explicit [Code Formatting Style Rules](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Code_formatting#Code_formatting) provide all the examples you need to resolve ambiguities.  Keep in mind that Google follows the C++ formatting rules in spirit.  How about an example pertaining to a common source of contention: Function Arguments?\n\n\u003e When possible, all function arguments should be listed on the same line. If doing so would exceed the 80-column limit, the arguments must be line-wrapped in a readable way. To save space, you may wrap as close to 80 as possible, or put each argument on its own line to enhance readability. The indentation may be either four spaces, or aligned to the parenthesis.\n\n#### Comments\n\nThe very explicit [Comments Style Rules](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Comments#Comments) also follow the C++ rules in spirit and specifically use [JSDoc](http://usejsdoc.org/).  There are many illustrative examples.  Read them!  And remember:\n\n\u003e Inline comments should be of the // variety.\n\n\n## reelyActive Standards\n\nThe existing standards above cover a lot, but they don't cover everything.  So we're establishing a few of our own internal standards which are specifically suited to our projects and workflow.\n\n### Coding Style\n\n#### Copyright\n\nEvery JavaScript file should start with the following comment:\n\n    /**\n      * Copyright reelyActive 2014-2015\n      * We believe in an open Internet of Things\n      */\n\nThe use of a copyright indicates that the code is intellectual property created by reelyActive.\n\nNote that the date range should extend between the year the file was initially created to the year the file was last modified.  This is a simple way to provide a brief historical perspective of the code.\n\nThe line _\"We believe in an open Internet of Things\"_ serves as a reminder of our vision and should inspire the developer to maintain the code in a way befitting of an open project with many collaborators.\n\n#### Self: what is this exactly?\n\nWhat is _this_?  In [Mixu's Node Book](http://book.mixu.net/node/ch4.html), the _this_ keyword is considered the #1 gotcha in V8 and JavaScript.  Therefore, in a class constructor and its class methods, we always use a _self_ variable to refer to the class object instance.  In other words, the _self_ unambiguously refers to the class instance.\n\nA static method can accept an _instance_ parameter in order to work on a specific class object instance.\n\nThe example below illustrates our use of the _self_ variable and _instance_ parameter.  And [this video clip](https://vimeo.com/59037145) represents an amusing meme you can use to recall our motivation for the _self_ variable.\n\n```javascript\n/**\n * An example class constructor\n * @constructor\n */\nfunction SomeClass() {\n  var self = this;                               // Always on the first line\n\n  self.app = express();\n  self.httpPort = 80;\n\n  self.app.listen(self.httpPort, function() {    // this.httpPort would work\n    console.log(\"Listening on \", self.httpPort); // this.httpPort wouldn't work\n  });\n};\n\n/**\n * An example class method\n */\nSomeClass.prototype.doSomething = function() {\n  var self = this;                               // Always on the first line\n\n  someStaticMethod(self);\n};\n\n\n/**\n * An example static method\n * @param {SomeClass} instance The given class object instance.\n */\nfunction someStaticMethod(instance) {\n  instance.app.doSomethingElse();\n};\n```\n\n### RESTful Structure\n\n#### Keep server.js simple\n\nThe class constructor is contained in a file named server.js.  A developer should be able to quickly read the file and identify all the supported routes.  Imagine it as a table of contents for the REST API.\n\nBelow is an example server.js file.\n\n```javascript\nvar express = require('express');\n\n/**\n * An example RESTful class constructor\n * @constructor\n */\nfunction RESTfulClass() {\n  var self = this;\n\n  self.app = express();\n\n  self.app.use(function(req, res, next) {\n    req.instance = self;                         // Sneak the class object\n    next();                                      //   instance into the req\n  });\n\n  // Each route is in a separate external file\n  self.app.use('/someroute', require('./routes/someroute'));\n  self.app.use('/anotherroute', require('./routes/anotherroute'));\n\n  self.app.listen(80);\n};\n\nmodule.exports = RESTfulClass;\n```\n\n#### One route per file\n\nEach API route is in a separate external file within a routes subfolder.  A developer should be able to quickly read the file and identify any middleware used, all the routes and subroutes as well as the supported HTTP methods for each.\n\nEach route is an [express router object](http://expressjs.com/api.html#router).\n\nEach method (GET, POST, PUT, DELETE, ...) for a given route will be implemented via a function call.  This allows a developer to quickly navigate to the implementation of any given route.  For clarity, the function name will have a prefix corresponding to the given HTTP method, specifically:\n- GET = retrieve\n- POST = create\n- PUT = replace\n- DELETE = delete\n\nIn keeping with the previous example, the file routes/someroute.js would resemble the following:\n\n```javascript\nvar express = require('express');\nvar router = express.Router();\n\nrouter.use(function someMiddleware(req, res, next) {\n  next();\n});\n\nrouter.route('/')                                // Supports GET, POST\n  .get(function(req, res) {\n    retrieveSomething(req, res);\n  })\n  .post(function(req, res) {\n    createSomething(req, res);\n  });\n\nrouter.route('/:id')                             // Supports GET, PUT, DELETE\n  .get(function(req, res) {\n    retrieveSomethingSpecific(req, res);\n  })\n  .put(function(req, res) {\n    replaceSomethingSpecific(req, res);\n  })\n  .delete(function(req, res) {\n    deleteSomethingSpecific(req, res);\n  });\n\nfunction retrieveSomething(req, res) { }         // GET = retrieve\nfunction createSomething(req, res) { }           // POST = create\n\nfunction retrieveSomethingSpecific(req, res) { } // GET = retrieve\nfunction replaceSomethingSpecific(req, res) { }  // PUT = replace\nfunction deleteSomethingSpecific(req, res) { }   // DELETE = delete\n\nmodule.exports = router;\n```\n\n## Development Tools\n\nWe use a handful of development tools to ensure that our code is consistent, tested and documented, thereby making everyone's life easier.\n\n### JSHint for Standards Enforcement\n\nSee [JSHint](http://jshint.com/).  Place the .jshintrc file included in this repository in the root folder of the project.  To validate a file named server.js run:\n\n    jshint server.js\n\nGive yourself a pat on the back when jshint returns no errors.\n\n### jscs for Code Style Enforcement\n\nSee [jscs](http://jscs.info/).  Place the .jscsrc file included in this repository in the root folder of the project.  To validate a file named server.js run:\n\n    jscs server.js\n\nReward yourself with a beer when jscs returns _No code style errors found_.\n\n### Mocha for Tests\n\nSee [Mocha](http://mochajs.org/).  Create a test folder in the root with two subfolders:\n- functional\n- unit\n\nUnit tests shall have a .test.js file matching the name of the .js file under test.  Functional tests shall have a .test.js file named after the scenario under test.  There shall be one scenario (describe) per file to keep things tidy.\n\nThe following is an example of /test/unit/server.test.js which would represent a unit test for the file /lib/server.js:\n\n```javascript\nvar assert = require('assert');\nvar server = require('../../lib/server.js');  // Module under test\n\n// Inputs for the scenario\nvar INPUT_DATA = 'coffee';\n\n// Expected outputs for the scenario\nvar EXPECTED_DATA = { coffeeType: 'mocha' };\n\n// Describe the scenario\ndescribe('server', function() {\n\n  // Set up the scenario (runs once at the start)\n  before(function() {\n    var self = this;\n    self.server = new server();\n  });\n\n  // Reset the scenario (runs before each individual test)\n  beforeEach(function() {\n    var self = this;\n    self.server.clear();\n  });\n\n  // Individual test (synchronous)\n  it('should return an Object when instantiated', function() {\n    var self = this;\n    assert.equal(typeof self.server, 'object');\n  })\n\n  // Individual test (asynchronous)\n  it('should return mocha when I ask for coffee', function(done) {\n    var self = this;\n    self.server.doSomethingAsynchronous(INPUT_DATA, function(data) {\n      assert.deepEqual(EXPECTED_DATA, data);\n      done();\n    });\n  })\n});\n```\n\n### JSDoc for Documentation\n\nSee [JSDoc](http://usejsdoc.org/).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freelyactive%2Fnode-style-guide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freelyactive%2Fnode-style-guide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freelyactive%2Fnode-style-guide/lists"}