bennycode / ts2esm

Transforms TypeScript imports and exports into ESM-compatible declarations.
https://www.npmjs.com/package/ts2esm
48 stars 2 forks source link

Support tsconfig paths #89

Closed prescottprue closed 1 week ago

prescottprue commented 1 week ago

Huge thanks for the lib - it has saved countless hours

When a path alias is used via paths setting in tsconfig it seems that ts2esm is not converting the import to have .js suffix

It would be awesome if we could check tsconfig (and even an extends file if one exists - i.e. tsconfig.paths.json referenced in "extends" setting of tsconfig) for paths settings - if they are found, make sure to apply suffix to imports using those aliases

Example

tsconfig.json

{
  "compilerOptions": {
    "paths": {
      "@libs/*": ["src/libs/*"]
    }
  }
}

Would convert the following import:

import { someLib } from '@libs/some-lib'

to

import { someLib } from '@libs/some-lib.js'`

Preferably also handling if the import is pointing to a folder that contains an index.js as is currently handled for import conversions

bennycode commented 1 week ago

Hi @prescottprue, I happy to hear that you find my tool valuable. πŸ™‚

I actually implemented support for paths in #53. Is your case specifically about the index.js file which isn't taken care of? I can try to reproduce this or do you have an open source repository that I can use for testing?

I also haven't tested TS configs that extend TS configs. I was hoping that https://github.com/dsherret/ts-morph handles this for me under the hood when calling project.getCompilerOptions().paths. Let me double check...

bennycode commented 1 week ago

Hey @prescottprue, I just tested a few cases...

Simple Export

src/libs/some-lib.ts

export const someLib = {};

src/main.ts

Before:

import { someLib } from '@libs/some-lib';
console.log(someLib);

After running tsesm:

import { someLib } from '@libs/some-lib.js';

console.log(someLib);

πŸ‘ - Test Passed

Index Export

src/libs/some-lib/index.ts

export const someLib = {};

src/main.ts

Before:

import { someLib } from '@libs/some-lib';
console.log(someLib);

After running tsesm:

import { someLib } from '@libs/some-lib/index.js';

console.log(someLib);

πŸ‘ - Test Passed

An import just from @libs/some-lib wouldn't work:

image

Paths in extends

When the paths are defined in a base config using extends, the ts2esm tool also works fine. Be aware, that an inherited config will overwrite the paths property. As per documentation:

It’s worth noting that files, include, and exclude from the inheriting config file overwrite those from the base config file, and that circularity between configuration files is not allowed.

prescottprue commented 1 week ago

Thanks for the quick response and testing!

Maybe I am doing something wrong then?

Here is a zip of the repro:

test-ts2esm.zip

Currently I have been doing the transform via yarn dlx ts2esm src/** - it shows that the src/index.jts is being processed, but the alias is not transformed

bennycode commented 1 week ago

Thank you for providing the example!

The ts2esm script seems to have issues with the "include": ["src"] entry in the project's tsconfig.json. Removing it resolves the problem.

You've raised a valid point, and I'll use it to prepare a fix. ✨

prescottprue commented 1 week ago

Oh awesome, glad to hear! In meantime I'll see if doing that in the existing projects I'm converting fixes it

bennycode commented 1 week ago

Hey @prescottprue, I just released a new minor version. Can you please try again using ts2esm v2.2.0?

I've also created a snapshot test for your use case. While doing so, I noticed a bug in the VS Code extension for Vitest.

It's always fun to see how everything connects and how software improves with each use case. πŸ™‚

prescottprue commented 1 week ago

Amazing thanks! Oh nice - wasn't aware of that extension for Vitest, I'll for sure start using that. Totally agree on the on improving with each use case and that only happens by OSS maintainers spending the time to checkout issues and replicate exactly like you did - bravo πŸ‘

From the looks of it in my test repo I uploaded in the zip above, I'm still not seeing @libs/some-lib being switched to @libs/some-lib/index.js in index.ts with 2.2.0. I'll keep poking at it though and see if it is something on my end