Search code examples
vue.jscss-loadercss-modulesnuxt.js

How to import CSS-Modules correctly with Nuxt?


I'm using CSS Modules with Nuxt and have run into some issues when trying to import a stylesheet in my js. If I import my stylesheet directly into the...

<style module>
   @import './index.css';
</style>

...everything works as expected. In my particular case I need to run a computed property to choose between two different stylesheets so instead of importing through the <style module> I need to import into <script> and implement the styles like so:

<script>
import foo from './index.css'
export default {
  computed: {
    styles() {
      return foo
    }
  }
}
</script>

When implementing this on vue everything works great and I get a style object returned. Nuxt however is returning an empty object and none of my styles render correctly.

I'm activating CSS-Modules in my nuxt.config.js file like this:

export default {
  ...
    loaders: {
      css: {
        modules: true
      }
    }
  ...
}

Is this an issue with Nuxt SSR? I've been looking for the root cause/solution but haven't had much luck in my search.

Update

After taking ivandata's advice and adding to my build script this code:

export default {
  ....
  build: {
    extend (config, ctx) {

      const cssLoader = config.module.rules.find(rule => {
        return rule.test.toString() === '/\\.css$/i';
      });

      delete cssLoader.oneOf[0].resourceQuery;

      ...
    }
  }
}

CSS modules appear to be working but a new problem popped up which is that now the project doesn't understand any vue-component styles that are not css-modules. After doing a bit of research I found out that the resourceQuery is telling the loader what type of file to apply the loader options to.

I've tried digging through the style loader on vue.cli 3 and comparing the differences to Nuxt. I removed ivandata's snippit and I tried matching the loaders of vue and nuxt but the problem still persisted.

Here is what is happening visually when between enabling and disabling ivandata's code:

Disabled enter image description here

Enabled enter image description here

And here is a code snippet of what is going on in my project:

<template>
  <section :class="style.container">
    <h1>hey</h1>
    <h2 class="test">hey</h2>
  </section>
</template>

<script>
import style from './index.css'
export default {
  computed: {
    style() {
      return style
    }
  }
}
</script>

<style>
  h1 {
    font-size: 100px;
  }

  .test {
    font-size: 100px;
  }
</style>

So as you can see if I have the resourceQuery in the css-loader my javascript import's of css do not work but all vue-component styles worked as normal. Once I remove the resourceQuery the js imported stylesheet works but the vue-template style classes no longer work. I don't think the solution lies in removing resourceQuery and I'm curious if this has something to do with another loader entirely. I've dug quite a bit through the vue.cli 3 loaders and can't see anything that distinctly sticks out to me.


Solution

  • Ok this another way. Leave your old code. Remove my code and add ?module to import file path:

    <script>
      import foo from './index.css?module'
      export default {
        computed: {
          styles() {
            return foo
          }
        }
      }
    </script>
    

    I was wrong. resourceQuery option is used to test against the query section of a request string.