Node.js gems
Enjoy the content
I have been watching some videos regarding Node.js in the past, and as usual, i've been taking notes during the lectures. This article consists of most of my notes and aims to inform you about some features that will be probably useful to you and your team when developing apps in Node.
Timing a function (Async events)
There are numerous times throughout the software development lifecycle where the developer wants to test how fast the code runs.
You just saw the word fast, so you're probably thinking about algorithmic complexity and big O's, but chill... this is an actual
timer implementation that tells you how many seconds the function takes in order to complete. I'm using node's built in EventEmitter
class so we can handle events like begin
, end
and data
.
// Bring in what we need
const fs = require('fs');
const EventEmitter = require('events');
// Create a custom 'Class' that extends the existing functionality of the EventEmitter 'Class'
class WithTime extends EventEmitter {
execute(asyncFunc, ...args) {
console.time('execute'); // Begin timing
this.emit('begin'); // Emit the 'begin' event which is handled below
// Run the actual func with possible arguments passed
asyncFunc(...args, (err, data) => {
if (err) {
return this.emit('error', err);
}
this.emit('data', data);
console.timeEnd('execute');
this.emit('end');
});
}
}
const withTime = new WithTime();
withTime.on('begin', () => console.log('About to execute'));
withTime.on('end', () => console.log('Done with execute'));
// Execute read file to the current directory
withTime.execute(fs.readFile, __filename);
Add console logs to a function execution (Sync events)
Same as above, but console logs.
const EventEmitter = require('events');
class WithLog extends EventEmitter {
execute(taskFunc) {
console.log('Before executing');
this.emit('begin');
taskFunc();
this.emit('end');
console.log('After executing');
}
}
const withLog = new WithLog();
withLog.on('begin', () => console.log('About to execute'));
withLog.on('end', () => console.log('Done with execute'));
withLog.execute(() => console.log('*** Executing task ***'));
Simple http server without any libraries (HTTP)
Yeah, I know a guy that uses Express.js
for literaly everything, but when it comes to simple things, node's built in http
package can do the job just as good.
const server = require('http').createServer();
server.on('request', (req, res) => {
res.writeHead(200, {'content-type':'text/plain'});
res.write('Connection is still alive');
setTimeout(function(){
res.write('SUP BRO');
}, 1000);
// Ends connection
res.end('Hello world');
});
server.listen(8000);
Simple http server without any libraries (HTTPS)
For secure connections to the web, you need an SSL certificate. You can generate one using the openssl CLI like below.
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -nodes
const fs = require('fs');
const server = require('https')
.createServer({
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
});
server.on('request', (req, res) => {
res.writeHead(200, {'content-type':'text/plain'});
res.write('Connection is still alive');
setTimeout(function(){
res.write('SUP BRO');
}, 1000);
// Ends connection
res.end('Hello world');
});
server.listen(443);
TCP port 443 is the standard TCP port that is used for website which use SSL. When you go to a website which uses the https at the beginning you are connecting to port 443. You should not use a different port number, because if you do then your users will need to enter the port number in the URL.
Allocating data to a buffer
I don't know how this is going to be useful to you, but it's a note so i'm dropping it here like it's hot 🔥.
// Allocates 1024 bytes buffer without initializing it
let buff = Buffer.allocUnsafe(1024).toString();
// Binary data
console.log(buff);
// Example
const string = 'tuna';
const buffer = Buffer.from('tuna');
console.log(string, string.length); // tuna 4
console.log(buffer, buffer.length); // <Buffer 74 75 6e 61> 4
Node process handling.
During the process lifecycle, many events occur, and you might
want to handle each event accordingly. Well Node.js lets you do
that with process.on(event, callback)
.
process.on('exit', (code) => {
// Do one final synchronous operation
// before the node process terminates
console.log(`About to exit with code: ${code}`);
});
process.on('uncaughtException', (err) => {
// Something went really wrong, cleanup & exit
console.error(err);
process.exit(1);
});
// Keep the event loop busy
process.stdin.resume();
// Trigger a TypeError
console.doge();