dominikg / tsconfck

A utility to find and parse tsconfig files without depending on typescript
Other
290 stars 14 forks source link

Cannot resolve solution-tsconfig of Vue files #195

Open sxzz opened 5 days ago

sxzz commented 5 days ago

Description

In the function resolveSolutionTSConfig, only JS/TS extensions are considered, but not including Vue files.

https://github.com/dominikg/tsconfck/blob/e45d31e42022cc7a72f3c630a7d7432de3f87635/packages/tsconfck/src/util.js#L142-L144

The transformWithEsbuild function in Vite fails to resolve the correct esbuild options (tsconfigRaw) for Vue files but works for TS files.

https://github.com/vitejs/vite/blob/ba56cf43b5480f8519349f7d7fe60718e9af5f1a/packages/vite/src/node/plugins/esbuild.ts#L125-L126

Reproduction

https://github.com/vitejs/vite-plugin-vue/issues/430#issuecomment-2248537357

Additional Information

N/A

dominikg commented 5 days ago

related in svelte: https://github.com/sveltejs/vite-plugin-svelte/issues/953

i'd rather not hardcode extensions though. given that ts itself does not resolve .vue files with **/* , one could argue that configurations targeting custom extensions must include them with their extension

sxzz commented 5 days ago

In the current Vue ecosystem (like Nuxt), we don't need to add the .vue suffix because the Vue Language Tools extension (Volar) handles it.

Additionally, adding .vue doesn't seem to affect non-Vue projects (also for .svelte)

dominikg commented 4 days ago

this would affect every user of tsconfck. It's primary use is to read tsconfig files as typescript would. Do you have information on how typescript deals with this?

tsconfck isnt going to implement custom behavior of third party tools as default. If there is sufficient demand and the implementation is simple/ easily maintained, then an option can be added.

alamhubb commented 3 days ago

util.js{isGlobMatch}

return regex.test(filename);

image

Hello, I also encountered related problems when using vue. I roughly understood the tsconfck related code. I saw that the regular expression was used to confirm whether the file was matched. Why is it still necessary to hard code it? Can't I just use filename and include? Why do I need separate extensions? Maybe I don't understand it deeply enough, but I am still curious. Sorry to bother you.

If you only use include, this problem does not exist. The user can configure include externally.

dominikg commented 3 days ago

yes, if the user uses a tsconfig that explicitly has the .vue extension it should work

"include": ["src","src/**/*.vue"]

The issue at hand seems to be that some tooling in vue decided that an extensionless glob * should match .vue files by default too, but the typescript documentation lists only ts,tsx,d.ts (and js/jsx with allowJs) https://www.typescriptlang.org/tsconfig/#include

alamhubb commented 3 days ago

yes, if the user uses a tsconfig that explicitly has the .vue extension it should work

"include": ["src","src/**/*.vue"]

The issue at hand seems to be that some tooling in vue decided that an extensionless glob * should match .vue files by default too, but the typescript documentation lists only ts,tsx,d.ts (and js/jsx with allowJs) https://www.typescriptlang.org/tsconfig/#include

But the problem now is that when I pass the correct include "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]

tsconfck still cannot return the correct tsconfg.app.json,

because the logic is blocked in this line of code, and false is directly returned, causing the include to fail to take effect.

extensions.some((ext) => filename.endsWith(ext)) &&

image

dominikg commented 3 days ago

ahh, thats unfortunate. I think past me added that as an optimization to skip all the regex checks in isIncluded if we can deduce from the extension already. Does it start to work if you remove that line from your copy of tsconfck in node_modules? (it is packaged as unbundled esm so you can just go in and edit it to test)

dominikg commented 3 days ago

a customExtensions option could still be the best compromise here, which leaves users in control. It would require a slight refactoring for the extensions regex group and passing the options into resolveSolutionTSConfig but shouldn't be too hard @sxzz

alamhubb commented 3 days ago

ahh, thats unfortunate. I think past me added that as an optimization to skip all the regex checks in isIncluded if we can deduce from the extension already. Does it start to work if you remove that line from your copy of tsconfck in node_modules? (it is packaged as unbundled esm so you can just go in and edit it to test)

Yes, when I delete this line of code, it works fine.

alamhubb commented 3 days ago

ahh, thats unfortunate. I think past me added that as an optimization to skip all the regex checks in isIncluded if we can deduce from the extension already. Does it start to work if you remove that line from your copy of tsconfck in node_modules? (it is packaged as unbundled esm so you can just go in and edit it to test)

I have an immature opinion. Not sure if this is correct, please advise

You said that for performance considerations, it is because the performance of filename.endsWith(ext) is better than regex.test(filename), so you can first perform an extension judgment to avoid regular judgment

If it is because .endsWith performs better than regular

Can extensions be taken out of include without the user's additional declaration?

Because this also involves a problem, that is, different tsconfig.json includes are different, does it mean that each tsconfig.json needs to configure customExtensions

Each time you read customExtensions from tsconfig.json and use include directly, are the extension names similar?

It can also avoid the problem of users declaring include and customExtensions separately

dominikg commented 3 days ago

customExtensions would not be in tsconfig.json but passed to tsconfck as part of the options to parse. It would not depend on the tsconfig file. Another option could be to have a boolean allowCustomExtensions (default false) and let everything pass if thats set.