Custom Element (Vue/PrimeVue) doesn't render DOM correctly

82 Views Asked by At

I am trying to create a widget with Vue3, which can be integrated with isolated styles in other websites. I am trying to create it as a custom element. I am using PrimeVue as the component framework. While compiling locally, my test project is rendered correctly. However, when I build it and host the generated js file on a server and embed it in a website, the DOM is loaded incorrectly (InputText-Component isn't displayed. The button, however, does correctly) and I get an error in the console:

TypeError: Cannot read properties of undefined (reading 'config')
in the builded/loaded js-file, in line: "p-variant-filled": e.variant ? e.variant === "filled" : r.$primevue.config.inputStyle === "filled"

  • "primeflex": "^3.3.1",
  • "primeicons": "^6.0.1",
  • "primevue": "^3.49.1",
  • "vue": "^3.4.15"

My Vue projectfiles

App.ce.vue

<script>
import Button from "primevue/button";
import FloatLabel from "primevue/floatlabel";
import InputText from 'primevue/inputtext';

export default {
  name: 'App',

  components: {
    Button, FloatLabel, InputText
  },
}
</script>

<template>
  <header>
  </header>

  <main>
    <FloatLabel>
      <InputText id="username" />
      <label for="username">Username</label>
    </FloatLabel>

    <Button label="Submit" />
  </main>
</template>

<style>
  @import 'primevue/resources/themes/lara-light-green/theme.css';
  @import 'primevue/resources/primevue.min.css';
  @import 'primeflex/primeflex.css';
  @import 'primeicons/primeicons.css';
</style>

widget-entry.js

import {defineCustomElement} from 'vue';
import App from "./App.ce.vue";

const WidgetElement = defineCustomElement(App);
customElements.define('my-widget', WidgetElement);

main.js

import 'primevue/resources/themes/lara-light-green/theme.css'
import 'primevue/resources/primevue.min.css';
import 'primeflex/primeflex.css';
import 'primeicons/primeicons.css'

import { createApp } from 'vue'
import App from './App.ce.vue'
import PrimeVue from 'primevue/config';

import FloatLabel from 'primevue/floatlabel';
import InputText from 'primevue/inputtext';
import Button from "primevue/button";

const app = createApp(App);
app.use(PrimeVue);
app.component('FloatLabel', FloatLabel);
app.component('Button', Button);
app.component('InputText', InputText);

app.mount('#app')

vite-config

import {fileURLToPath, URL} from 'node:url'
import {defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default ({mode}) => {

  const env = loadEnv(mode, process.cwd(), "");

  return defineConfig({
    define: {
      "process.env": env,
    },
    plugins: [
      vue()
    ],
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url))
      }
    },

    //Begin configuration, to compile into one single file
    build: {
      lib: {
        entry: 'src/widget-entry.js',
        name: 'MyWidget',
        fileName: (format) => format === 'umd' ? 'registration-widget.js' : `registration-widget.${format}.js`
      }
    }
  })
}

Embedding into my webpage with

<script src="https://path/to/my/js/file"></script>
<div style="height: 500px; width: auto; overflow-y: auto;">
    <my-widget></my-widget>
</div>

(Incorrect) DOM of my webpage (InputText is missing)

incorrect DOM

(Correct) DOM while local debugging

correct DOM

0

There are 0 best solutions below