Use Node.js 15 native `EventTarget` object
See original GitHub issue- I’ve searched for any related issues and avoided creating a duplicate issue.
Description
Node.js 15 already provides a native implementation of EventTarget
, so there’s no need to use our own implementation. In fact, using both of them at the same time leads to errors.
In my use case, I’ve created a Client
class that extends from Node.js native EventTarget
class, that internally it’s using an ws
instance (and doing some other project specific things), and setting as listeners methods from this Client
class, with the idea of propagate these errors to the user:
export class Client extends EventTarget
{
constructor(ws)
{
super()
if(!(ws instanceof WebSocket)) ws = new WebSocket(ws)
ws.binaryType = 'arraybuffer'
ws.addEventListener('close', this.#onClose, {once: true})
ws.addEventListener('error', this.#onError)
ws.addEventListener('message', this.#onMessage)
ws.addEventListener('open', this.#onOpen, {once: true})
this.#ws = ws
}
#onClose = this.dispatchEvent.bind(this)
#onError = this.dispatchEvent.bind(this)
#onOpen = this.dispatchEvent.bind(this)
}
Problem is, since ws
is using its own implementation of both EventTarget
and Event
classes, when these events gets propagated to the native one, I get the next error:
TypeError [ERR_INVALID_ARG_TYPE]: The "event" argument must be an instance of Event. Received an instance of ErrorEvent
at new NodeError (node:internal/errors:277:15)
at EventTarget.dispatchEvent (node:internal/event_target:326:13)
at WebSocket.onError (/home/piranna/Trabajo/Atos/awrtc_signaling/node_modules/ws/lib/event-target.js:141:16)
at WebSocket.emit (node:events:329:20)
at WebSocket.EventEmitter.emit (node:domain:467:12)
at ClientRequest.<anonymous> (/home/piranna/Trabajo/Atos/awrtc_signaling/node_modules/ws/lib/websocket.js:579:15)
at ClientRequest.emit (node:events:329:20)
at ClientRequest.EventEmitter.emit (node:domain:467:12)
at TLSSocket.socketErrorListener (node:_http_client:478:9)
at TLSSocket.emit (node:events:329:20) {
code: 'ERR_INVALID_ARG_TYPE'
}
This is due because Node.js native EventTarget
class is expecting a native Event
class instance, instead of the one provided by ws
. According to Node.js docs it should be accepting any object with a type
field, but for some reason is not accepting it.
Reproducible in:
- version: 7.4.0
- Node.js version(s): 15.2.0
- OS version(s): Ubuntu 20.10
Steps to reproduce:
- use Node.js 15
- create an object instance with Node.js 15 native
EventTarget
class in its prototype chain - create a
ws
instance and call toaddEventListener
setting one function that propagate the event to the nativeEventTarget
- emit the event
- BOOM
Expected result:
ws
should check for actual support of both Event
and EventTarget
classes in the native platform (in this case, Node.js 15) and use them. In case they are not available, then use its own implementation as a polyfill.
Actual result:
ws
is using always its own implementation of Event
and EventTarget
classes, since there was none before, so now it conflicts with the new Node.js native available ones.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:7
- Comments:34 (14 by maintainers)
What spec? 👀
This is how it works in the browser and how I’m used to it:
I prefer to keep making
WebSocket
inherit fromEventEmitter
for now.Advantages:
WebSocket
class is always anEventEmitter
and the documentation is the same in all supported Node.js versions.Disadvantages:
ws
EventTarget
implementation and the Node.jsEventTarget
implementation.That said, I think making
WebSocket
inherit fromNodeEventTarget
is something worth exploring.