This is a simple wrapper to enable the use of async route handlers in express:
const wrapAsyncHandler = (fn) => {
return (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
}
}To use it:
app.get('/some/url', wrapAsync(async(req, res) => {
try {
const ret = await someAsyncOperation(req.query.param1, req.query.param2);
return res.send({ success: true, result: ret });
} catch(err) {
console.log('Error: ', err);
return res.send({ success: false, error: err });
}
}));const protectedHandler = (req, res, next) => {
const tok = getToken(req);
if (!tok || !verifyToken(tok)) {
return res.send({ success: false, error: 'Invalid auth' });
}
// Set some protected value if needed
res.locals.protectedResourceId = ...
return next();
}const recordElapsedTime = (req, res, next) => {
const timeStart = process.hrtime();
res.on('finish', () => {
const elapsedTime = process.hrtime(timeStart);
const elapsedTimeMs = elapsedTime[0] * 1000 + elapsedTime[1] / 1e6;
console.log(`Elapsed time for ${req.path} = ${elapsedTimeMs}`);
});
next();
}
app.use(recordElapsedTime);const EventEmitter = require('events');
let ee = new EventEmitter();
ee.on('some-event', () => {
console.log('Event handler 1');
});
ee.on('some-event', () => {
console.log('Event handler 2');
});
ee.on('some-event', (param1) => {
console.log('Event handler 3, param1: ', param1);
});
ee.emit('some-event', 'This is param1');const EventEmitter = require('events');
class SomeHandler extends EventEmitter {
// ...
}
let someHandler = new SomeHandler();
someHandler.on('handle-event', (param1) => {
console.log('On handle-event, param1: ', param1);
});
someHandler.emit('handle-event', someParam);Wrap the handler in setImmediate:
someHandler.on('handle-event', (param1) => {
setImmediate(() => console.log('On handle-event async, param1: ', param1));
});For CPU-intensive work, not IO-bound work.
const { Worker } = require('worker_threads');
// Instantiate from a file
const aWorker = new Worker('some_file.js');
// Load directly via eval
const anotherWorker = new Worker(`
console.log('anotherWorker worker thread');
`, { eval: true });const { Worker, isMainThread } = require('worker_threads');
if (isMainThread) {
const aWorker = new Worker(__filename);
// Do main thread work
// ...
} else {
console.log('aWorker worker thread');
// ...
}const { Worker, isMainThread, workerData } = require('worker_threads');
if (isMainThread) {
const aWorker = new Worker(__filename, {
workerData: {
someData: 'Something',
moreData: 42,
}
});
// ...
} else {
console.log('aWorker worker thread');
console.log('someData: ', workerData.someData);
// ...
}const { Worker, isMainThread, parentPort } = require('worker_threads');
if (isMainThread) {
const aWorker = new Worker(__filename);
aWorker.on('message', (msg) => {
console.log('aWorker posted: ', msg);
});
// ...
aWorker.postMessage('Hello from the main thread.');
} else {
parentPort.on('message', (msg) => {
console.log('Parent posted: ', msg);
});
parentPort.postMessage('aWorker starting.');
// ...
parentPort.postMessage('aWorker completed.');
}Sometimes it's useful to export some values that reference each other, for
example components of URLs. Components like prototypes and hostnames can be
defined, and then those can be used to build multiple URLs. This can be done
with Object.freeze and defining accessors with get:
module.exports = Object.freeze({
PROTO: 'https',
HOST: 'example.com',
PARAM: 'foo',
get URL1() { return `${this.PROTO}://${this.HOST}/path/to/something` },
get URL2() { return `${this.PROTO}://${this.HOST}/another/path/?param=${this.PARAM}` },
});Error: Unsupported platform for fsevents
fsevents is a darwin-specific lib. To get around this, install with the force
flag:
npm i -fIt's annoying that npm audit doesn't have an option for only displaying high or critical vulnerabilities. It does have an option for failing the audit if a given level of vulnerability is found, but it happily returns all the issues found. That's not useful for triage.
For example:
npm audit --audit-level=critical
found 907 vulnerabilities (888 low, 18 moderate, 1 high) in 1866 scanned packages
run `npm audit fix` to fix 592 of them.
315 vulnerabilities require manual review. See the full report for details.To display only high and critical vulnerabilities:
npm audit | grep -E "(High | Critical)" -B3 -A10
# Run npm update http-proxy --depth 4 to resolve 1 vulnerability
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High │ Denial of Service │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package │ http-proxy │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ react-scripts │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path │ react-scripts > webpack-dev-server > http-proxy-middleware > │
│ │ http-proxy │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info │ https://npmjs.com/advisories/1486 │
└───────────────┴──────────────────────────────────────────────────────────────┘node --inspect-brk node_modules/.bin/jest --runInBandThen open Chrome/Chromium, enter chrome://inspect, and click Open Dedicated DevTools for Node. Then resume the debugger, which is automatically paused at a
breakpoint.
If you have an async activity to setup in beforeEach, you can either use the done parameter, or return a value from beforeEach:
beforeEach(async () => {
const someObj = await anActivity();
return someObj;
});Sometimes you might have tests you want to run in a file that doesn't match Jest's default test regex pattern (perhaps because it's not in the test/ directory. You can work around this by specifying a pattern that matches the file you want to run. For example, if you have a file called some-tests.js in your project's root that you want to run, you can do that with:
jest --testRegex=some-tests ./some-tests.js