Symfony using Vite with Vue 3 encounters an error: Uncaught ReferenceError - exports is undefined

Currently, I am in the process of developing a Symfony 3 Application with Vite and Vue3 integrated with TypeScript.

To replace Symfony's Webpack Encore, I opted for the Vite Buildtool using this convenient plugin: https://github.com/lhapaipai/vite-bundle

Initially, I followed the migration guide and everything was working smoothly. However, now I seem to be facing an issue where my Vue application is not rendering as expected. Vue Devtools also fail to recognize it. Even when accessing localhost:8000/vue, I am unable to see my components.

The console throws me this error message:

app.js:8 Uncaught ReferenceError: exports is not defined
    at app.js:8:23
(anonymous) @ app.js:8

I'm unsure why this is happening all of a sudden. Could there have been something that I missed during the setup? Below are the details of my configuration files.

In case you're wondering, I don't encounter any errors while running `vite dev / npm run dev`.

This is how my `app.vue` looks like:

<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>

Here's how my `app.ts` file appears:

/*
 * 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');

For my vite configuration settings, they look like this in `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"
            },
        }
    },
});

This is how my `tsconfig.json` file is configured:

{
  "compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true,
    "sourceMap": true
  },
}

And finally, here are the contents of my `index.html.twig` file:

{% extends 'base.html.twig' %}

{% block title %}Hello VueController!{% endblock %}

{% block body %}
Test
<div>
    <div id="app">
        <app></app>
    </div>
</div>
{% endblock %}

As for my `base.html.twig` template, it looks like this:

<!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>

Last but not least, here's what my `package.json` contains:

{
  "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"
}

Answer №1

It is possible that the issue stems from your package.json file.

{
  "module": true
}

Your ESM environment might not be recognizing a variable specific to CommonJS. Have you considered renaming your configuration file to vite.config.cjs? Alternatively, removing "module": true (although this may not be a good idea due to upcoming changes in Vite.js version 5). I recall reading about a similar issue with vite-plugin-symfony in its previous versions - perhaps updating to version 6 could help resolve it?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Rearrange elements in an array

Currently, I have an array of sphere meshes and I am looking for a way to position them in a level. The meshes are currently set in a specific position (in the shape of a skeleton), but I would like to move the entire array and place it in a different loca ...

The syntax for specifying the post body content in frisby.js is important

My current setup involves smooth UI and server data exchange, but I am interested in exploring new development possibilities with Frisby.js. The UI utilizes a JavaScript form manager powered by jQuery. To send the request body, I first serialize a JavaScri ...

Is it possible to write a text file in UTF-16 using Javascript?

I need to create a UTF-16 text file from a string. For instance: var s = "aosjdfkzlzkdoaslckjznx"; var file = "data:text/plain;base64," + btoa(s); The above code generates a UTF-8 encoding text file. How can I modify it to produce a UTF-16 text file usin ...

Implementing a translucent overlay onto a specific HTML section using sidebar.js/jQuery

Searching for a way to enhance the functionality of my website using Sidebar.js, I came across an interesting feature on hypebeast.com. When you click on the three-bar icon, the main container section's opacity changes. How can I achieve this effect? ...

Encountered in the Angular library: NG0203 error stating that inject() should only be invoked within an injection context like a constructor, factory function, or field initializer

Having recently updated my Angular project from version 9 to 15, I encountered the following issue. Any assistance would be greatly appreciated as I have been struggling with it for over 2 weeks. The problem lies within app-lib.module.ts in the Angular li ...

Relay information between requests using a RESTful API and various data formats, such as JSON, XML, HTML

In a scenario with a REST API that can deliver JSON, XML, HTML, and other formats, the default response for browsers without JavaScript enabled is HTML. This API utilizes tokens for authentication and authorization. Within a traditional website project, t ...

What steps can be taken to repair the script?

https://jsfiddle.net/fnethLxm/10/ $(document).ready(function() { parallaxAuto() }); function parallaxAuto() { var viewer = document.querySelector('.viewer.active'), frame_count = 5, offset_value = 500; // init control ...

Displaying country-specific API details (such as capital and currency) in a card container when selecting a country from a dropdown menu

My objective is to display the card information for South Africa as the default value, even before entering any country's name into the search bar input field or selecting a specific country from the provided list. I am utilizing the restcountries API ...

Restrict the Angular ng-repeat directive to specific rows only

Suppose we have a JSON dataset listing all languages of books: $scope.data = [{ "title": "Alice in wonderland", "author": "Lewis Carroll", "lang": ["en"] }, { "title": "Journey to the West", "author": "Wu Cheng'en", "lang": [" ...

Transitioning from JSTL's forEach loop to angular.js's ng-repeat functionality during the spring season is like switching your

I am just getting started with angular.js. I currently have a spring MVC application and I want to transition from jstl to angular.js. This is how I began the process: <table> <c:forEach var="list" items="${list}"> <tr c ...

Issues with Toggling Visibility in HTML, CSS, and Javascript

Currently, I am working on a website and following a tutorial called "Creating Slideshow using HTML, CSS, and Javascript" by W3Schools. In the project, I want to hide the thumbnail images located at the bottom and the navigation arrows initially and have t ...

Upon running the command "React + $ npm start," an error occurred with the code 'ERR_OSSL_EVP_UNSUPPORTED' related to opensslErrorStack

When running $npm start, an error is being thrown: opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ], library: 'digital envelope routines', reason: 'unsupported', code: 'ERR_OSSL_EVP_ ...

How to display a page outside the router-outlet in angular 4

I'm currently developing an angular 4 application and I am trying to figure out how to load the login.page.ts outside of the router-outlet This is what my home.component.html file looks like: <div class="container"> <top-nav-bar></ ...

Automatically submitting the selection when it changes

I am facing an issue with a selection form that is supposed to update the database on change using jQuery, but it seems like nothing is happening. Can anyone provide assistance with this problem? <SELECT name='status' id='status'> ...

What is the best way to transition all elements down while sliding a header up or down?

Is it possible to bring down the entire page when hovering over a header element using CSS, ensuring that the header overlaps nothing else on the page? If so, how can this be achieved? See an example of the header in action here: Thank you! ...

Using Angular JS to manage multiple views with a single controller

Would it be considered best practice to use one controller, yet have two distinct HTML file templates that present the same data in different formats? Essentially, I require a slightly altered template for displaying content in a modal dialog and another ...

How can I retrieve my cropped image using Symfony2 Cropit?

My experience with this plugin has been disappointing. As someone new to JS/Jquery, I really needed this plugin for my website. That's why I came across cropit here: I struggled to figure out how to retrieve my cropped image in my controller and save ...

Error message: Material Design UI - The type 'string' cannot be assigned to the type Icon

I am currently working on a component that is responsible for returning the specific icon based on the prop that is passed. Here is a simplified version of how it works in my application: import * as icons from "@mui/icons-material"; interface I ...

Creating a nuxt.js application from scratch without using create-nuxt-app

I am interested in learning how to build a Nuxt app without using the create-nuxt-app template. As a beginner, I would like to start a new project with Vue.js and then gradually integrate Nuxt functionality into it. I have searched online but haven't ...

Ways to resolve the issue: The property 'X' is not recognized on the '{ object }' data type

Just getting started with vuejs and encountering an error in my vue file Issue: Property 'ClientsSrv' is not recognized on type '{ name: string; props: {}; data(): { ClientsSrv: ClientsService | null; ClientsList: ClientsModel[] | null; IsR ...