Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot build TS project when targeting Node16 or NodeNext #1589

Closed
Julien-Marcou opened this issue Sep 2, 2023 · 6 comments
Closed

Cannot build TS project when targeting Node16 or NodeNext #1589

Julien-Marcou opened this issue Sep 2, 2023 · 6 comments
Labels
needs investigation This issue needs further investigations
Milestone

Comments

@Julien-Marcou
Copy link

Julien-Marcou commented Sep 2, 2023

Describe the bug

When I build my Node.js + Typescript project, I get the following error:

npm run build

> test@0.0.0 build
> tsc

src/index.ts:1:20 - error TS1479: The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import("socket.io-client")' call instead.
  To convert this file to an ECMAScript module, change its file extension to '.mts', or add the field `"type": "module"` to '/home/jmarcou/dev/tarot-ai/package.json'.

1 import { io } from 'socket.io-client';
                     ~~~~~~~~~~~~~~~~~~


Found 1 error in src/index.ts:1

To Reproduce

Here is my project:

📂 test/
├── 📂 src/
│   └── 📄 index.ts
├── 📄 package.json
└── 📄 tsconfig.json

index.ts

import { io } from 'socket.io-client';
// nothing else, this is just the minimal repro we need

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "downlevelIteration": true,
    "target": "ES2022",
    "module": "Node16",
    "lib": [
      "ES2022",
      "DOM"
    ]
  },
  "include": [
    "src/**/*.ts"
  ]
}

package.json

{
  "name": "test",
  "version": "0.0.0",
  "scripts": {
    "build": "tsc"
  },
  "private": true,
  "dependencies": {
    "socket.io": "^4.7.2",
    "socket.io-client": "^4.7.2"
  },
  "devDependencies": {
    "@types/node": "^18.17.13",
    "typescript": "^5.2.2"
  }
}

Expected behavior

I expect to be able to import socket.io-client in the same manner as I can import socket.io.

When I import socket.io I don't have any problem:

import { Server } from 'socket.io';

Platform

  • WSL2 / Ubuntu 20.04
  • Node.js v18.17.1

Additional context

Now you might be wondering why am I importing socket.io-client on a Node.js script ?
Well because I want to connect to a socket.io server from my terminal ^^

I know I can switch the module setting in the tsconfig.json from Node16/NodeNext to CommonJS to fix this issue, but I think there might be a configuration problem in socket.io-client that is the root cause of this problem, so I'd rather wait for a proper fix rather than switching to CommonJS

@Julien-Marcou Julien-Marcou added the to triage Waiting to be triaged by a member of the team label Sep 2, 2023
@darrachequesne
Copy link
Member

Hi!

or add the field "type": "module" to '/home/jmarcou/dev/tarot-ai/package.json'.

I think you might be missing the "type": "module" in your package.json file, could you please check?

@darrachequesne darrachequesne added needs investigation This issue needs further investigations and removed to triage Waiting to be triaged by a member of the team labels Sep 13, 2023
@Julien-Marcou
Copy link
Author

Yes, it's a possible solution, but then I need to rewrite my entire project to be compatible with ESM, which is not the case at the moment.

For instance, all my imports doesn't specify the file extension, if I switch to "type": "module", then I need to fix all my imports.

Isn't socket.io-client supposed to behave as socket.io when imported on a Node.js project ?

@luisdeka
Copy link

waiting for this...

@tylerbutler
Copy link
Contributor

I think the root of the problem is that the exports field for the package doesn't define types for the CJS export. I think it should look more like this:

    ".": {
      "import": {
        "types": "./build/esm/index.d.ts",
        "node": "./build/esm-debug/index.js",
        "default": "./build/esm/index.js"
      },
      "require": {
        "types": "./build/cjs/index.d.ts",
        "default": "./build/cjs/index.js"
      }
    },

https://www.typescriptlang.org/docs/handbook/modules/reference.html#packagejson-exports

I think the types need to be duplicated, too, so that the CJS and ESM types have different paths. I found this somewhere in the Typescript docs but can't find it now, so I might be mistaken.

Patching the exports field manually worked in my project; I can open a PR if it is helpful.

@darrachequesne
Copy link
Member

This should be fixed by 605de78, included in version 4.7.3.

@tylerbutler could you please check?

@tylerbutler
Copy link
Contributor

This should be fixed by 605de78, included in version 4.7.3.

@tylerbutler could you please check?

Sorry for the delay. I confirmed 4.7.3 works for us, and I was able to remove our patched version. Thank you!

@darrachequesne darrachequesne added this to the 4.7.3 milestone Feb 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs investigation This issue needs further investigations
Projects
None yet
Development

No branches or pull requests

4 participants