Did anyone make a large TypeScript codebase work with ESM + TS + node (together with IDE support and yarn pnp support?)
The thing that is annoying with ESM is that it requires to have extensions in imports, i.e. `import .. from '/foo.js'`.
This gets messy with TypeScript, where your files are named `foo.ts` but you need to import `foo.js`.
The previous "best practice" in TS world was to have extensionless JS imports, so this move would require a massive codemod to update all imports in an entire codebase.
For now, we've been using `ts-node` with swc under the hood, but without ESM. I tried `tsx`, but the compilation time of esbuild is way too slow, some of our node CLI tools written in TS take 15s to boot up, which is not acceptable (with `ts-node` it's 3-4s) (tbh, it's probably partly a fault of our CLI framework, which crawls all workspaces to discover all CLI tools, and as we have a lot of them, tsx has a lot of useless work to do).
While `rewriteRelativeImportExtensions` works for frontend applications, it has a significant limitation: it doesn't fix declaration files (.d.ts), which is problematic when developing libraries or public packages.
I created a small tool to address ESM + TypeScript issues that the tsc doesn't handle:
https://github.com/2BAD/tsfix
Also there are eslint rules older than erasableSyntaxOnly that can also be useful in doing a "rip-the-bandaid-off-refactor" using all the lint warnings/warnings-as-errors to add extensions everywhere in the case where your brownfield also needs to be a version or two behind on Typescript.
The thing that is annoying with ESM is that it requires to have extensions in imports, i.e. `import .. from '/foo.js'`.
This gets messy with TypeScript, where your files are named `foo.ts` but you need to import `foo.js`.
The previous "best practice" in TS world was to have extensionless JS imports, so this move would require a massive codemod to update all imports in an entire codebase.
For now, we've been using `ts-node` with swc under the hood, but without ESM. I tried `tsx`, but the compilation time of esbuild is way too slow, some of our node CLI tools written in TS take 15s to boot up, which is not acceptable (with `ts-node` it's 3-4s) (tbh, it's probably partly a fault of our CLI framework, which crawls all workspaces to discover all CLI tools, and as we have a lot of them, tsx has a lot of useless work to do).