SmallComfort/react-vue-loader

styles tag with `modules` or `scoped` attributes do not work

Closed this issue · 5 comments

Hey there, first off, this is excellent work. Combining React + Vue works pretty much perfectly. So this is just a minor issue.

Basically the following does not result in scoped styles:

<template>
  <div class="container">
      foo
  </div>
</template>

<style lang="stylus" scoped>
.container
  background green
  position absolute
  top 0px
  left 0px 
  width 100vw
  height 100vh
  z-index -1
  display flex
  align-items center
  justify-content center
  & span
    color rgba(255,255,255, .5)
    font-size 32px
</style>

No attribute is added to the top template element, and the resulting css class definition is scoped to the attribute id.

css modules also don't seem to work:

<template>
  <div @click="count++" :class="$style.container">
    <div>{{count}}</div>
    <slot></slot>
  </div>
</template>

<script>
  export default {
    data () {
      return {
        count: 0
      }
    }
  }
</script>
<style lang="stylus" module>
.container
  background green
  position absolute
  top 0px
  left 0px 
  width 100vw
  height 100vh
  z-index -1
  display flex
  align-items center
  justify-content center
  & span
    color rgba(255,255,255, .5)
    font-size 32px
</style>

I tried it with and without the webpack cssModules option:

{
        test: /\.vue$/,
        loader: 'react-vue-loader',
        options: {
          vue: path.resolve(__dirname, '../vue.config.js'),
          loaders: {
            stylus: 'vue-style-loader!css-loader!stylus-loader'
          },
          cssModules: {
            localIdentName: '[path]-[name]-[local]',
            camelCase: true,
            modules: true,
            importLoaders: 1
          }
        }
      },

it appears at this line:

https://github.com/SmallComfort/react-vue-loader/blob/master/lib/loader.js#L34

its style[':attr'].module === 'true' that we are looking for.

However, even if we force this to be true and set moduleName to '$style' as a result. It still doesn't work.

Otherwise, it seems the loader.js file is very different than the code from the original repo:

https://github.com/vuejs/vue-loader/blob/master/lib/loader.js

Several hundred lines are missing. I see that they aren't new, but you in fact removed them. Are modules and scoped simply not supported? It seems like it is in fact almost working. I'm not sure what's missing.

Basically it seems this call:

const getRequire = getRequireModule.call(this)

which generates this:

cssModules["$style"] = require("!!vue-style-loader!css-loader!../../node_modules/react-vue-loader/lib/style-compiler/index?{\"vue\":true,\"id\":\"data-v-2c011bd0\",\"scoped\":false,\"hasInlineConfig\":false}!../../node_modules/react-vue-loader/lib/selector?type=styles&index=0!./Hello.vue");

Doesn't in fact generate the necessary "locals."

And I guess similarly the CSS isn't transformed. I'm currently not sure where that's supposed to happen.

What was the goal of removing all that was removed from the original vue-loader?
..Oh, I see, because you moved the code to getRequireModule.

ok, I figured it out. <style module> doesn't get the module transformed to true like it would with React. I had manually tried replacing it in code for a long time, but it didnt work. Then I realized I needed to do it near the top of the loader code and it works now.

I'm now trying to find a way to trigger it from application code.

ok, im closing this out, as I've now left you a PR that fixes this:

#2