Node Express TS source somehow being read as JS

I’m trying to set up a minimal proof of concept of an express TS deployment, with the file structure

root
- api
  - index.ts
  - map.ts
- package.json
- tsconfig.json
etc.

Currently, I can deploy and run index.ts just fine, until it hits a relative import. Trying to import { app } from './map' (or ./map.ts) errors with Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/var/task/api/api/map.ts' imported from /var/task/api/api/index.js. Which led me to realize that all the TS files are being read as JS - changing the import to import { app } from './map.js' works just fine. What makes this even weirder is that I can check the source in the deployment and confirm that all the files are still TS files, despite being read otherwise.

This is a huge inconvenience to go through all my imports, and each one that I add down the line, to manually change the extension. So is there a reason this is happening that I can pinpoint, maybe in my tsconfig.json?

tsconfig.json

{
  "compilerOptions": {
    "lib": ["ES6"],
    "module": "ES6",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "allowJs": true,
    "outDir": "build",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitAny": true,
    "skipLibCheck": true,
    "declaration": true,
    "noEmit": true,
    "allowImportingTsExtensions": true
  },
  "ts-node": {
    "esm": true
  }
}

api/index.ts

import { app } from './map'; // fails with ./map, succeeds with ./map.js

export default app;

api/map.ts

import express from 'express';
const app = express();

app.get('/', (req, res) => {
  res.json({ message: 'Hello world' });
});

app.listen(3001, () => console.log('AAAA'));
export { app };

If you’re having trouble deploying an Express app, this guide can help.

You can also ask v0 for suggestions tailored to your own project setup.

Up front i did follow Using Express.js with Vercel to get a working single file express app, it’s the relative imports that are problematic here.

Solved - bit the bullet, migrated to node16 module resolution and disallowed ts extensions

1 Like

Thanks for coming back and sharing what worked for you!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.