Unable to run built/transpiled Typescript applications with Node – Tsc x Babel

My question is about a problem that I’m actually facing but I think I’m still missing some concepts about transpiling Typescript into Javascript. Basically what I’m planning to do in my application is to develop it using Typescript, build it to Javascript and run it with PM2. It’s an application used for studies purposes only. Repository

I guess the main problem here is ES modules over CommonJS.

In my application I’ve set up a base directory in tsconfig.json so my imports look like this:

import SignUp from "src/application/services/signup";
import UserRepository from "src/infra/repositories/account-repository";
import PasswordHasher from "src/infra/security/hasher";
import SignUpController from "src/presentation/controllers/sign-up-controller";

export default class SignUpFactory {
  static makeUseCase(): SignUp {
    const userRepository = new UserRepository();
    return new SignUp(userRepository, new PasswordHasher());
  }

  static makeController(): SignUpController {
    return new SignUpController(this.makeUseCase());
  }
}

Basically my imports are all set up to an absolute path.

When I transpile the project, it turns to keep the absolute paths:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _signup = _interopRequireDefault(require("src/application/services/signup"));
var _accountRepository = _interopRequireDefault(require("src/infra/repositories/account-repository"));
var _hasher = _interopRequireDefault(require("src/infra/security/hasher"));
var _signUpController = _interopRequireDefault(require("src/presentation/controllers/sign-up-controller"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
class SignUpFactory {
  static makeUseCase() {
    const userRepository = new _accountRepository.default();
    return new _signup.default(userRepository, new _hasher.default());
  }
  static makeController() {
    return new _signUpController.default(this.makeUseCase());
  }
}
exports.default = SignUpFactory;

And when running using node dist/server.js it gives me an error telling me the modules weren’t found.

node:internal/modules/cjs/loader:1148
  throw err;
  ^

Error: Cannot find module 'src/application/services/get-account'
Require stack:
- /home/gabriel/PROJETOS/LEARNING/branas-io/account/dist/main/factories/get-account-factory.js
- /home/gabriel/PROJETOS/LEARNING/branas-io/account/dist/main/app/routes.js
- /home/gabriel/PROJETOS/LEARNING/branas-io/account/dist/main/app/app.js
- /home/gabriel/PROJETOS/LEARNING/branas-io/account/dist/server.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1145:15)
    at Module._load (node:internal/modules/cjs/loader:986:27)
    at Module.require (node:internal/modules/cjs/loader:1233:19)
    at require (node:internal/modules/helpers:179:18)
    at Object.<anonymous> (/home/gabriel/PROJETOS/LEARNING/branas-io/account/dist/main/factories/get-account-factory.js:7:42)
    at Module._compile (node:internal/modules/cjs/loader:1358:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
    at Module.load (node:internal/modules/cjs/loader:1208:32)
    at Module._load (node:internal/modules/cjs/loader:1024:12)
    at Module.require (node:internal/modules/cjs/loader:1233:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/gabriel/PROJETOS/LEARNING/branas-io/account/dist/main/factories/get-account-factory.js',
    '/home/gabriel/PROJETOS/LEARNING/branas-io/account/dist/main/app/routes.js',
    '/home/gabriel/PROJETOS/LEARNING/branas-io/account/dist/main/app/app.js',
    '/home/gabriel/PROJETOS/LEARNING/branas-io/account/dist/server.js'
  ]
}

Node.js v20.14.0

I tried to use the default tsc transpiler and Babel but both ways I get the same result.

babel.config.json

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "current"
        }
      }
    ],
    "@babel/preset-typescript"
  ],
  "plugins": [
    [
      "module-resolver",
      {
        "root": [
          "./src"
        ]
      }
    ]
  ],
  "ignore": [
    "**/*.spec.ts"
  ]
}

tsconfig.json

{
  "compilerOptions": {
    "lib": [
      "ESNext",
      "DOM"
    ],
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Node",
    "moduleDetection": "force",
    "esModuleInterop": true,
    "allowJs": true,
    "jsx": "react-jsx",
    "verbatimModuleSyntax": false,
    "baseUrl": ".",
    "rootDir": "./src",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "types": [
      "vitest/globals"
    ],
    "outDir": "dist",
    "removeComments": false,
  },
  "include": [
    "src/**/*.ts",
  ],
  "exclude": [
    "node_modules",
    "dist",
    "tests",
    "vitest.config.ts",
  ]
}

I’m looking for a solution but if you have some references on ESModules and CommonJS in Typescript transpilation I appreciate it.

Well, I expected my built application running either with node or pm2. I’m planning to run this process in a Docker container so I can keep on developing and running automated tests in other microservices from the whole project.

As I said before I tried to build it using tsc and babel but got the same error in both.