I'd like to export some of the components I use in my vue projects as web-component in order to be able to use them on other non-vue projects. I see that vue has support for this, and it exports web-components, but the issue I have is with the css - it is not included (or not useable) when using the exported webcomponent.
In order to make this case easy to reproduce, I'm using the default code generated when creating a new vue js 3 project. And the component I'd like to export as web component is the default App.vue we get with the new project.
Steps to reproduce:
- create a standard vue (I have 3.2) project, with typescript and less.
- Modify the main.ts like this:
import { createApp, defineCustomElement } from 'vue'
import App from './App.vue'
createApp(App).mount('#app'). // this can be commented out
const customApp = defineCustomElement(App);
window.customElements.define('app-component', customApp);
- add a new script in package.json:
"build:wc": "vue-cli-service build --target lib --name AppComponent src/main.ts"
- Modify the vue.config in order to include the style in exported bundle:
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
css: {
extract: false,
}
})
- On HelloWord.vue I added a custom class to the first div (in order to be easier to find it in generated js library code) and inside the css (less in my case) block:
.hello { border: 1px solid green; background-color: #dedede; }
- Run the build: npm run build:wc
This will create a new folder - dist - and inside it will put the exported webcomponent - AppComponent.udm.js is the file we need to import in order to have access to the newly exported component.
- On the public folder I created a simple html file, test.html with this content:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Web-Component</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="../dist/AppComponent.umd.js"></script>
</head>
<body>
<app-component></app-component>
</body>
</html>
When I open this file, in chrome, I can see the webcomponent in my test.html I can see the component, but it has no css applied to it.
I opened the generated AppComponent.umd.js file and I see that the css was added to it (you can see the .hello class and its definition: border:1px solid green;background-color:#dedede):
var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
// Module
___CSS_LOADER_EXPORT___.push([module.id, "h3[data-v-1ac357d5]{margin:40px 0 0}ul[data-v-1ac357d5]{list-style-type:none;padding:0}li[data-v-1ac357d5]{display:inline-block;margin:0 10px}a[data-v-1ac357d5]{color:#42b983}.hello[data-v-1ac357d5]{border:1px solid green;background-color:#dedede}", ""]);
But.... the test.html file doesn't render correctly (as you can see in the following screen capture).
Questions:
How is the correct way to do this? How to export from vue 3 a webcomponent (with subcomponents - like I have in this case App.vue using HelloWordComponent) in order to get it rendered correctly (with css) by the browsers.
Is someone that had this issue? Some ideas? Some documentations/tutorials?
I try to export a VUE component as a webcomponent. I expect to get a full functional component - but I get it without style.
querySelector
, and Frameworks will have to adapt to it. That means Vanilla code is always better.... if you account for your whole component lifecycle. – Howes