I am currently working on a Symfony 3 Application with Vite and Vue3 together with TypeScript.
I replaced Symfonys Webpack Encore with the Vite Buildtool using this plugin here:
https://github.com/lhapaipai/vite-bundle
I followed the migration guide initially and it worked before.

I have an assets folder, that contains my components. Everything Vue related lies under assets/vue. My App.ts contains the needed code for my components and App.vue. This is used by Vite. The bundle then let me allow to include the compiled js into my twig files like so:
{% block stylesheets %}
{{ vite_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ vite_entry_script_tags('app') }}
{% endblock %}
To start my application, I need to run npm run dev (vite dev) and symfony serve (symfony server start).
My issue is: My Vue Application is not rendering anymore, Vue Devtools is also not recognizing. I can’t see my components, when I open up localhost:8000/vue.
My console displays me this error message:
app.js:8 Uncaught ReferenceError: exports is not defined
at app.js:8:23
(anonymous) @ app.js:8

Why is this happening? What did I miss – I did not encounter this issue before. Below are my setup files.
I don’t get any error for running vite dev / npm run dev.
My app.vue
<script setup lang="ts">
import BaseLayout from "./layout/BaseLayout.vue";
import StickyBanner from "./patterns/StickyBanner.vue";
import ImageSlider from "./components/image-slider.vue";
import BottomMenu from "./components/bottom-menu.vue";
import NavigationBar from "./components/navigation-bar.vue";
import MasonryGallery from "./components/masonry-gallery.vue";
</script>
<template>
<BaseLayout>
<template #header>
<StickyBanner />
<NavigationBar />
<h1>Header</h1>
</template>
<template #main>
<ImageSlider />
<MasonryGallery />
</template>
<template #footer>
<BottomMenu />
<h1>Footer</h1>
</template>
<slot/>
</BaseLayout>
</template>
<style lang="scss" scoped></style>
My app.ts
/*
* Welcome to your app's main TS file!
*
* We recommend including the built version of this JavaScript file
* (and its CSS file) in your base layout (base.html.twig).
*/
// any CSS you import will output into a single css file (app.css in this case)
import './styles/app.css';
// start the Stimulus application
import './bootstrap';
import 'flowbite';
import {createApp} from "vue";
import App from "./vue/App.vue";
import ModeSwitcher from "./vue/patterns/ModeSwitcher.vue";
import ImageSlider from "./vue/components/image-slider.vue";
import StickyBanner from "./vue/patterns/StickyBanner.vue";
import ServiceInfo from "./vue/components/service-info.vue";
const app = createApp({});
app.component('App', App);
app.component('ModeSwitcher', ModeSwitcher);
app.component('ImageSlider', ImageSlider);
app.component('StickyBanner', StickyBanner);
app.component('ServiceInfo', ServiceInfo);
app.mount('#app');
vite.config.ts
import { defineConfig } from "vite";
import symfonyPlugin from "vite-plugin-symfony";
import vue from "@vitejs/plugin-vue";
/* if you're using React */
// import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
/* react(), // if you're using React */
symfonyPlugin(),
vue(), // write this
],
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
}
},
base: '/build/',
build: {
outDir: './public/build',
rollupOptions: {
input: {
app: "./assets/app.ts",
/* you can also provide css files to prevent FOUC */
styles: "./assets/styles/app.css"
},
}
},
});
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true
},
}
index.html.twig
{% extends 'base.html.twig' %}
{% block title %}Hello VueController!{% endblock %}
{% block body %}
Test
<div>
<div id="app">
<app></app>
</div>
</div>
{% endblock %}
base.html.twig
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
{# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #}
{% block stylesheets %}
{{ vite_entry_link_tags('app') }}
{% endblock %}
{% block javascripts %}
{{ vite_entry_script_tags('app') }}
{% endblock %}
<script>
// On page load or when changing themes, best to add inline in `head` to avoid FOUC
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
console.log('dark')
} else {
document.documentElement.classList.remove('dark')
console.log('light')
}
</script>
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
package.json
{
"devDependencies": {
"autoprefixer": "^10.4.14",
"core-js": "^3.23.0",
"postcss": "^8.4.21",
"postcss-loader": "^7.1.0",
"regenerator-runtime": "^0.13.9",
"tailwindcss": "^3.3.1",
"ts-loader": "^9.4.2",
"unplugin-vue-components": "^0.24.1",
"vue": "^3.0",
"vue-loader": "^17.0.1"
},
"license": "UNLICENSED",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"dependencies": {
"@headlessui/vue": "^1.7.12",
"@vitejs/plugin-vue": "^4.1.0",
"flowbite": "^1.6.5",
"sass": "^1.62.0",
"vite": "^4.2.1",
"vite-plugin-symfony": "^0.7.6"
},
"type": "module"
}