karol-f / vue-custom-element

Vue Custom Element - Web Components' Custom Elements for Vue.js
https://karol-f.github.io/vue-custom-element/
MIT License
1.97k stars 187 forks source link

[Question] Is it possible to add scss styles to the shadow dom? #191

Closed supproduction closed 4 years ago

supproduction commented 4 years ago

Is it possible to add scss styles to the shadow dom?

Like vue-web-component-wrapper at turned on appropritate shadow dom options in the 'vue-loader' and 'vue-style-loader'?

karol-f commented 4 years ago

I didn't test it but should be possible:

import styles from 'styles.scss'

And then put it to shadowCss option using (if needed) raw webpack loader.

Regards

supproduction commented 4 years ago

But in this case, when I have reused component

import SprykerButton from '../spryker-button/spryker-button.vue';

    @Component({
        components: {
            SprykerButton
        }
    })

it has imported without styles. Do you have workaround to this?

karol-f commented 4 years ago

Hi, currently You can import CSS/SCSS file using different Webpack loaders and put it into shadowCss option.

If You want to get styles from SFC (Single File Components), I currently don't know how to do it. There was some query option in vue-loader when importing Vue files to get only styles but probably it was removed. I'll try to check.

supproduction commented 4 years ago

I resolved importing css/scss, but while we are importing one component into another, there are no styles for imported compoent. Ок, check it please. Cause your plugin looks more promising then web-component-wrapper.

Maybe should we reopen this topic in this case?

karol-f commented 4 years ago

Can You please prepare example repository or more in depth example of the issue with importing scss files?

supproduction commented 4 years ago

Yes, please https://github.com/supproduction/vue-example

karol-f commented 4 years ago

From a quick look, for styles inside other components (import as standard vue component) maybe use same technique as You import .ts file - <style src="./style.css"></style> inside.vue file?

supproduction commented 4 years ago

In this case vue-loader give an error when I am trying to turn on shadowDomMode

supproduction commented 4 years ago
  1. slots are broken and it works without styles if shadowCss turned off

    Vue.customElement('spryker-button', new SprykerButton().$options, {
    shadow: true
    });

    image

  2. When I am triyng turn on shadowMode at the loaders a have an errors image

image

DrMabuse23 commented 4 years ago

Yes, please https://github.com/supproduction/vue-example

url no longer available ?

DrMabuse23 commented 4 years ago
// [read](https://medium.com/@royprins/get-started-with-vue-web-components-593b3d5b3200)

function enableShadowCss(config) {
  const configs = [
    config.module.rule('vue').use('vue-loader'),
    config.module.rule('css').oneOf('vue-modules').use('vue-style-loader'),
    config.module.rule('css').oneOf('vue').use('vue-style-loader'),
    config.module.rule('css').oneOf('normal-modules').use('vue-style-loader'),
    config.module.rule('css').oneOf('normal').use('vue-style-loader'),
    config.module.rule('postcss').oneOf('vue-modules').use('vue-style-loader'),
    config.module.rule('postcss').oneOf('vue').use('vue-style-loader'),
    config.module.rule('postcss').oneOf('normal-modules').use('vue-style-loader'),
    config.module.rule('postcss').oneOf('normal').use('vue-style-loader'),
    config.module.rule('scss').oneOf('vue-modules').use('vue-style-loader'),
    config.module.rule('scss').oneOf('vue').use('vue-style-loader'),
    config.module.rule('scss').oneOf('normal-modules').use('vue-style-loader'),
    config.module.rule('scss').oneOf('normal').use('vue-style-loader'),
    config.module.rule('sass').oneOf('vue-modules').use('vue-style-loader'),
    config.module.rule('sass').oneOf('vue').use('vue-style-loader'),
    config.module.rule('sass').oneOf('normal-modules').use('vue-style-loader'),
    config.module.rule('sass').oneOf('normal').use('vue-style-loader'),
    config.module.rule('less').oneOf('vue-modules').use('vue-style-loader'),
    config.module.rule('less').oneOf('vue').use('vue-style-loader'),
    config.module.rule('less').oneOf('normal-modules').use('vue-style-loader'),
    config.module.rule('less').oneOf('normal').use('vue-style-loader'),
    config.module.rule('stylus').oneOf('vue-modules').use('vue-style-loader'),
    config.module.rule('stylus').oneOf('vue').use('vue-style-loader'),
    config.module.rule('stylus').oneOf('normal-modules').use('vue-style-loader'),
    config.module.rule('stylus').oneOf('normal').use('vue-style-loader'),
  ];
  if (!process.env.BUILD_MODE) {
    process.env.BUILD_MODE = config.store.get('mode');
  }
  configs.forEach(c => c.tap(options => {
    if (options && options.shadowMode) {
      options.shadowMode = true;
    }
    return options;
  }));
}

module.exports = {
  css: {
    modules: true
  },
  // https://cli.vuejs.org/guide/webpack.html#chaining-advanced
  chainWebpack: config => {
    enableShadowCss(config);
    config.resolve.symlinks(false)
  },
}

i do this for enable shadow dom in the vue.config.js

supproduction commented 4 years ago

@DrMabuse23 Hello. Sorry for delay. Actually I am using webpack vue compiler not vue cli. I have created another one repo https://github.com/supproduction/vue-custom-element-shadow-dom-issue I hope it will help you

karol-f commented 4 years ago

I will try to get styles as described in vue-loader docs: import style from 'source.vue?vue&type=style&index=1' https://github.com/vuejs/vue-loader/blob/master/README.md

Unfortunately end of the year don't make it easy to find spare time. Regards

supproduction commented 4 years ago

Ok, thanks in any case

supproduction commented 4 years ago

@karol-f Also pay attention to the slots - it has broken now. I reproduced it at the repo above

ankurk91 commented 4 years ago

I was able to do it like

import PencilButton from './Button.vue';
import ButtonStyles from '!!raw-loader!sass-loader!./button.scss';

Vue.customElement('x-pencil-button', PencilButton, {
  shadow: true,
  shadowCss: ButtonStyles
});

Notice , i am chaining raw-loader with sass-loader, raw loader will return styles as string which you can pass into arguments. Notice: !! this will prevent webpack from applying other loader configured in webpack.config.js

karol-f commented 4 years ago

@ankurk91 thanks for sharing!

supproduction commented 4 years ago

@ankurk91 Yes, it works. But if we want to reuse PencilButton in the Vue ecosystem, component will be without styles. Like this

.....
components: {
        PencilButton
}
.....
nicod-pc commented 3 years ago

@supproduction Have you found a solution? Or why did you close it?

karol-f commented 3 years ago

@supproduction Have you found a solution? Or why did you close it?

What is wrong with https://github.com/karol-f/vue-custom-element/issues/191#issuecomment-569428185 ?

nicod-pc commented 3 years ago

What is wrong with #191 (comment) ?

Because this:

@ankurk91 Yes, it works. But if we want to reuse PencilButton in the Vue ecosystem, component will be without styles.

sounds like it doesn't solve the problem if you reuse a component as sub component.