//area.js
var PI = Math.PI;
function circle (radius) {
return radius * radius * PI;
}
module.exports.circle = circle;
var areaCalc = require('./area');
console.log(areaCalc.circle(5));
// MyFancyObservable.js
var util = require('util');
var EventEmitter = require('events').EventEmitter;
function MyFancyObservable() {
EventEmitter.call(this);
}
util.inherits(MyFancyObservable, EventEmitter);
MyFancyObservable.prototype.hello = function (name) {
this.emit('hello', name);
};
var MyFancyObservable = require('MyFancyObservable');
var observable = new MyFancyObservable();
observable.on('hello', function (name) {
console.log(name);
});
observable.hello('john');
function MyClass (options) {
this.options = options;
}
function create(options) {
// modify the options here if you want
return new MyClass(options);
}
module.exports.create = create;
function userModel (options) {
var db;
if (!options.db) {
throw new Error('Options.db is required');
}
db = options.db;
return {
create: function (done) {
db.query('INSERT ...', done);
}
}
}
module.exports = userModel;
var db = require('./db');
var userModel = require('User')({
db: db
});
Dependency injection is a software design pattern in which one or more dependencies (or services) are injected, or passed by reference, into a dependent object.
Dependency injection is really helpful when it comes to testing. You can easily mock your modules' dependencies using this pattern.
var db = require('db');
// do some init here, or connect
db.init();
var userModel = require('User')({
db: db
});
userModel.create(function (err, user) {
});
var test = require('tape');
var userModel = require('User');
test('it creates a user with id', function (t) {
var user = {
id: 1
};
var fakeDb = {
query: function (done) {
done(null, user);
}
}
userModel({
db: fakeDb
}).create(function (err, user) {
t.equal(user.id, 1, 'User id should match');
t.end();
})
});
function userModel (options) {
var db;
if (!options.db) {
throw new Error('Options.db is required');
}
db = options.db;
return {
create: function (done) {
db.query('INSERT ...', done);
}
}
}
module.exports = userModel;
In the example above we have two different dbs. In the index.js file we have the “real” db module, while in the second we simply create a fake one. This way we made it really easy to inject fake dependencies into the modules we want to test.
app.use = function(fn){
this.middleware.push(fn);
return this;
};
So basically when you add a middleware it just gets pushed into a middleware array. So far so good, but what happens when a request hits the server? code> var i = middleware.length; while (i–) {
next = middleware[i].call(this, next);
} </code>
process.stdin.on('readable', function () {
var buf = process.stdin.read(3);
console.dir(buf);
process.stdin.read(0);
});
$ (echo abc; sleep 1; echo def; sleep 1; echo ghi) | node consume2.js <Buffer 61 62 63> <Buffer 0a 64 65> <Buffer 66 0a 67> <Buffer 68 69 0a>
Your code uses require to include modules. Modules use exports to make things available.
Named exports - one module, many exported things. Anonymous exports - simpler client interface.
// foo.js
foo = function () {
console.log('foo!');
}
// app.js
require('./foo.js');
foo();
// bar.js
module.exports = function () {
console.log('bar!');
}
// app.js
var bar = require('./bar.js');
bar();
// fiz.js
exports.fiz = function () {
console.log('fiz!');
}
// app.js
var fiz = require('./fiz.js').fiz;
fiz();
// buz.js
var Buz = function () {};
Buz.prototype.log = function () {
console.log('buz!');
};
module.exports = new Buz();
// app.js
var buz = require('./buz.js');
buz.log();
// baz.js
var Baz = function () {};
Baz.prototype.log = function () {
console.log('baz!');
};
exports.Baz = new Baz();
// app.js
var baz = require('./baz.js').Baz;
baz.log();
// doo.js
var Doo = function () {};
Doo.prototype.log = function () {
console.log('doo!');
}
module.exports = Doo;
// app.js
var Doo = require('./doo.js');
var doo = new Doo();
doo.log();
// qux.js
var Qux = function () {};
Qux.prototype.log = function () {
console.log('baz!');
};
exports.Qux = Qux;
// app.js
var Qux = require('./qux.js').Qux;
var qux = new Qux();
qux.log();
Modules should expose an error-first callback interface.
The next example checks, if an Error happened during the execution. You should always check for them.
function readJSON(filePath, callback) {
fs.readFile(filePath, function(err, data) {
var parsedJson;
// Handle error
if (err) {
return callback(err);
}
// Parse JSON
try {
parsedJson = JSON.parse(data);
} catch (exception) {
return callback(exception);
}
// Everything is ok
return callback(null, parsedJson);
});
}
Try to avoid this and new. Node involves passing around lots of callbacks, and heavy use of higher-level functions to manage control flow. Using a functional style will save you a lot of trouble. Of course, there are some cases, when prototypes can be more efficient, but if possible, try to avoid them.
Start a new project with npm init. The init command helps you create the application's package.json file. It sets some defaults, which can be later modified. Start writing your fancy new application should begin with:
mkdir my-awesome-new-project cd my-awesome-new-project npm init
Specify a start and test script. In your package.json file you can set scripts under the scripts section. By default, npm init generates two, start and test. These can be run with npm start and npm test. Also, as a bonus point: you can define custom scripts here and can be invoked with npm run-script <SCRIPT_NAME>. Note, that NPM will set up $PATH to look in node_modules/.bin for executables. This helps avoid global installs of NPM modules.
Production/staging deployments should be done with environment variables. The most common way to do this is to set the NODE_ENV variable to either production or staging. Depending on your environment variable, you can load your configuration, with modules like nconf. Of course, you can use other environment variables in your Node.js applications with process.env, which is an object that contains the user environment.
You can use JSCS, which is a code style checker for JS, you can add it:
npm install jscs --save-dev
The very next step you have to make is to enable it from the package.json file by adding a custom script:
scripts: {
"jscs": "jscs index.js"
}
Prefer JS over JSON for configuration files. Something like this:
var url = require('url');
var config = module.exports = {};
var redisToGoConfig;
config.server = {
host: '0.0.0.0',
port: process.env.PORT || 3000
};
// look, a comment in the config file!
// would be tricky in a JSON ;)
config.redis = {
host: 'localhost',
port: 6379,
options: {
}
};
if (process.env.REDISTOGO_URL) {
redisToGoConfig = url.parse(process.env.REDISTOGO_URL);
config.redis.port = redisToGoConfig.port;
config.redis.host = redisToGoConfig.hostname;
config.redis.options.auth_pass = redisToGoConfig.auth.split(':')[1];
}