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

Not updating when new classes are added

Open mariusGundersen opened this issue 4 years ago • 14 comments

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.

mariusGundersen avatar Jul 21 '20 09:07 mariusGundersen

It seems to take up to 15 seconds on my machine

boformer avatar Jul 22 '20 16:07 boformer

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.

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

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.

mrmckeb avatar Jul 27 '20 07:07 mrmckeb

No, it does not show up later, not as far as I can tell.

mariusGundersen avatar Jul 27 '20 21:07 mariusGundersen

Are you able to provide a reproduction, even something very simple, @mariusGundersen? I can look this weekend and try to resolve then :)

mrmckeb avatar Aug 05 '20 11:08 mrmckeb

@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.

chrisgbaker avatar Oct 21 '20 02:10 chrisgbaker

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 by tsconfig.json and referenced from an import counts towards this total.
  • .ts/.tsx files aren't subject to the polling delay since editors send immediate updateOpen requests with the full filename to tsserver 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:

  1. 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.
  2. 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.
  3. If tsserver used a notification-based watcher instead of polling, this wouldn't be an issue. At the moment tsserver overrides a compiler watch object to always use polling. I may file a separate question/issue on microsoft/TypeScript to see why that is. (Edit: Filed as https://github.com/microsoft/TypeScript/issues/41549.)

gluxon avatar Nov 16 '20 01:11 gluxon

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.

mrmckeb avatar Nov 23 '20 09:11 mrmckeb

Hi. Typescript team closes #41549 two monts ago. Did it really help?

sosoba avatar May 12 '21 05:05 sosoba

@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.

gluxon avatar May 19 '21 14:05 gluxon

If anyone has feedback on this in TS 4.3, please let us know here :)

mrmckeb avatar May 29 '21 11:05 mrmckeb

I've just updated a large codebase to TS 4.3. Unfortunately, I haven't seen any noticeable improvements for this problem.

davidmh avatar Jun 01 '21 17:06 davidmh

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.

mrmckeb avatar Jun 05 '21 08:06 mrmckeb

@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!

yts avatar Aug 16 '21 15:08 yts

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).

mrmckeb avatar Oct 24 '22 05:10 mrmckeb

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

davidmh avatar Nov 17 '22 06:11 davidmh

same error [email protected]

ducmaster01 avatar Feb 20 '23 02:02 ducmaster01

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"]
}

work for me, thank you

ducmaster01 avatar Feb 20 '23 02:02 ducmaster01

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.

mrmckeb avatar Feb 20 '23 02:02 mrmckeb