This guide should give an overview of the general style within the alinex system and it's packages. It is neither meant as a hard limit but neither as some nice to have rules. So as much as possible this rules have to be followed.
Within the code I use 2 spaces for indention neither tabs because they make reading problematic and also are not suited for coffee script if mixed with spaces.
Over all modules some common variable names will be used for the same values:
cb- for the callback method
done- alternatively used for the callback for better reading
error- for an error message object
Classes start with an Uppercase letter:
test = new Test
To mark private properties/functions they may start with an underscore.
Modules are always imported into a variable which is named after the module and if the module exports a class the uppercase name is used.
Generally required modules belong on top of the file. But all things which will be required at the top will immediately load and slow down the initialization. Often some of these requirements won't be needed in every call. So it is better to load them dynamically then needed.
To optimize readability the variables for dynamically loaded requirement will be set on top and the real requirement can be put anywhere in the code.
Classes and Instances¶
Classes are written starting with uppercase letter while it's instances start with lowercase letters.
They are used seldom but if so you have to name it completely in uppercase with underscores for word separator.
Through the whole code as much as possible only asynchronous code should be used without blocking. That brings the most performance out.
These code follows the node.js convention of providing a single callback as the last argument of your asynchronous function.
To not make it too complex the async function may call it's callback synchronously
in the same event loop or later. It is no true asynchronity by definition, so
if you need it maybe think about your code structure or call the function
You may also use the Async module. It brings you a lot of methods to make asynchronous calls parallel or serial.
Often events are also used to make use of the asynchronous behavior in class objects.
- Synchronous code will return an Error object instead of the normal return value:
myfuncSync = () -> x = doSomething() if x is 1 return new Error "Failed calculation" return x result = myfuncSync() if result instanceof Error console.error result.message
- Asynchronous code should send the error as first parameter to the callback
nullif no error occurred:
myfunc = (cb) -> x = doSomething() if x is 1 cb new Error "Failed calculation" else cb null, x myfunc (err, result) -> if err console.error err.message
And at last an error may be thrown only if it is a hard error which signals an fatal error which may stop the overall process.
Such an error may be catched in a try block, in a domain or on the process.
Another solution is to use eventful methods which emit an
Read more in the errorHandler documentation.
To make the code more readable and prevent some hanging else-statements which you have to search to which indention level it belongs to return or callback as fast as possible.
if err doSomething (err) -> return cb err else return true
return true unless err doSomething (err) -> return cb err
All the code in any language will be documented inline using comments as possible in the specific language. No JavaDoc or alike have to be used. Only plain markup which will be automatically detected and converted to documentation.
In each exported method the parameters will be documented in detail and the callback methods with their values, they will get.
Some overall documentation like this will be stored in special markup files
Best use the node-inspector for this:
sudo npm install -g node-inspector node-inspector node --debug-brk lib/cli.js -v
But additionally the
debug package is used in all packages to make it possible
to debug any time, also in the production code to get more information.
debug = require('debug') 'mypack' debug "the system is running"
You instantiate a new debug instance after requiring it with a name. This should
be your package name (for the main part). For subparts of your package add a colon
with a specifier like
If you run the code above normally nothing will happen but if you set the
environment variable like:
DEBUG=mypack node lib/index.js
You will get the debug output. You can add multiple debug packages with colon or
use asterisk like
mypack* to select the package with all sub level.
You can also add multiple debug statements and exclude some:
Linting is used to pre-check the code. This will not only check the syntax but also the style and the above conventions of the styleguide.
Mocha unit tests are used to check individual parts and the overall functionality. As much as possible should be tested but not only single units but all interface calls. An test coverage of 100% should be the goal.
If used the builder will call them
builder -c test for you.
To publish new packages the following steps should be done:
- Check dependencies and their version in package.json (maybe run
- Cleanup to remove test packages
- Install and update packages
- Run the test suite
- Push code to repository
- Publish new package
- Create and publish new documentation
The tasks are done in an easy way using the alinex-builder.
# check what is changed and if all packages are up-to-date builder -c changes # do the steps 1-7 builder -c publish --minor
The general configuration is stored in files to be also available without database connection. To make it easy readable and maintainable it should be written in YAML rather than JSON.
alinex-config helps in working with such files.
To use singleton modules the dependencies for specific versions should be as open as possible. This makes it possible to use:
This will flatten down the modules to the uppermost common module in hierarchy.
Peer dependencies are also possible, in which a sub module specifies which
parent it needs. This will be specified in the