pladaria / reconnecting-websocket

Reconnecting WebSocket. For Web, React Native, cli (Node.js)
MIT License
1.22k stars 197 forks source link

ReconnectingWebSocket is not a constructor #95

Closed bennycode closed 5 years ago

bennycode commented 5 years ago

I am trying to use the reconnecting-websocket library in a TypeScript project using Node.js module resolution. Compiling works but when starting the project I am always getting the following error:

TypeError: reconnecting_websocket_1.default is not a constructor

This is what my tsconfig.json looks like:

{
  "compilerOptions": {
    "lib": [
      "dom",
      "es6"
    ],
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "dist",
    "removeComments": true,
    "rootDir": "src",
    "strict": true,
    "target": "es5"
  },
  "exclude": [
    "dist",
    "node_modules"
  ]
}

And here is my demo code:

import ReconnectingWebSocket, {Options} from 'reconnecting-websocket';
import NodeWebSocket = require('ws');

const options: Options = {
  WebSocket: typeof window !== 'undefined' ? WebSocket : NodeWebSocket,
  connectionTimeout: 4000,
  debug: true,
  maxReconnectionDelay: 10000,
  maxRetries: Infinity,
  minReconnectionDelay: 4000,
  reconnectionDelayGrowFactor: 1.3,
};

function buildWebSocketURL(timestamp: number = Date.now()): string {
  return `wss://echo.websocket.org/?time=${timestamp}`;
}

const socket: ReconnectingWebSocket = new ReconnectingWebSocket(
  buildWebSocketURL,
  undefined,
  options
);

socket.onmessage = (event: MessageEvent): void => {
  console.log(`Response: ${event.data}`);
};

socket.onerror = (): void => {
  console.error('Ooops!');
};

socket.onopen = (): void => {
  console.log('WebSocket is alive!');
};

You can also try it yourself by cloning my repository and executing yarn start: https://github.com/bennyn/reconnecting-websocket-node

pladaria commented 5 years ago

Hi, try setting esModuleInterop to true in tsconfig.json

pladaria commented 5 years ago

Cloned your repo and updated tsconfig to enable esModuleInterop. Seems to work as expected:

yarn run v1.12.3
$ yarn dist && node ./dist/WebSocketClient.js
$ tsc
RWS> connect 0
RWS> next delay 4000
RWS> connect { url: 'wss://echo.websocket.org/?time=1543253270059',
  protocols: undefined }
RWS> addListeners
RWS> open event
WebSocket is alive!
RWS> accept open
bennycode commented 5 years ago

My demo will run when using "esModuleInterop": true but this introduces a whole set of new problems.

When using esModuleInterop, then you cannot extend EventEmitter and namespace-style imports (such as import * as logdown from 'logdown') will cause a failure at runtime.

I extended my example to showcase that: https://github.com/bennyn/reconnecting-websocket-node/commit/71c66c1675cb74d09f6ac784998d3e6f7de8012c

cgarrovillo commented 3 years ago

This is still an issue at 4.4.0. This project looks abandoned at this point

liuxin2533 commented 3 years ago

const ReconnectingWebSocket = require('reconnecting-websocket').default

cgarrovillo commented 3 years ago

const ReconnectingWebSocket = require('reconnecting-websocket').default

Not a constructor

That only fixes the types with a TSLint server on, but on runtime it throws the error

zhwei820 commented 1 year ago

solved in latest version

import ReconnectingWebSocket from "reconnecting-websocket"; // ok

however it will fail with require syntax.

var ReconnectingWebSocket = require("reconnecting-websocket"); // error