-
Notifications
You must be signed in to change notification settings - Fork 1
Module Style
The module structure I use for our projects is based on preferences developed over the years to go beyond Javascript's primitive "PascalCase for constructors, camelCase for everything else" conventions that stem from its toy-like origin.
Additionally:
- We are using the AirBNB ESLint rules, but have relaxed/overridden some; see our bundled
eslintrc.json
file. - The AirBNB ESLint are enforced using Prettier, and 'Format On Save' is our internal recommended default. For code that shouldn't be touched, use
// prettier-ignore
selectively as described here and/or disable ESLint entirely with/* eslint-disable */
at the top of the file. You can also modify/create the.prettierignore
file to tell Prettier what files to exclude. - While we allow a generous 120-character soft wrap, comments must fall within an 80-character limit.
- We are using EditorConfig to set "tabs as spaces, 2-space tab size, LF line endings" formatting standards.
We use capitalization conventions within our own code modules that are more similar to languages like C#.
- PascalCase for all functions, classes, and methods
- camelCase for object properties and local variables
We have additional suggested conventions for other types of symbols in our Javascript code to help keep different scopes and purposes straight that otherwise would be lost.
- Imported npm library instances are declared as PascalCase
- Our own internal LIBRARY objects are declared UPPERCASE and one word (no underscores)
- CONSTANTS are UPPERCASE_WITH_UNDERSCORES
- Function parameters are all short lowercase, and they are described in comments inside the function as they are assigned/used.
- Local declarations inside a function block use camelCase
- Module-wide static functions and variables use the
m_
prefix, and are cased according to previous rules. Classes are always PascalCase - We simulate "class-wide static functions and properties" by attaching to the class declaration, which is similar to C++ style languages. They are cased according to previous rules (e.g. MyClass.property or MyClass.MyStaticMethod).
- Nested function declarations ("function-in-a-function") use the
u_
(for "utility") prefix. - Class filenames are preceded with
class-
and the classname is PascalCase - React component filenames are also are PascalCase, but without the prefix
When choosing names, be short but also:
- Use words or phrases that can't be confused for a noun when it is a verb and vice versa
- Use appropriate and consistent tense
- For functions, reflect the type of action being performed, and indicate its return type
- Avoid passing long lists of parameters to functions (more than 3). Use an options object and name the properties descriptively.
Our conventions also use structures that are more similar to block-style C# code, eschewing Javascript object-style declaration so it's easier to copy/paste blocks of code without worrying about dangling commas.
It's also easier to see blocks of code function in our style, particularly when using the comment typography guidelines (see below). It's designed to be clear, easy-to-scan, and provide hints about variable scope. Scope in Javascript is historically awful and requires a firm understanding of its peculiarities, but this template provides a good start.
This is available as a Visual Studio Code snippet file
/*///////////////////////////////// ABOUT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*\
Dave.Sri Module Format Template
<your description here>
\*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ * /////////////////////////////////////*/
const DBG = true; // module-wide debug flag
/// LIBRARIES /////////////////////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const MyLibrary = require('./mylibrary');
const NpmPackage = require('npm-package');
const ClassName = require('./classes/class-name');
/// STATIC DECLARATIONS ///////////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const TYPE_CONSTANT_A = 'A';
let m_collection = []; // module-wide declaration, accessible everywhere
/// PRIVATE STATIC METHODS ////////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// this is a module-wide declaration, accessible everywhere
function m_Method() {
return 'hello';
}
/** Extended Comment Block ***************************************************\
For in-line documentation or longer explanations of key classes
No need to add/remove comment prefixes for each line. JUST WRITE.
\*****************************************************************************/
/// CLASS DECLARATION /////////////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
class MyClass {
/* for declaring classes, one per file */
/* remove if you're making a module (see below) */
constructor() {
this.propertyZ = 'Z'; // declare instance props
}
MyClassMethod() { // note use of PascalCase instead of JS convention
m_collection.push(this.propertyZ);
}
}
// static declarations
MyClass.StaticMethod = () => {
/* properties attached to class declaration are class-wide (static) */
/* and accessible by instances, but can not access instance vars (duh) */
};
MyClass.STATIC_CONSTANT = 'foo';
MyClass.staticProperty = 'bar';
/// PUBLIC METHODS ////////////////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const MODULE = {};
MODULE.propA = 'module property accessed with this or MOD';
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// Description of PublicA
MODULE.PublicA = () => {
console.log(MODULE.propA);
console.log(this.propA); // for advanced javascript devs
};
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// Description of PublicB
MODULE.PublicB = () => {
m_collection = [TYPE_CONSTANT_A, 'B', 'C'];
};
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// Description of PublicC
MODULE.PublicC = () => {
if (DBG) console.log(`m_Method says ${m_Method()}`);
};
/// EXPORTS ///////////////////////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
module.exports = MODULE;
/* or for classes */
module.exports = MyClass;
User Manual
Developer Manual
Installation
Setting Up End-User Projects
Deploying
- Deploy Electron
- Electron Code Signing README-signing.md
- Digital Ocean Deployment
- Updating MEME for 2021+
--
Coding Practices
Background
Design Notes
- Dev Insights
- Design Data Management
- Student Login
- Reference Build Differences
- Design Settings Manager
- Why Electron?
Deprecated