Skip to content

Support for CSS modules #38

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

Closed
LinusBorg opened this issue Dec 28, 2017 · 5 comments
Closed

Support for CSS modules #38

LinusBorg opened this issue Dec 28, 2017 · 5 comments

Comments

@LinusBorg
Copy link
Member

LinusBorg commented Dec 28, 2017

As the README states, this lib currently doesn't process the <style> parts.

That's not a big issue when we unit test components that use the normal styles API, by which I mean they use harcoded class names in the template:

<div class="staticClass" v-bind:class="{ 'dnyamicClass' : someFlag }">

However, for CSS modules, this means that this.$styles is undefined in unit tests and rendering will fail.

I think we have two options:

A: Mock $styles

We could simply add this prop to a component if we find a style part with the modulesattribute, and use a Proxy to return the class that was required:

// pseudocode
  this.$style = new Proxy({}, {
    get(_, property) {
      return property
    }
  })

Proxies are available in node since http://node.green/#ES2015-built-ins-Proxy, so that's quite good. We are dropping support for node 4.* in vue-cli etc. as well, so that should be enough.

The only downside I see it that we can't catch missing classes: If I mistype a class name in my component, I will still get back that mistyped classname from the proxy. If we properly evaluated the styles, we would get undefined and could catch this bug better, I think.

B: Evaluating styles and building the $styles object.

We could add the usual popular preprocessors as peer deps, write a small wrapper for each to compile the styles, and then use something like string-extract-class-names to get all classnames from the resulting CSS.

From that, we could build a "real" $styles object and inject it into the component.

@eddyerburgh - what approach would you prefer?

@eddyerburgh
Copy link
Member

Option B would be the best approach, I won't have time to implement it for a few weeks. Would you be able to make a PR?

If not, we could do option A as a quick fix.

@LinusBorg
Copy link
Member Author

I am off work for the coming week, would try a PR.

@LinusBorg LinusBorg reopened this Dec 28, 2017
@danielbastos11
Copy link
Contributor

Any updates? I'd love to help if needed.

@danielbastos11
Copy link
Contributor

danielbastos11 commented Jan 23, 2018

I just made a PR using option B.
I made three decisons:

  1. I decided to use extract-from-css instead of string-extract-class-names because the latter would claim .5px is a CSS class in letter-spacing: 0.5px. The former seems to work just fine.

  2. In order to inject the mock object into the component, I am using a code like the following at the end of the output (take a look the PR for the actual version):

;(function() {
  var render = _Component.render
  _Component.render = function(h) {
    this['$style'] = {/* mock object */}
    return render.call(this, h)
  }
})()

I don't know if there's a better way to do this. Let me know if there is.

  1. I added Stylus as a peer dependency, since other users might use SASS, for instance. This is causing the tests to fail, though. (they pass just fine once stylus is installed)

@lzgrzebski
Copy link

lzgrzebski commented Jun 5, 2019

Im populating my colors from scss variables and Im using in through this. $style, but for some reason this is not working when running unit tests in jest, through yarn serve all works fine. Any ideas? Am I doing smth wrong?
`<style lang="scss" module>
@import '@/styles/variables.scss';
:export {
primary: $color-primary;
secondary: $color-secondary;

success: $color-success;
danger: $color-danger;
info: $color-danger;

light: $color-light;
white: $color-white;

}
</style>`

Why am I doing this? Im using in couple of places colors in js and want to have it in one place.
Inspiration comes from here css-modules/css-modules#86 (comment)

Currently Im just getting empty obj in jest and the object is populated normally when Im running the app.

Is this valid use case @eddyerburgh ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants