Skip to content

One more corner case when paths is present in tsconfig, but doesn't have "*": ["*"] there #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dko-slapdash opened this issue Nov 11, 2019 · 4 comments · Fixed by #43
Labels
Bug Something isn't working

Comments

@dko-slapdash
Copy link

Thanks for the previous fix in PR #41! It works perfectly when no paths key is defined in tsconfig.

But actually I think that const { baseUrl = "", paths = { "*": ["*"] } } = compilerOptions; still doesn't cover all the cases. Here is another example which makes the TS compiler totally happy, but ttsc (with this plugin) doesn't resolve paths in the compiled output:

{
  "compilerOptions": {
    "paths": {
      "shared/*": ["../../shared/src/*"]
    }
  }
}

Adding a dummy "*": ["*"] here helps again:

{
  "compilerOptions": {
    "paths": {
      "*": ["*"],
      "shared/*": ["../../shared/src/*"]
    }
  }
}

Looks like the full fix would be to search for "*" occurrence in compilerOptions.paths and, if it's there, add "*" as the last option (if it's not there yet). If it's not there, add the dummy paths key as it's done in the current PR #41.

@danielpza danielpza added the Bug Something isn't working label Nov 11, 2019
@danielpza
Copy link
Member

Thanks for the bug report, a fix will be merged shortly.

I also have another PR that should cover all those edge cases and should behave exactly as the typescript compiler #44

@dko-slapdash
Copy link
Author

Thank you!

JFYI, there is another example where tsc & /typescript-transform-paths work differently.

The below example is not caught up by typescript-transform-paths, it doesn't resolve e.g. import "shared/xyz" when shared/xyz.ts locates in common/src/shared/xyz.ts.

"paths": {
  "*": ["*", "../../common/src/*"]
}

At the same time, an absolutely equivalent construction below works:

"paths": {
  "*": ["*"],
  "shared/*": ["../../common/src/shared/*"]
}

Hope PR #44 will cover it too.

@danielpza
Copy link
Member

Yep, #44 should cover it. I'm still considering it, I could use your opinion on it btw. I'll probably push another fix in meantime.

@dko-slapdash
Copy link
Author

dko-slapdash commented Nov 11, 2019

Cool. I've just made typescript-transform-paths the only source of truth about paths in our project (and removed NODE_PATH=xyz hacks everywhere), works fine so far.

I have one more thought on all these. Maybe it's not a part of this particular issue, but it's probably too raw to create a new issue (more precisely, a feature request, and maybe even not for typescript-transform-paths).

In short, imagine we set this:

"outDir": "dist",
"baseUrl": "src",
"paths": {
  "*": ["*"],
  "shared/*": ["../../shared/src/*"]
}

and have the following folders structure:

(1)
├── server
│   ├── dist/
│   ├── src
│   │   └── entry.ts  // import "shared/some.ts"
│   └── tsconfig.json
└── shared
    └── src
        └── some.ts

If we run tsc, it will try to do its best - it will try to find the closest common parent for both shared/ and server/ folders and then re-create the files structure in dist/ accordingly:

(2)
├── server
│   ├── dist
│   │   ├── server
│   │   │   └── src
│   │   │       └── entry.js
│   │   └── shared
│   │       └── src     // <------ WAT
│   │           └── some.js
│   ├── src
│   │   └── entry.ts    // import "shared/some.ts"
│   └── tsconfig.json
└── shared
    └── src
        └── some.ts

Which is very very wild! What I would expect it to do is to NOT pretend to be that smart and instead just follow the original (before resolution) files structure in the output dir, like that:

(3)
├── server
│   ├── dist
│   │   ├── entry.js
│   │   └── shared       // this is my dream
│   │       └── some.js
│   ├── src
│   │   └── entry.ts   // import "shared/some.ts"
│   └── tsconfig.json
└── shared
    └── src
        └── some.ts

What's way worse is that, if I remove import "shared/some.ts" from entry.ts, then the tsc output in (2) magically becomes flat, like in (3), but without shared/ folder of course (because it doesn't have to find a common parent anymore). I.e. the structure of the output folder (and its nesting level) depends on what the code imports and what it doesn't import - which is just crazy.

There is no way to make tsc to do this currently, and the TS engineers are quite resistant to add an option to change the structure of the output.

(Actually, we use one work-around - we just create a symlink server/src/shared pointing to shared/src and don't use paths mapping in tsconfig for this - but it makes VSCode mad a little, it doesn't like symlinks.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants