Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gatsby 3 syntax support #129

Closed
mosesoak opened this issue May 28, 2021 · 18 comments
Closed

Gatsby 3 syntax support #129

mosesoak opened this issue May 28, 2021 · 18 comments

Comments

@mosesoak
Copy link

Is your feature request related to a problem? Please describe.

Yes. I'm unable to use your solution with Gatsby 3, which supports:
import { classOne, classTwo } from './styles.module.scss';

and supports but doesn't recommend,

import * as styles from './styles.module.scss';

but no longer supports:

import styles from './styles.module.scss';

At best, after installing the plugin, setting up VS Code as recommended and reloading the project, I've simply gotten string types to show up by doing export = classes; in the d.ts file, export default classes; fails entirely.

Describe the solution you'd like

Ideally I'd like to use Gatsby 3 with its standard gatsby-plugin-sass and scss modules, and be able to both get type hints in VS Code and ideally be able to jump to the definition of the style in the scss file from the component file.

Even more ideal than even this language plugin would be a way to just make this easier for anyone who wants to use Gatsby and scss modules work with Typescript out of the box in VS Code. For example could someone author a VS Code plugin that would solve this? Should we be petitioning Microsoft to somehow make this easier? It's frustrating that such a fundamental technology (css/scss modules + import) is so lacking in official support.

Describe alternatives you've considered

Currently the only solution that partially works is another 3rd-party lib, gatsby-plugin-scss-typescript, which generates individual d.ts files for each scss file. However, that adds quite a bit of clutter to the project, and clicking through does not jump into the class definition, just into the generated type. That said, it successfully adds code hinting.

Additional context

I'm on a PC running VS Code with remote-WSL. While testing out this solution I upgraded to TS 4.3.2.

@mosesoak
Copy link
Author

I found a VS Code plugin called CSS Modules that currently does work to provide code hinting and jump-to-definition. It doesn't support absolute paths, curly-brace module imports, and doesn't show any errors on incorrect class names, but so far it's the closest thing I've found to something that works with import * as styles syntax.

@mrmckeb
Copy link
Owner

mrmckeb commented May 29, 2021

Hi @mosesoak, thanks for all of the detail above.

I've just tested this locally and can confirm that it does work with the first example, and not the second.

You can see this working in VSCode here:
image

Just to clarify, are you saying that you can't use this approach and need to use * as styles? Or that you can't get the first example to work either? If it's the latter, could you provide a repro?


On your other comment, I agree and also wish this was easier. The TypeScript team haven't spent a lot of time on the plugin ecosystem and there are still limitations, there are a few issues on the topic and I know that they're listening - I think it's just prioritisation.

The VSCode plugin is a good alternative to this plugin. The original idea was that this plugin would give build-time errors too, but that's still not possible with plain TypeScript.

@mosesoak
Copy link
Author

Thanks for your reply.

Since Gatsby 3 no longer supports import styles I need support for import * as styles. The destructured import syntax didn't work for me.

I guess I'll be using the VS code extension for now, but was hoping I could use your plugin in tandem to provide type-checking.

(So far your plug-in doesn't work at all for me with Gatsby 3 -- if you have time, you could spin up a Gatsby project with Typescript and try adding your plugin to cross-test)

@cedeber
Copy link

cedeber commented Jun 2, 2021

Hello, the CSS tree shaking of Parcel v2 is also only available via import * as styles or named import. (although it still supports the default import)

So I agree that supporting the destructuring import would be nice :-)
Thanks.

@mrmckeb
Copy link
Owner

mrmckeb commented Jun 5, 2021

Hi @mosesoak and @cedeber, I made some changes in the last update (released last weekend and that seems to have fixed import * as styles in my testing.

If this syntax, or destructured imports still aren't working for you, it's very likely an issue with the CSS files themselves and how this plugin parses them (maybe a missing setting, or something we can add to help). Providing a reproduction would go a long way in helping me to resolve that type of issue - I'd love to help get this sorted for you!

As an example, you can see here that I have autocompletion/types.
image

@mrmckeb
Copy link
Owner

mrmckeb commented Jun 5, 2021

Another thought, if your classnames have hyphens, they obviously won't be able to be destructured (just in case).

@cedeber
Copy link

cedeber commented Jun 7, 2021

I upgrade to 3.4.0 and, indeed, it works better now.
But a class named my_css_class_name with the setup "classnameTransform": "asIs" doesn't work. I believe underscores are valid, aren't they? (It works well with default export btw)

@mrmckeb
Copy link
Owner

mrmckeb commented Jun 7, 2021

Hello, they definitely are supported! 😊

I've just double-checked with my test project, and this is what I see with that setting (note the last classname).
image

There might be something else happening, I'd be happy to take a look if you can provide a minimal reproduction?

@cedeber
Copy link

cedeber commented Jun 7, 2021

Yeah, but does styles.App_logo work too? I mean underscores are valid in objects prop names.

@mrmckeb
Copy link
Owner

mrmckeb commented Jun 8, 2021

Yes, it does :)
image

@mosesoak
Copy link
Author

mosesoak commented Jun 8, 2021

@mrmckeb Thanks for the updates! I have some pretty good results:

  • Both * as styles and destructured imports and code-hinting all work now!
  • You were right that a line in my scss file was choking the plugin: @import '~/styles/variables'; -- it's the absolute path configuration we use. Changing to a relative import path fixes the error.
  • Jump-to-definition does jump to the correct file but does not jump the cursor to the correct class. That's something that does work perfectly with the vs code css modules plugin, which I had deactivated for this test. If I reactivate it, two definitions are shown, theirs correctly shows the class, yours shows filename.scss:238:13 (the file only has 121 lines).

Anyway good progress, thank you for your quick response.

Sidebar: I've been surprised that CSS modules are not really in demand, I sort of thought or hoped that they'd be more embraced as a new standard since I kind of prefer SCSS to css-in-js solutions, which tend to add a new paradigm of their own that just doesn't feel like it will ever become a real standard way of doing things. The Gatsby team wrote back on my question about this saying there's just not much demand for CSS modules & typescript out there. Kind of a bummer. We're continuing to try out different things in our projects, styled-jsx, styled-components, emotion, and frameworks like tailwind. Cool that folks are working on this but I guess styling is just a neverending eddy in the fast-moving world of web dev.

@cedeber
Copy link

cedeber commented Jun 9, 2021

Wow, that's weird on my side. This is how it looks like on intelliJ:

With array notation:
css_module_1

With dot notation:
css_module_2

I only have access to style.default.axis_container? (which doesn't work with Parcel2 btw)

The SCSS file only contains this class and I import it via import * as style from "./styles/Whatever.module.scss";

@mosesoak
Copy link
Author

BTW @mrmckeb you probably saw me mention you here: clinyong/vscode-css-modules#25 (comment)

The short of it is this: you're the only one on the web who's come this close to solving modules + TS 😄 with the one remaining bug here being the jump-to-definition line. Whatever @clinyong did for his vs code plugin, do that.

The ideal would be a single vscode plugin that wrapped your work here to provide both language-level support and editor functionality!

We're going to move away from scss modules and try out some of the popular css-in-js libs for a while, but may end up coming back to this down the road - thanks for your help along the way!

@mrmckeb
Copy link
Owner

mrmckeb commented Jun 12, 2021

Hi @mosesoak, thanks for the kind words!

I think the problem in the ecosystem that everyone has a different config - Less/Sass/SCSS, different ways of aliasing/importing, etc. Because there isn't a standard, no tool will be perfect.

I'm on the team for Create React App and that's one place where I can guarantee certainty ;) I also need to do some spot checking against the default support in Next.js too, but I don't expect issues.

On definitions... I actually had an idea of how to make jump-to-definition work, and it looks like the VSCode extension you mentioned uses that exact approach:
https://github.com/clinyong/vscode-css-modules/blob/master/src/DefinitionProvider.ts

Note that this probably fails in some cases, like when classes are created with concatenation, etc.

TLDR; The final definition file will look very different to the source, and that's why the lines are messed up. We'd need to "reconstruct" the .d.ts to have the same line positions for this to work.

// Source (your *.css)

.class-b {
   color: red;
   background: blue
}

.class-b {
   color: green;
}

// Definition (virtual *.d.ts)

"declare let classes: {
  'class-a': string;
  'class-b': string;
};
export default classes;

It's mostly a matter of time, and I just haven't had the time to invest into rewriting the definitions to improve jump-to-definition... sorry!


Update @mosesoak, I felt like a challenge today and created a draft Sass implementation.
#137

@mrmckeb
Copy link
Owner

mrmckeb commented Jun 12, 2021

@cedeber perhaps you need to transform the classname? The below tsconfig.json example might work for you. The camelCase option gives both axis_container and axisContainer, or you can use camelCaseOnly to only get the latter of those :)

{
  "compilerOptions": {
    "plugins": [
      {
        "name": "typescript-plugin-css-modules",
        "options": {
          "classnameTransform": "camelCase"
        }
      }
    ]
  }
}

@cedeber
Copy link

cedeber commented Jun 14, 2021

Yes, thanks, but unfortunately camelCase transformation doesn't work currently with Parcel 2. There is some issues with PostCSS apparently. But still, I prefer to keep the same name in the (S)CSS than in JS too, just to avoid confusion to other team mates who are not used to CSS modules "magic"

I'll try to figure out what's going on with simpler project.

@andykenward
Copy link

andykenward commented Jul 23, 2021

For Gatsby 3 and css modules and you are using gatsby-plugin-sass you can set namedExport: false.

// gatsby.config.js
{
 resolve: `gatsby-plugin-sass`,
  options: {
   cssLoaderOptions: {
    modules: {
     namedExport: false,
    },
   },
  },
},

Then you can do

import styles from 'styles.module.scss' |

instead of

import * styles from 'styles.module.scss'

@mrmckeb
Copy link
Owner

mrmckeb commented Jan 4, 2022

I'll close this off, but feel free to reopen in future.

@mrmckeb mrmckeb closed this as completed Jan 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants