I'm currently trying to globally / permanently inject my own set of functions into the prototype of Node's IncomingMessage class. To do so, I came up with this abomination of code:
class RequestHelpers {
get ip() { return this.socket.remoteAddress; } //https://nodejs.org/api/net.html#net_socket_remoteaddress
foobar() { return this; }
get foobar2() { return "1"; }
}
const IncomingMessage = require("http").IncomingMessage;
RequestHelpers.prototype.__proto__ = IncomingMessage.prototype;
IncomingMessage.__proto__ = RequestHelpers;
IncomingMessage.prototype = RequestHelpers.prototype;
While this (seems to) work and does exactly what I need it to do (Makes it as tho IncomingMessage extends my RequestHelpers, which then extends whatever IncomingMessage originally extended) there seems to be some weird issue, and I'm wondering if it is something that can be ignored.
If I now send a HTTP request who'se request handler looks like the following (I am using Polka, which is a wrapper around the native HTTP server) and access it theres no issues at all:
index(req, res) {
res.end(JSON.stringify({ip: req.ip, foobar: req.foobar(), foobar2: req.foobar2}));
}
However, if I set a breakpoint at the res.end call and manually call any of my methods / access any of my getters in the console, I am being greeted with this message after resuming execution (Eventho they return the expected output):
(node:3348) [DEP0016] DeprecationWarning: 'GLOBAL' is deprecated, use 'global'
Just setting a breakpoint or inspecting the request object (While seeing my own methods in there) does not trigger the issue.
Iterating trough the object using Object.getPrototypeOf
yields the following output. As expected, my class is added right in the beginning. Why it is that it is now being presented as IncomingMessage
, I dont know.
Default:
IncomingMessage {_readableState: ReadableState, readable: true, _events: Object, _eventsCount: 1, _maxListeners: undefined, …}
Readable {setTimeout: , _read: , destroy: , _addHeaderLines: , _addHeaderLine: , …}
[...]
And with my hack:
IncomingMessage {_readableState: ReadableState, readable: true, _events: Object, _eventsCount: 1, _maxListeners: undefined, …}
IncomingMessage {constructor: , ip: <accessor>, foobar: , foobar2: <accessor>}
Readable {setTimeout: , _read: , destroy: , _addHeaderLines: , _addHeaderLine: , …}
[...]
Last off: Why am I even doing it like this?
The idea is to have a zero performance impact way to add my methods into the original class. Obviously I could alternatively pollute the original prototype and write my methods directly into it, but, at least to me, this seems like a better solution.
If somebody has an idea whats going on here I'd appreciate some input.