I can't use ES6 module with typescript in my Node.js project

132 Views Asked by At

I want to use both typescript and the es6 module in my Node.js project, and in addition, I want the files compiled to the javascript language to have the es6 module.

This is my package.json :

{
  "name": "arep",
  "version": "1.0.0",
  "description": "",
  "main": "app.ts",
  "type": "module",
  "scripts": {
    "start": "nodemon --exec ts-node app.ts",
    "build": "tsc"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^16.4.1",
    "express": "^4.18.2",
    "mysql2": "^3.9.1"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "@types/node": "^20.11.17",
    "nodemon": "^3.0.3",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3"
  }
}

And this is my tscongif.json :

{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

Here is the error I get :

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /home/rznkolds/Desktop/Standart/2- Development/2- Applications/1- NodeJS/arep/app.ts
    at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:160:9)
    at defaultGetFormat (node:internal/modules/esm/get_format:203:36)
    at defaultLoad (node:internal/modules/esm/load:141:22)
    at async nextLoad (node:internal/modules/esm/hooks:865:22)
    at async nextLoad (node:internal/modules/esm/hooks:865:22)
    at async Hooks.load (node:internal/modules/esm/hooks:448:20)
    at async handleMessage (node:internal/modules/esm/worker:196:18) {
  code: 'ERR_UNKNOWN_FILE_EXTENSION'
}

When I do this with the commonjs module, everything works fine, but when I do it with the es6 module, I get this error. I couldn't find much resources about this error. In many places, people solved the problem by turning it into the CommonJS module.

1

There are 1 best solutions below

1
Saiful Miqdar On

The error you're encountering is because Node.js does not natively support ES modules (ESM) as of version 14.x. This means that when you try to run a .ts file with the type set to "module" in your package.json, Node.js will throw an error because it doesn't know how to handle .ts files.

To resolve this issue, you have a few options:

  1. Use the esModuleInterop option in your tsconfig.json file. This will allow TypeScript to emit code that is compatible with both CommonJS and ESM. However, this might not be ideal if you want to strictly use ESM.

  2. Use the .mjs file extension for your TypeScript files. This tells Node.js to treat the file as an ESM module. You would need to update your package.json to point to the .mjs file:

    {
  "name": "arep",
  "version": "1.0.0",
  "description": "",
  "main": "app.mjs",
  "type": "module",
  "scripts": {
    "start": "nodemon --exec ts-node app.mjs",
    "build": "tsc"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "dotenv": "^16.4.1",
    "express": "^4.18.2",
    "mysql2": "^3.9.1"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "@types/node": "^20.11.17",
    "nodemon": "^3.0.3",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3"
  }
}
  1. Use the --esModuleInterop flag when running your TypeScript files with ts-node. This will enable the same interoperability as the esModuleInterop option in your tsconfig.json file.

  2. Upgrade to Node.js 16.x or later, which has experimental support for ES modules. You can enable this experimental feature by running Node.js with the --experimental-modules flag.

Personally, I would recommend using the .mjs file extension approach, as it most closely aligns with your goal of using ES modules in your Node.js project.