stomp-js / stompjs

Javascript and Typescript Stomp client for Web browsers and node.js apps
Apache License 2.0
763 stars 81 forks source link

Compatibility with Typescript 4.7 #452

Closed dargmuesli closed 1 year ago

dargmuesli commented 2 years ago

Trying to use Typescript 4.7 with the attached tsconfig yields the following error:

import { Client } from '@stomp/stompjs';
         ^^^^^^
SyntaxError: Named export 'Client' not found. The requested module '@stomp/stompjs' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@stomp/stompjs';
const { Client } = pkg;
{
    "compilerOptions": {
        "esModuleInterop": true,
        "module": "es2022",
        "target": "es2022",
        "moduleResolution": "node",
        "outDir": "dist",
        "strict": true
    },
    "include": [
        "./src/**/*"
    ],
    "ts-node": {
        "esm": true
    }
}

What can I do about it?

kum-deepak commented 2 years ago

The current version is released as es2015 (https://github.com/stomp-js/stompjs/blob/develop/tsconfig.json#L5). Please verify that you are using the latest version before I dig deeper.

dargmuesli commented 2 years ago

I've created a minimal reproduction: https://github.com/dargmuesli/stompjs-demo Trying to execute yarn dev yields the given error. Is it related to nodemon?

The commands yarn build and yarn lint run fine however.

kum-deepak commented 2 years ago

I tried your project. What I can figure out:

Digging deeper, the issue does not seem to be with Typescript compilation but with node's ability to execute the compiled output.

Further experimenting, when I instruct typescript to generate UMD as output instead of es2022 the error goes away.

So, I will suggest focusing on running the generated code with Node - by using node on command line. Following which switching to ts-node or nodemon

kum-deepak commented 2 years ago

For reference the tsconfig that works:

{
    "compilerOptions": {
        "esModuleInterop": true,
        "module": "UMD",
        "target": "es2022",
        "moduleResolution": "node",
        "outDir": "dist",
        "strict": true
    },
    "include": [
        "./src/**/*"
    ],
    "ts-node": {
        "esm": true
    }
}
dargmuesli commented 2 years ago

Ok! Sadly I currently cannot use UMD module output as that does not allow to use import.meta.url, which I need because I use NODE_OPTIONS=--experimental-vm-modules for esm jest tests. I think using NodeNext module output might be a solution, but that throws an unexpected error for which a bug ticket already exists: https://github.com/microsoft/TypeScript/issues/49842 All this makes heads spin! :joy:

kum-deepak commented 2 years ago

In such cases in the past, I used the library in the source code form - by using the original .ts files and compiling these along with my project code.

For similar reasons, the Angular version of this library was distributed as source for quite a while.

dargmuesli commented 2 years ago

How would I give the instruction to import or compile typescript files from a dependency that would resolve to the built output by default?

Polve commented 2 years ago

I have the same problem! Is it possible to publish the library as an ESM module?

kum-deepak commented 2 years ago

This package is distributed as UMD and ESM. NodeJS does not honor the module key in package.json. Ref https://nodejs.org/api/packages.html#packages_exports and https://nodejs.org/api/packages.html#dual-commonjses-module-packages

kum-deepak commented 1 year ago

The latest develop branch exports modules. It will be released as a beta soon. It will be worth testing with that.

dargmuesli commented 1 year ago

I receive many errors like

node_modules/.pnpm/@stomp+stompjs@7.0.0-beta1/node_modules/@stomp/stompjs/esm6/index.d.ts:1:15 - error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './client.js'?

So it appears that the module code is not compatible with nodenext yet.

kum-deepak commented 1 year ago

I think it needs more changes. I will fix it shortly.

kum-deepak commented 1 year ago

Tested with the recently released beta2. I needed to add WebSocket polyfill, and it worked for me (I checked out the project you had shared earlier).

$ yarn add ws @types/ws @stomp/stompjs@7.0.0-beta2

The test file:

import { Client } from '@stomp/stompjs';
import { WebSocket } from 'ws';

Object.assign(global, { WebSocket});

const client = new Client({
  brokerURL: 'ws://localhost:15674/ws',
  debug: console.log,
  onConnect: () => {
    client.subscribe('/topic/test01', message => console.log(`Received: ${message.body}`));
    client.publish({destination: '/topic/test01', body: 'First Message'});
  }
});

client.activate();
dargmuesli commented 1 year ago

It indeed does work for me now! Thank you :) Let's close this issue once v7 is not beta anymore. What else do you plan for v7?

kum-deepak commented 1 year ago

All the items intended for 7.0 has been completed. Please see https://github.com/stomp-js/stompjs/blob/develop/Change-log.md

The module system change caused tooling breakage, including the bundler and test setup. So, it might cause breakages for others as well.

So, waiting for a few reports before pushing it to 7.0.

kum-deepak commented 1 year ago

Released 7.0,0