Closed SergkeiM closed 3 years ago
Hi @karol-f
I think I've rushed wil pull-request, we could do this in:
beforeCreateVueInstance(root){
const rootNode = root.el.getRootNode();
if(rootNode instanceof ShadowRoot){
root.shadowRoot = rootNode
}else{
root.shadowRoot = document.head;
}
return root;
}
I use document.head
in case shadow dom is not available.
@Froxz do you have an example project demonstrating how the fix works?
I'm trying to extrapolate how to use it for VueCLI 3 users, but webpack refuses to attach the styles to the shadowDOM. It seems that the shadowDOM does not exist yet when webpack tries to inject the styles
Hi @bryanvaz ,
I use laravel-mix
, but a fork because laravel-mix doesn't support yet vue-style-loader
Also becuase css-loader 4+ uses esModule loader and is not yet implemented in vue-style-loader
As you can see there are a lot "but". But here is working code sample:
css-loader
version ^3shadowDom
on vue-custom-element
beforeCreateVueInstance
callback// src/index.js
import Vue from "vue";
import vueCustomElement from "vue-custom-element";
import myComponent from "./components/myComponent";
Vue.customElement('my-component', myComponent, {
shadow: true,
beforeCreateVueInstance(root){
const rootNode = root.el.getRootNode();
if(rootNode instanceof ShadowRoot){
root.shadowRoot = rootNode
}else{
root.shadowRoot = document.head;
}
return root;
}
});
Full list of devDependencies
Note: you don't need to install vue-style-loader
it is included in vue-loader
.
"devDependencies": {
"postcss": "^8.2.2",
"vue-loader": "^15.9.6",
"vue-template-compiler": "^2.6.12",
"css-loader": "^3.6.0",
"laravel-mix": "https://github.com/Froxz/laravel-mix.git#custom-latest",
"sass": "^1.32.0",
"sass-loader": "^10.1.0",
"vue": "^2.6.12",
"vue-custom-element": "^3.2.14"
}
laravel-mix
config
const mix = require('laravel-mix');
mix.js('src/index.js', 'dist/webcomponents.js').vue({
version: 2,
options: {
shadowMode: true
}
});
let me know if you need anything else.
Full example repo: https://github.com/Froxz/webcomponents
P.S. I think if you use Vue CLI it will not work espicially if you target wc
Hi @Froxz,
Ok I think I get it now, your PR isn't necessarily required if you use the beforeCreateVueInstance
.
Theoretically all the pieces are there. Your custom laravel-mix
should just be the same and adding the shadowMode:true
directly to vue-loader
and vue-style-loader
's vue.config.js
Oh target wc
tells vue cli to use the old "official" wc wrapper, which is just barely maintained. A straight target lib
works fine when using karol's library.
Hi @bryanvaz yeap closing the PR, as using beforeCreateVueInstance
does the job.
Hi @bryanvaz yeap closing the PR, as using
beforeCreateVueInstance
does the job.
Should probably create a separate PR to add this to the docs, since running in shadow mode requires users to pass specific code into the Vue.customElement
call (Without the stylings, custom components in shadow mode are pretty useless).
I'm planning on updating the docs myself since there's no clear instructions on how to properly contain a component in the shadow DOM, but I still can't find out why Vue CLI is refusing to inject the styles (both in HMR, straight prod builds, and umd/cjs builds). Theoretically all the correct pieces are there:
css-loader@^3
shadowMode: true
for all vue-style-loader
usesbeforeCreateVueInstance
I've set aside today to try to debug this. For some reason the final injection call for styles in vue-style-loader
is never triggered.
If I can't figure it out, @Froxz can you take a look later this week? I saw you had some open PRs on the same topic in vue-style-loader
and laravel-mix
, so I'm sure you'll be able to find something I missed.
Cheers, Bryan
Hi @bryanvaz Can you make a repo with full example, I will take a look.
@Froxz, I managed to get it working this afternoon.
You can have a look. It was actually quite simple once I paired your beforeCreateVueInstance
fix with my vue.config.js
updates for shadowMode
.
Haven't tested it with Vue 3 or css-modules^4
, but it theoretically should work. I'll update the docs tomorrow.
Right now I'm fighting with vuetify to create an example, however I think the library might be too far gone. Do you have any Material UI or visual primitive libraries which might make a good example of how the shadow DOM isolates visual styles?
Example: https://github.com/bryanvaz/vue-custom-element-shadow-examples (still have to clean up and doc the examples)
Hola @bryanvaz ,
Yo uso
laravel-mix
, sino un tenedor porque laravel-mezcla no apoyo aúnvue-style-loader
También porque css-loader 4+ usa esModule loader y aún no está implementado en
vue-style-loader
Como puede ver, hay muchos "pero". Pero aquí hay una muestra de código de trabajo:
- Necesitas laravel mix con los mismos cambios que mi fork (o usa webpack directamente)
- Necesitas la
css-loader
versión ^ 3- Adjuntar
shadowDom
envue-custom-element
beforeCreateVueInstance
devolución de llamada// src / index.js importa Vue desde "vue" ; importar vueCustomElement de "vue-custom-element" ; importar myComponent desde "./components/myComponent" ; Vue . customElement ( 'my-component' , myComponent , { shadow : true , beforeCreateVueInstance ( root ) { const rootNode = root . el . getRootNode ( ) ; si ( rootNode instanceof ShadowRoot ) { raíz . shadowRoot = rootNode } más { raíz . shadowRoot = documento . la cabeza ; } return root ; } } ) ;
La lista completa de
devDependencies
Nota: no es necesario que la instalevue-style-loader
, está incluida envue-loader
." devDependencies " : { " postcss " : " ^ 8.2.2 " , " vue-loader " : " ^ 15.9.6 " , " vue-template-compiler " : " ^ 2.6.12 " , " css-loader " : " ^ 3.6.0 " , " laravel-mix " : " https://github.com/Froxz/laravel-mix.git#custom-latest " , "descaro " : "^ 1.32.0 " , " sass-loader " : " ^ 10.1.0 " , " vue " : " ^ 2.6.12 " , " vue-custom-element " : " ^ 3.2.14 " }
laravel-mix
configconst mix = require ( 'laravel-mix' ) ; mezclar . js ( 'src / index.js' , 'dist / webcomponents.js' ) . vue ( { versión : 2 , opciones : { shadowMode : true } } ) ;
Déjame saber si necesitas algo más.
Repo de ejemplo completo: https://github.com/Froxz/webcomponents
PD: Creo que si usa Vue CLI, no funcionará especialmente si
target wc
With your example you have saved my life, you should make the pull request of the changes so that laravel-mix takes them into account. Thanks a thousand thanks
Hi,
vue-style-loader
can inject css into shadowDom, what is missing fromvue-custom-element
is reference to this shadowDom.this PR fixes it.
Usage:
Fixes: #214 #191 #156