moscajs / aedes

Barebone MQTT broker that can run on any stream server, the node way
MIT License
1.75k stars 228 forks source link

[bug] Aedes is undefined in Typescript #927

Closed benbai123 closed 6 months ago

benbai123 commented 6 months ago

System Information

Describe the bug Run official example, Aedes is undefined and got error TypeError: aedes_1.default is not a constructor

To Reproduce Steps to reproduce the behavior:

create 3 files below and run shell npm install && npm run start

{
  "scripts": {
    "start": "npx tsc --p ./tsconfig.json && node dist/main.js"
  },
  "devDependencies": {
    "typescript": "^5.3.3"
  },
  "dependencies": {
    "@types/node": "^20.10.7",
    "aedes": "^0.50.1"
  }
}
{
  "compilerOptions": {
    "rootDir": "src",
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false
  },
  "include": ["src/"],
}
import Aedes from 'aedes'
import { createServer } from 'net'

const port = 1883

const aedes = new Aedes()
const server = createServer(aedes.handle)

server.listen(port, function () {
  console.log('server started and listening on port ', port)
})

Expected behavior Should start a broker

Additional context

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const aedes_1 = require("aedes");
const net_1 = require("net");
const port = 1883;
const aedes = new aedes_1.default();
const server = (0, net_1.createServer)(aedes.handle);
server.listen(port, function () {
    console.log('server started and listening on port ', port);
});
//# sourceMappingURL=main.js.map
robertsLando commented 6 months ago

Does it works with 0.50.0? May be a regression introduced by #918 .

cc @hjdhjd

benbai123 commented 6 months ago

nope, tried 0.49.0 and 0.50.0, same error

robertsLando commented 6 months ago

Could you submit a PR to fix the issue?

hjdhjd commented 6 months ago

I don't think there is a PR needed here - the issue is with the compilation options the user is using, not the code itself.

Try using:

tsconfig.json:

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "declaration": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "lib": [
      "DOM",
      "ES2022"
    ],
    "module": "ES2022",
    "moduleResolution":"node",
    "outDir": "dist",
    "rootDir": "src",
    "sourceMap": true,
    "strict": true,
    "target": "ES2022"
  },
  "include": [
    "src"
  ]
}

Ensure package.json has "type": "module" in there as well.

@robertsLando I can confirm that everything is working as it should be with the existing release.

benbai123 commented 6 months ago

confirmed, need "type": "module" and 2 key compiler options.

{
  // ...
  "module": "ES2022",
  "moduleResolution":"node",
}

btw, the compiler options I used before are copied from NestJS

benbai123 commented 6 months ago

tried run Aedes with NestJS, failed as expected.

workaround for NestJS :

import * as Aedes from 'aedes'
import { createServer } from 'net'

const port = 1883

const aedes = Aedes.createBroker()
const server = createServer(aedes.handle)

server.listen(port, function () {
  console.log('server started and listening on port ', port)
})

found another ts compiler option "esModuleInterop": true working with NestJS, but probably will break some other packages like jwks-rsa raw-body

robertsLando commented 6 months ago

Ensure package.json has "type": "module" in there as well.

@hjdhjd So it only works with ESM now? Does it always require type module??