typescript-plugin-css-modules icon indicating copy to clipboard operation
typescript-plugin-css-modules copied to clipboard

"Go to definition" does not work right

Open dko-slapdash opened this issue 5 years ago • 22 comments

Describe the bug

Thanks for the awesome plugin!

I noticed that "Go to definition" feature doesn't jump to the CSS class though.

To Reproduce

Here is an animated GIF which shows the problem:

Aug-14-2019 23-19-57

  • OS: MacOS
  • Version: current

dko-slapdash avatar Aug 15 '19 06:08 dko-slapdash

...what I also want to say: your plugin is the only really working solution in the universe. I just spent 2 days only on bridging css-modules + typescript strong typing + babel. And it finally works (except the two issues I created here). It's a big responsibility - and a big respect - to support this solution, because (as I believe) the general success of css-modules (vs. other techniques like styled-components may significantly depend on the success of this plugin (if we consider that typescript will continue its dominance). E.g. the popular create-react-app tool does not currently support css-modules properly (they miss this particular plugin in their config). If the plugin appeared polished enough to be included in create-react-app, it would be a HUGE success.

dko-slapdash avatar Aug 15 '19 09:08 dko-slapdash

Hi @dko-slapdash, I'm actually on the Create React App team - the reason we haven't included this is because plugins for TypeScript only work in an IDE... which means you don't get errors during build, or on your CI. I hope the TS team addresses this in the near future.

As for this issue, it's definitely a known issue and I should have documented it.

The plugin works by loading CSS, processing it (Sass/Less/PostCSS), parsing it, and then we get an object back with keys representing the classes found.

To make this feature work, I would need to know the location of each class. I think we'd need to do a string search... which in some cases would be impossible, especially if class names are generated (as they can be in Less and Sass)... So it is possible, but not in all circumstances.

We may also be able to use sourcemaps for this, but again, it could be a fair amount of work.

If you have any thoughts or ideas though, I'd love to hear them.

And thanks for all of your feedback!

mrmckeb avatar Aug 16 '19 08:08 mrmckeb

Oh wow, I didn’t realize you’re in create-react-app!

I think that even a raw string search by /^\.key\b/ where key is the property visible from TS side would be waaay better than nothing.

(BTW regarding less, I had to switch back from less to css unfortunately, because the plugin was stopping working silently; I can’t reproduce it stable enough though; btw, how do you debug the code? Is there a quick way to turn on some verbose logging in vscode in regards to this plugin?)

dko-slapdash avatar Aug 16 '19 08:08 dko-slapdash

There's a PR in to resolve the issue around silent failures - it was an oversight on my part.

I'm currently away on a business trip and I don't have a lot of time, but I hope to get that in in the next few days.

I think searching by key is fine, but the concern is that it won't catch all classnames... but I'm wondering if we could do something with sourcemaps instead... :)

mrmckeb avatar Aug 18 '19 09:08 mrmckeb

hi @dko-slapdash, just dropping a note to say that I haven't forgotten about this.

I think it's going to require using sourcemaps. Perhaps using something like this https://github.com/mozilla/source-map, or something more lightweight if possible.

mrmckeb avatar Sep 07 '19 12:09 mrmckeb

@mrmckeb Source maps won't help here as the icss stack generally doesn't supply source information when they are doing the transforms.

All exported elements are extracted from the :export pseudo class. Which might be generated by :local, @value or postcss messages that adhere to the 'icss spec'.

The ideal solution would be to include source information through the whole icss world, but that is not realistic. Next best thing is a 'simple' string search with something like a word boundary. It will not be perfect in all situations, for example:

.test {
  ...
}

.other > .test {
  ...
} 

Here the test export is created by both occurrences. And I don't think (I might be wrong) typescript has support for things originating in two locations.

I however think no-one will blame you for linking to the first occurrence.

If you later wanted to add some form of preview I could help you with the postcss plugin that helps you find the rule, :export prop or @value definition that is referred to.

For now, the string search option seems a safe, non-expensive way to make the plugin much more valuable.

EECOLOR avatar Nov 10 '19 21:11 EECOLOR

@EECOLOR, I complete agree - the only concern I have is that this won't work for many cases.

As you mentioned, it won't work for multiple occurences, it also won't work for generated/concatenated classnames, etc.

My thought was that we could possibly deal with the latter issue by creating a sourcemap before we extract the classnames... or as a separate process. As you mentioned, that's not going to be cheap.

If someone wants to put together a basic string-match in the meantime, I'd be happy to merge that in :)

mrmckeb avatar Nov 11 '19 07:11 mrmckeb

BTW, VSCode supports multiple occurrences in the UI - i.e. if we create the following:

// a.ts
interface A {
  field1: number;
}

// b.ts
interface A {
  field2: string;
}

then it will be an interface A with 2 fields, and when doing "Go to definition", it will show 2 files and 2 locations for A.

P.S. I'd say that the absence of "go to definition" doesn't hurt much presently. What really hurts is that the plugin doesn't work stable enough still: e.g. if I add a new classname to a css file, in 70% of cases VSCode doesn't recognize a reference to it in *.tsx file, and only vscode restart helps. I suspect it's still the same issue which was hot-patched in https://github.com/mrmckeb/typescript-plugin-css-modules/issues/41 - it used to crash tsserver, and after the patch, it doesn't crash, but just ignores all further changes in css file.

dko-slapdash avatar Nov 11 '19 08:11 dko-slapdash

Hey there! Very nice plugin, thank you very much for the work. here and on CRA. I don't think it would be bad to be included in the create-react-app even if it doesn't throw errors in compilation. Would already be a giant help :)

In VsCode, we can press F2 to rename a symbol. With this plugin, it doesn't work to rename both css and the .ts. Looks like it is the same problem as the OP pointed.

I still don't know how plugins works, but wouldn't a Regex fix it?

Edit: Also, won't open an issue for this one, because I don't know if your plugin could do it: It is possible to autocomplete the path, when importing the styles file?

ftzi avatar Nov 17 '19 20:11 ftzi

HI @SrBrahma,

You're right, that is the same issue. It's something I'd like to fix - and I'd welcome a PR from anyone that has the time. It's just that I haven't personally had time to investigate the best way to achieve this.

Also, won't open an issue for this one, because I don't know if your plugin could do it: It is possible to autocomplete the path, when importing the styles file? I don't think it's possible right now - as the plugin needs the file to be imported before it picks it up. We could look to change that in future, but it would be a bit of work.

mrmckeb avatar Dec 01 '19 12:12 mrmckeb

I know this isn't the right place to say it, but I'd rather not pollute the repo with a pointless issue.

Thank you SO much for this plugin. As @dko-slapdash noted, this is literally the only thing that currently works. Great stuff.

AleksandrHovhannisyan avatar Dec 05 '19 01:12 AleksandrHovhannisyan

Thanks for the feedback @AleksandrHovhannisyan!

mrmckeb avatar Dec 08 '19 17:12 mrmckeb

I just wanted to add a note here that I managed to get this working as expected in VS Code by installing the CSS Modules extension. However, this causes there to be duplicate autocomplete options and duplicate definitions, which isn't ideal either.

michael-swarm avatar Jul 25 '20 18:07 michael-swarm

@michael-swarm if you're using that extension, I'd recommend not using this plugin. Both are doing the same thing, as you mentioned.

This is something that's fixable... but not for all cases. It's mostly that I haven't had the time to spend on it sorry - but we always welcome PRs.

mrmckeb avatar Jul 27 '20 07:07 mrmckeb

It's something I'd like to fix - and I'd welcome a PR from anyone that has the time. It's just that I haven't personally had time to investigate the best way to achieve this.

Could someone suggest which method of Typescript or LanguageHosts should be ovverided to do mapping the css file line to the .ts line?

sosoba avatar May 13 '21 06:05 sosoba

I'm not 100% sure on that either @sosoba, as I haven't attempted it yet. I assume we'll be able to use sourcemaps here to get the original lines/locations, I'm just not sure how to surface that in the IDE.

mrmckeb avatar May 29 '21 11:05 mrmckeb

I did npx create-next-app@latest --ts and I can't go to definition. instead, vscode brings me to global.d.ts. I know this is a different issue but it's related to the discussion here.

NoamNol avatar Jan 11 '22 18:01 NoamNol

@NoamNol If you created a new project, your case may be that that it's using the Editor/IDE Typescript, instead of the typescript in your workspace.

The errors are shown normally (if you write a wrong classname, for example)?

If you are using VSCode, make sure you follow the steps defined at https://code.visualstudio.com/docs/typescript/typescript-compiling#_using-the-workspace-version-of-typescript

lucasbasquerotto avatar Jan 12 '22 12:01 lucasbasquerotto

@lucasbasquerotto I configured it to use the workspace TypeScript but it doesn't matter. No error for wrong classname. Latest version of VSCode. TypeScript 4.5.4.

NoamNol avatar Jan 12 '22 14:01 NoamNol

@NoamNol It should give an error, so it seems the plugin is not being used.

One reason for that is that it's not using the typescript of your workspace, like I said previously. Another reason is that the typescript tsconfig.json file doesn't have:

plugins": [{ "name": "typescript-plugin-css-modules" }]

Can you verify that your tsconfig.json file has the plugin above, and that your package.json also has it in dependencies or devDependencies (and it's installed in node_modules)?

If it has, then I don't know what it could be, maybe someone else can help, but first check what I said above.

lucasbasquerotto avatar Jan 12 '22 15:01 lucasbasquerotto

@lucasbasquerotto Thanks it works! I thought npx create-next-app@latest --ts will do all the configuration but I was wrong

NoamNol avatar Jan 12 '22 15:01 NoamNol

@NoamNol can you share more about your setup? i've tried installing this plugin but it looks like the Next.js types still overwrite the plugin's types (i get taken to global.d.ts). i have this in my tsconfig:

    "plugins": [
      {
        "name": "typescript-plugin-css-modules"
      }
    ]

FunctionDJ avatar Apr 04 '22 13:04 FunctionDJ

Hi @FunctionDJ, the Next.js types will be used during build, but these types will be used in VSCode (or other editors). Just make sure you've followed the instructions in the README :)

mrmckeb avatar Oct 24 '22 05:10 mrmckeb

My VSCode opens d.ts file with definition, how to open at least correct CSS file?

max-mykhailenko avatar Nov 04 '22 15:11 max-mykhailenko

@max-mykhailenko

I've been having the same problem for a long time, the problem went away when I used react-ts-css . I would love for you to try it. 👍

piro0919 avatar Nov 11 '22 03:11 piro0919

@piro0919 @mrmckeb thank you, works better now, now I have two definitions. How to tell VSCode to ignore d.ts files for css? image

max-mykhailenko avatar Nov 11 '22 10:11 max-mykhailenko

@max-mykhailenko

I don't know the details, but what if you put the following settings in vscode?

  "editor.gotoLocation.multipleDefinitions": "goto",
  "editor.gotoLocation.multipleTypeDefinitions": "goto",

piro0919 avatar Nov 11 '22 12:11 piro0919

If I understand correctly this only works for Sass files at the moment. What work is left to do to make this work for regular CSS files? (I tried it but it didn't seem to work properly.)

Update: extracted to https://github.com/mrmckeb/typescript-plugin-css-modules/issues/175

https://user-images.githubusercontent.com/921609/204132679-d4b01ac8-eb5b-47d3-adcc-6a9cfd066ac4.mov

OliverJAsh avatar Nov 27 '22 11:11 OliverJAsh