Rollup-plugin-vue: No scoped attribute in children elements with scss

Created on 13 Jan 2020  路  6Comments  路  Source: vuejs/rollup-plugin-vue

Version

5.1.1

Steps to reproduce

What is expected?

All elements have scope identifier attribute.

What is actually happening?

Only root element have scope identifier.


Im working with nuxt and importing my module to test it. But developing "library" independently.

Most helpful comment

I'm seeing a similar issue on Nuxt SSR. We have a Vue library built with Rollup and included in the Nuxt app. On an SSR only root elements have a scope attribute set so styles are not working.

All 6 comments

I'm seeing a similar issue on Nuxt SSR. We have a Vue library built with Rollup and included in the Nuxt app. On an SSR only root elements have a scope attribute set so styles are not working.

I found that problem yesterday and I had some time to dig into that. I found out that there was a similar issue in vue-loader fixed by @yyx990803 a few years ago.
https://github.com/vuejs/vue-loader/commit/36c5b95e6693e0298f10b28b4cfb42c9bd1349dd

I'm not super familiar with vue compiler neither rollup plugins but it seems that in case of rollup-plugin-vue when the compiler is created (source code) we do not pass information about scopeId. Adding information about current scope should fix that problem :)

Additional information about my findings:
This problem appears only with optimizeSSR: true because that option to gain performance boost on server side will try to optimize render function by parsing you HTML nodes (ex.<div class="style">...</div>) to static string with HTML inside.

Example:

Vue component template:
<template>
  <div class="root_node">
    <div class="sub_node">
      {{ message }}
    </div>
  </div>
</template>


Compiled template to render function:
/* template */
var __vue_render__ = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", { staticClass: "root_node" }, [
    _c("div", { staticClass: "sub_node" }, [
      _vm._v("\n    " + _vm._s(_vm.message) + "\n  ")
    ])
  ])
};


Compiled template to render function with SSR optimization
var __vue_render__ = function() {
  var _vm = this;
  var _h = _vm.$createElement;
  var _c = _vm._self._c || _h;
  return _c("div", { staticClass: "root_node" }, [
    _vm._ssrNode(
      '<div class="sub_node">' +
        _vm._ssrEscape("\n    " + _vm._s(_vm.message) + "\n  ") +
        "</div>"
    )
  ])
};

As far as I noticed on the component root node this optimization is never applied so `scopeId` will be resolved during the actual render process on the server (or client if you don't use SSR) 

If I find some free time this week I will try to contribute to this project :)

Hi Guys, I tried to implement a fix but I found a problem related to TS interface in @vuejs/component-compiler-utils. It seems that all valid options are not present in the type definition.

In vue-loader implementation I found that:
in Line 27 we have defined 2 compilerOptions scopeId and comments
https://github.com/vuejs/vue-loader/blob/master/lib/loaders/templateLoader.js#L27

which are later on passed to compileTemplate from @vue/component-compiler-utils
https://github.com/vuejs/vue-loader/blob/master/lib/loaders/templateLoader.js#L46

However in @vue/component-compiler-utils
https://github.com/vuejs/component-compiler-utils/blob/master/lib/compileTemplate.ts#L38
we have defined TemplateCompileOptions with definition also for VueTemplateCompilerOptions

https://github.com/vuejs/component-compiler-utils/blob/master/lib/types.ts#L33
which unfortunately does not include scopeId nor comments which are used in vue-loader.

It seems that types for the actual compiler (implemented in flow) are much more complex. https://github.com/vuejs/vue/blob/dev/flow/compiler.js

with a lot of options not mentioned in docs for vue-template-compiler.:
https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#compilercompiletemplate-options

On my fork of this repo, I created a fix for that issue assuming that VueTemplateCompilerOptions accepts scopeId as a valid argument. (it's WIP, and was not tested in the bigger app.)
https://github.com/przemkow/rollup-plugin-vue

@znck I would be really grateful if you could give me some hints on how to solve this problem as it's related to multiple repositories and I'm not sure if that CompilerOptions are not visible in the TS interface on purpose.

Options listed in https://github.com/vuejs/vue/blob/dev/flow/compiler.js are all supported but https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#compilercompiletemplate-options lists the public API (this can be outdated as Vue 3 has been the main focus recently).

You can use any option used by vue-loader as we won't intend to break it in any case.

Thanks for answer @znck I opened PR with the fix.

Thanks! This seemed to fix our Nuxt SSR issue.

Was this page helpful?
0 / 5 - 0 ratings