NiGhTTraX / ts-monorepo

Template for setting up a TypeScript monorepo
MIT License
1.5k stars 169 forks source link

Support for using alias paths in the package #348

Closed syhxzzz closed 2 months ago

syhxzzz commented 2 months ago

Hi, sorry to bother you again.

I have been using your solution to build my project and encountered a challenge that I need some assistance with. Specifically, I am trying to create alias paths in a package shared by multiple apps.

I reviewed your apps/cra folder and noticed the @hooks/ alias example. However, this approach did not work for me, as the alias paths are located in the apps folder. I searched through the issues using the keyword alias but could not find a solution that addresses my problem.

I attempted to modify the tsconfig.json file in the package/foo example to include an alias path, and while the IDE did not raise any alerts, the alias paths were not recognized by webpack during packaging. To resolve this, I had to add the alias @foo/ to the apps/webpack/tsconfig.json file.

image image

Here is the change I made: Commit Link.

I am wondering if there is a better way to create alias paths in the package folder. It feels unusual to write alias paths in the apps' tsconfig.json, but I am unsure of a better approach.

Thank you for your time.

Best regards

NiGhTTraX commented 2 months ago

You're on the right path. If you want to use aliases within a package then you need to configure those aliases for all its consumers as well. Either you do it per package like in the commit you linked, or you centralize them in the monorepo root.

The above is necessary if you want "live types" e.g. Go to definition and type errors work as expected without first having to build the projects. If you're fine with building [some] packages first, then you can define the aliases just once and then use a toolchain that rewrites those aliases when building e.g. webpack.

For me, the possibility of not getting the intended outcome because I forgot to build some package first outweighs the alternative of some duplication in the configs.

syhxzzz commented 2 months ago

If you want to use aliases within a package then you need to configure those aliases for all its consumers as well. Either you do it per package like in the commit you linked, or you centralize them in the monorepo root.

From my perspective, the tsconfig.json file in the package primarily assists the IDE in resolving aliases. For example, if you remove the aliases from the tsconfig.json in the package, the IDE will indicate it cannot resolve the aliases you are using.

image

In applications where I need to bundle the project, Webpack encounters two sets of aliases. First, when it resolves to @nighttrax/foo/src/folder1/folder2/folder3, the initial path helps Webpack locate the package folder. Second, Webpack needs to resolve the dependency in the @nighttrax/foo/src/folder1/folder2/folder3 content. When it encounters @foo/src, although this alias is specified in the tsconfig.json of the package/foo, Webpack will not refer to that tsconfig.json since it only considers the tsconfig.json in its own or parent directory. Therefore, I need to define the alias @foo/* in apps/webpack/tsconfig.json to help Webpack resolve this alias. Another example is if you remove the aliases in package/foo, the IDE will alert, but Webpack can still build correctly.

This issue might be beneficial for users who use Webpack to bundle their code. It can guide them on correctly using aliases. Do you think this is worth including?

image
NiGhTTraX commented 2 months ago

From my perspective, the tsconfig.json file in the package primarily assists the IDE in resolving aliases.

Yes, but the toolchains can also read the same configs and rewrite the aliases. If a package is using aliases it can have downstream effects.

Another example is if you remove the aliases in package/foo, the IDE will alert, but Webpack can still build correctly.

If you remove them from packages/foo but keep them in apps/cra then yes, compiling the latter will work as expected since its config contains everything that's needed.

This issue might be beneficial for users who use Webpack to bundle their code. It can guide them on correctly using aliases. Do you think this is worth including?

It goes beyond the scope of this project, which is providing a good DX for navigating between packages in a monorepo. Using aliases inside a package can improve the DX for that package specifically (by shortening imports), but it will have downstream effects, by forcing the consumers to duplicate the aliases (or hoisting them in the root). The same would apply if a package imported non-TS files e.g. .png. The package in question would need a type declaration for *.png and all its consumers would have to contain it as well.

I just remembered that there's an open discussion https://github.com/NiGhTTraX/ts-monorepo/discussions/322 about this same topic, so I'll close this issue and pin it to help others find the discussion. Feel free to keep the linked discussion going.