typescript-plugin-css-modules
typescript-plugin-css-modules copied to clipboard
Not updating when new classes are added
Describe the bug When I first import a css module in my tsx file it lists the classes that are in the css file. But when I add a new class to the css module file they do not show up in the ts intellisense. In other words, it seems like the classes are cached and the cache is not updated when the css file is edited and saved.
It seems to take up to 15 seconds on my machine
I'm having the same issue, but it never updates in my case, even after a restart of VS Code. The error says Property 'myClassName' does not exist on type '{}'
, even when the file has multiple classes in it (including the one I'm referencing).
EDIT: My issue actually turns out to be #82, sorry for the noise.
Hi @mariusGundersen - can you confirm that as @boformer indicated, this is showing up later?
This plugin relies on TypeScript to watch file changes, so this might be a hard issue to solve. But any additional help could be much appreciated.
No, it does not show up later, not as far as I can tell.
Are you able to provide a reproduction, even something very simple, @mariusGundersen? I can look this weekend and try to resolve then :)
@mariusGundersen were you ever able to resolve this? I also believe it is related to relative imports mentioned in #78 and #82, as I need to update my .scss
imports from @import('styles/globals/colors.scss')
to @import('src/styles/globals/colors.scss'
in order for the plugin/ts server to correctly initialize. However, after they do,changes to .scss
files are not noticed, and in order to pick any up, I need to restart the TS server.
My tsconfig.json
:
{
"compilerOptions": {
"target": "es2019",
"module": "esnext",
"allowJs": false,
"checkJs": false,
"jsx": "react",
"declaration": false,
"resolveJsonModule": true,
"noEmit": true,
"strict": false,
"noImplicitAny": false,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"esModuleInterop": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"baseUrl": "src",
"paths": {
"styles/*": ["styles/*"],
},
"plugins": [
{
"name": "typescript-plugin-css-modules",
"options": {
"customMatcher": "\\.scss$",
}
}
]
},
"include": ["src/**/*"],
"exclude": ["node_modules"],
}
@mrmckeb is there also a possibility that a sheer volume of scss
and TS files could affect this? I took the very large repo in question and tried to pare it down to a small repro of the issue with just one component, an associated style file, and a global style file being relatively imported, but have not been successful in doing so.
Hey @mrmckeb, thanks for the great plugin.
My coworker and I dug into this and narrowed it down to tsserver
's polling file watch behavior. At the moment, tsserver
polls background files for file modification times in batches of 30
every 2500
milliseconds. This means a project with 5000 files will see a CSS file update every ~6.94 minutes.
Note that:
- A project with ~5000 files watched isn't uncommon since it includes
node_modules
. Any file included bytsconfig.json
and referenced from an import counts towards this total. -
.ts
/.tsx
files aren't subject to the polling delay since editors send immediateupdateOpen
requests with the full filename totsserver
on keystrokes.
I'm not sure what the best way for typescript-plugin-css-modules
to fix this is since it's limited by the language service API. To brainstorm a bit:
- If there was a way for TypeScript Language Service plugins to know which CSS files were open, we could watch these files directly and call
Project.updateGraph
when they change. I don't think this is doable though since VSCode filters out CSS files from open file list payloads. - We could propose a change to the plugin API that allows it to specify additional file extensions it cares about. Unfortunately this would require a change in TypeScript and all editors with TypeScript language service support.
- If
tsserver
used a notification-based watcher instead of polling, this wouldn't be an issue. At the momenttsserver
overrides a compiler watch object to always use polling. I may file a separate question/issue onmicrosoft/TypeScript
to see why that is. (Edit: Filed as https://github.com/microsoft/TypeScript/issues/41549.)
Hi @gluxon,
Thanks for the feedback - and for the very detailed/thorough analysis.
And thanks for creating the issue with TypeScript, I've subscribed and will wait for an update.
The TypeScript team have been fairly resistive to add more support for plugins like this so far, instead wanting to spend more time on TypeScript features (which I understand) and they seem concerned about supporting such APIs long-term (which again is understandable).
I still think that they need to do this, long-term, as there will always be files that users want to import that don't are being transformed in some way. Today the only robust solution is to literally have a d.ts
written to the disk that details every module's exports... and this plugin tries to do that without the disk-writing, but obviously loses build-time support.
I've recently hit the same issue with .graphql
files and we're just restarting the TypeScript server in VSCode everytime we change a query for now, because there doesn't seem to be a cleaner way to handle this... and it's even worse if you use ESLint with TypeScript, as you also need to restart that.
I will leave this open and also keep thinking about ways to solve this, as I'd love to improve performance here too.
Hi. Typescript team closes #41549 two monts ago. Did it really help?
@sosoba The changes from #41549 aren't released on stable yet. It's pending for TypeScript 4.3: https://github.com/microsoft/TypeScript/pull/42542#issuecomment-769409747
At writing the latest version of TypeScript is 4.2.4.
If anyone has feedback on this in TS 4.3, please let us know here :)
I've just updated a large codebase to TS 4.3. Unfortunately, I haven't seen any noticeable improvements for this problem.
OK, thanks for the updates @davidmh. I'll keep an eye on this and see if there are any wins we can have here in future.
@gluxon , @mrmckeb I was having this issue of the TS FileWatcher only firing after a few minutes, and updating TypeScript from 4.1.2 to 4.3.5 fixed the problem for me.
Thank you @gluxon for reporting the issue to the TypeScript team!
I'm on Typescript 4.7.3 and it's still slow.
Here's my workaround:
I figured that when I use VSCode command like Typescript: Restart TS Server
or Typescript: Reload Project
it forces TS to recalculate and I can see updated types. The second command seems faster so what if we can run it every time I save my CSS file (SCSS in my case)?
I found a great idea on how to achieve it on StackOverflow.
We have to create a task that will run the VSCode command and put it into tasks.json
. This file can be somewhere in User folder (default path) or in .vscode
project's folder. It looks like that:
{
"version": "2.0.0",
"tasks": [
{
"label": "typescript-reload-projects",
"command": "${command:typescript.reloadProjects}"
}
]
}
Then we have to install Trigger Task on Save extension and add this into VSCode's settings.json
:
"triggerTaskOnSave.tasks": {
"typescript-reload-projects": ["*.scss"]
}
From what I've heard (and seen), performance shouldn't be a big issue anymore @piotr-musialek-footballco - but that's a great solution for anyone that does have performance/sync issues, thanks!
I'm going to close this off now as there's not a lot we can do from this side (as far as I can tell).
I updated the codebase I was having issues with to TS 4.9, and the changes now reflect immediately!
It looks like an improvement in their file-watching system: https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/#file-watching-now-uses-file-system-events
same error [email protected]
I'm on Typescript 4.7.3 and it's still slow.
Here's my workaround: I figured that when I use VSCode command like
Typescript: Restart TS Server
orTypescript: Reload Project
it forces TS to recalculate and I can see updated types. The second command seems faster so what if we can run it every time I save my CSS file (SCSS in my case)?I found a great idea on how to achieve it on StackOverflow. We have to create a task that will run the VSCode command and put it into
tasks.json
. This file can be somewhere in User folder (default path) or in.vscode
project's folder. It looks like that:{ "version": "2.0.0", "tasks": [ { "label": "typescript-reload-projects", "command": "${command:typescript.reloadProjects}" } ] }
Then we have to install Trigger Task on Save extension and add this into VSCode's
settings.json
:"triggerTaskOnSave.tasks": { "typescript-reload-projects": ["*.scss"] }
work for me, thank you
Glad that helped, thank you for sharing!
It can be slow. Unfortunately there's not a lot I can do there for now as we rely on TypeScript's language service which doesn't natively support CSS files.