Web Components encorperating Vuetify a la carte ignore style, even when bundled together via rollup
SumNeuron opened this issue · 3 comments
Cool stuff you're doing here.
How I got here:
- Created empty project repo:
mkdir test && cd test
- Created fresh project via
vue-cli
:vue create dev
- Added Vuetify to project:
cd dev && vue add veutify
- Pulled config files from
test/dev
up totest
- Updated
vue.config.js
to point to new location:
//vue.config.js
{
//...
pages: {
index: {
entry: 'dev/src/main.js',
template: 'dev/public/index.html',
filename: 'index.html',
}
},
}
- Made a very simple component
CountButton.vue
which is just a wrapper of the Vuetify component<v-btn>
imported a la carte (seetest/dev/components/CountButton.vue
) - tried mounting multiple instances of the component
CountButton
indev/src/main.js
e.g.
// dev/src/main.js
// ...
import CountButton from './components/CountButton.vue'
new Vue({
store,
vuetify,
render: h => h(CountButton)
}).$mount('#app')
new Vue({
store,
vuetify,
render: h => h(CountButton)
}).$mount('#app2') // <--- copy pasted <div id="app"> and gave it new id "app2" in `public/index.html`
- Noticed that direct mounting this way does not work as expected (
CountButton.vue
was mounted and data was reactive in Vue inspector, but not the template) - Updated
dev/src/App.vue
to contain justCountButton.vue
- Tried the multi-mount, and that works.
- Copy pasted the file
dev/src/App.vue
todev/src/App0.vue
and tried mounting theApp0
component. This failed in the same manner as (8) as thevue-cli
targetsdev/src/App.vue
as the entry point. - Tried to then convert component to a WebComponent by adding the following
package.json
"build:wc": "npx vue-cli-service build --target wc --name pub 'dev/src/components/*.vue'",
-
inspected the resulting
dist/pub.min.js
anddist/demo.html
files and noticed the component regained its dynamic template - error from (8) - but lost all styling -
Thought that this may be due to Vuetify styles not being bundled with the the Vuetify component
-
Setup rollup to try and force the CSS to be bundled with the component (see
rollup.config.js
,dev/src/rollup.entry.js
andpackage.json
) -
then I rolled up
npm run build:r
-
then I tried to use the component: (
dist/demo.html
) -
Am back to where I was at step (13); namely, I have WebComponents, but despite bundling
vuetify.min.css
with theCountButton.vue
component, but no styling.
This belabored process raises two questions:
- How to mount multiple components (not App.vue) in main.js from vue-cli3
- How to rollup Vue Components that are built on top of Vuetify.js to keep their styling and functionality outside of
The former is related more to vue-cli
(but if you know the answer I'd appreciate it)
The latter is where my issue comes from.
How can I have @vue/web-component-wrapper
convert my component and either include the requisite styles or use the stylesheets from a cdn?
a MWE repo to help figure this out can be found here
I have tried a bunch of stuff
// rollup.entry.js
let components = {
CountButton
}
// BEGIN: @vue/web-component-wrapper
// helpers for registering with window
const pascalToKebabHelper = (x, y) => `-${y.toLowerCase()}`
const pascalToKebab = (str) => {
return str.replace(/\.?([A-Z]+)/g, pascalToKebabHelper).replace(/^-/, "")
}
let GlobalVue = null;
let GlobalVuetify = null;
// define webcomponents
if (typeof window !== 'undefined') {
// vue / vuetify from cdn
GlobalVue = window.Vue;
GlobalVuetify = window.Vuetify
let vuePlugins = GlobalVue._installedPlugins
let vuetifyFound = false
for (let i = 0; i < vuePlugins.length; i++) {
let plug = vuePlugins[i]
if (plug.name === 'Vuetify') {
vuetifyFound = true // Vue.$_vuetify_installed = true, but Vue._installedPlugins[0].installed = false
// tried manually installing vuetify, didn't work
// if (plug.installed === false) {
// plug.install()
// plug.installed = true
// }
break
}
}
if (!vuetifyFound) {
// GlobalVue.use(plugin);
GlobalVue.use(GlobalVuetify)
}
console.log(GlobalVue)
Object.keys(components).forEach(name=>{
let htmlTagName = pascalToKebab(name) // <--- too lazy to wrangle pascal to kebab case
// let vueWebComponent = wrap(new Vue({}), components[name]) // tried new Vue but complains about constructor
let vueWebComponent = wrap(GlobalVue, components[name]) // this doesn't work with vuetify
window.customElements.define(htmlTagName, vueWebComponent)
})
}
// END: @vue/web-component-wrapper
Loading the .css in the component. It worked for me.
<template>
<div>
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet" />
.
.
.
<div>
<template>
@SumNeuron have you ever found a solution for this?