-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Hey there! First off, thanks for this awesome tool—it's been a huge time-saver! 🙌
I recently migrated a TypeScript project to ESM and used ts2esm to correctly add .js extensions in imports. While it worked well overall, I ran into a few challenges that I think could improve the tool even further.
1️⃣ Partial Support for tsconfig Paths
I saw that tsconfig path support works to some extent, but I had issues in an Nx monorepo with /apps/* and /libs/*. These are linked using tsconfig paths, and ts2esm only resolved the imports correctly after I moved libs inside an apps folder. My workaround looked like this:
- Move
libs/*intoapps/myapp/libs/* - Update
tsconfig.jsonpaths accordingly - Run
ts2esm - Move
libsback to their original location - Repeat for each app
If ts2esm could resolve paths of aliases outside the current project dir, that would be amazing!
2️⃣ Handling Package Exports and Subpath Imports
My project had a mix of modern packages (with package.json exports) and older ones using subpath imports. It would be great if ts2esm could leverage TypeScript's built-in resolver to automatically handle these cases.
Example 1: Legacy Package (lodash)
lodash doesn't have an exports field, so it requires .js in the import path:
// Before (CommonJS)
import omit from 'lodash/omit';
// After (ESM)
import omit from 'lodash/omit.js';Currently, ts2esm doesn’t handle this, so I had to fix it manually.
Example 2: Modern Package (firebase-functions)
firebase-functions has an exports field, so no changes are needed:
// This works in both CJS and ESM
import { HttpsError } from 'firebase-functions/v1/https';However, in cases where an import incorrectly targets a private subpath, it breaks in ESM:
// This works in CJS but fails in ESM
import type { ObjectMetadata } from 'firebase-functions/lib/v1/providers/storage';Since TypeScript correctly flags these issues, maybe ts2esm could warn or ignore them?
3️⃣ Dynamic Imports Are Not Converted
I also noticed that dynamic imports aren’t updated with .js extensions:
const module = await import('./my-function.function');
// Expected:
const module = await import('./my-function.function.js'); Handling this would make ts2esm even more powerful!
Would love to hear your thoughts! Let me know if I can help test anything. 😊