2

I ran into an issue that had me scratch my head for a few days now. I am doing a application with vuejs3 frontend.

For all the code I provide I removed the most other code and kept what I think is relevant to make it more readable. If you need more information let me know and I update the question with it.

My main js:

import { createApp } from 'vue';
import App from './App.vue';
import router from './router.js';

const app = createApp(App);
app.use(router);
app.mount('#app');

This is my App.vue:

<template>
  <div>
    <!-- if I put <Userbasket /> here it works -->
    <div>
      <router-view v-slot="{ Component }">
        <Transition mode="out-in">
          <component :is="Component"/>
        </Transition>
      </router-view>
    </div>
  </div>
</template>
<script>

export default {
  name: 'App',
}
</script>

Relevant vue router:

import { createRouter, createWebHistory } from 'vue-router';
import HomeView from "@/views/Home.vue";

const routes = [
  {
    name: 'home',
    path: '/home',
    component: HomeView,
  },
  {
    name: 'root',
    path: '/',
    redirect: '/home',
  },
];
const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes: routes
});

export default router;

And my Home.vue:

<template>
  <div class="d-flex p-2">
    <div class="row-12 mb-2">
      <WeekSummary />
    </div>
    <div class="row-12 mb-2">
      <!-- here it doesn't work, thrown warning in console -->
      <UserBasket />
      <!-- OtherComp renders correctly -->
      <OtherComp/>
    </div>
  </div>
</template>

<script>
import WeekSummary from '@/components/WeekSummary.vue'
import UserBasket from '@/components/UserBasket.vue';
import OtherComp from '@/components/OtherComp.vue';

export default {
    name: 'HomeView',
    components: {
      WeekSummary,
      UserBasket,
      OtherComp,
    }
};
</script>

And the component I am trying to render UserBasket.vue:

<template>
  <div>
    ... lots of div and span ...
  </div>
</template>

<script>
// no child component
export default {
  name: 'UserBasket',
}
</script>

And my directory structure:

src
|-components
| |-UserBasket.vue
| |-Popup.vue
| |-WeekSummary.vue
| |-OtherComp.vue // and more
|-views
| |-Home.vue
| |-OtherView.vue // and more
|-App.vue
|-main.js
|-router.js

So what I try is to render the UserBasket component, but I getting the error that in the title. Whats weird that I have 20+ components and this is the only one that do not want to get rendered.

The UserBasket component is actually inside the WeekSummary component but I moved it up into HomeView trying to debug this and the error is still appear so kept it there for simplicity. I also tried moving it to the root component in App.vue and there it renders without a problem, so I don't think there is a typo like other SO question answers suggest. I also copied the import statement from the child component where the error appear to the App.vue to make it sure its not a typo.

During development I use npm run serve to run it so it hotreloads if I change a file. When I save the UserBasket.vue file it hotreloads and it actually can import it and render it correctly whitout a warning, so this is also why I think there is no typo. But if I reload the page the component does not render again.

I tried building the app with npm run build and the built version also have this issue.

I also tried putting an other component next to UserBasket and the other renders correctly. The other component is in the same folder with UserBasket and I used the same path declaring method. "@/components/OtherComp.vue" like "@/components/UserBasket.vue" so I dont thin it is a path issue. I also tried the path "./components/UserBasket.vue" and "./UserBasket.vue" in the WeekSummary.vue.

I want to mention that In WeekSummary I have another component "Popup.vue" that is renders correctly and the "Popup.vue" file is next to UserBasket.vue in the components folder

my vue versions are:

    "vue": "^3.4.31",
    "vue-router": "^4.2.5",

And I also tried downgrading down to 3.3.0 the issue is still there.

UserBasket is used 3 places and none of the work. in the loaded site inspecting the HTML DOM in the browser there is the <userbasket></userbasket> tag where is should be.

The console warning is throw from three different lines for each location where I used UserBasket.

  • One form the main.js app.use(router); line.
  • Second from my auth.js file form a line where I put data from an axios response: this.user = response.data; I dont know why it is here.
  • and my third is from my socket.js file from saving a data from a websocket basket.basket = data.basket;

Note that at the second and third one I save data into a pinia store object. At this point I don't know what is relevant or not.

My vue.config.js if it matters:

const { defineConfig } = require('@vue/cli-service');
const packageJson = require('./package.json');


module.exports = defineConfig({
  chainWebpack: (config) => {
    // Set environment variables for Webpack
    config.plugin('define').tap((args) => {
      args[0]['process.env'].VUE_APP_VERSION = JSON.stringify(packageJson.version);
      return args;
    })
  },
  configureWebpack: {
    devServer: {
      historyApiFallback: true
    }
  },
  transpileDependencies: true
});

What I tried from other SO related question:

  • made sure that I have a single root component inside UserBasket
  • checked for typo in component name and path
  • made sure the component registration is in components and not component
  • checked other browsers, and made sure no cache involved
  • I did tried on another machine(a pi 3 I had laying around) and the issue is there as well
  • I also tried different browsers and refreshing the site with shift + f5.

Thank you for reading my question, let me know if you need more information.

Update

In the browser, no other vue warning displayed only an Feature flag one:

Feature flag __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined. You are running the esm-bundler build of Vue, which expects these compile-time feature flags to be globally injected via the bundler config in order to get better tree-shaking in the production bundle.

Trying @yoduh's suggestion(Thank you) to remove code to simplify the UserBasket componet, I removed every use of my pinia store from my component(that where the warnings are thrown) saved the file. No warning displayed in the console, and my component rendered fine. So I guess I the pinia state object is breaks somwhere.

To further investigate I tried removing only my basket store entirely from UserBasket and no warning thrown and the component rendered fine. I found out that simply having the import line in the component will break the reference somehow. I tried to remove every line from the whole projcet where I update the basket value but nothing changed.

I also tried commenting out all getter and action method in the store, but it did not change anything.

In WeekSummary I had a vue watch statement defined for my auth store, removed it and it get rid of one of the warnings that was pointed to the auth.js store file. My guess from this is somewhere I try to update the basket store's value but I am not sure. The only warning(this appears 4 times in a row) left is pointing to the app.use(router) line in my main.js. Another thing to note that the pinia default log 🍍 "basket" store installed 🆕 dont get printed printed in the console for any of my stores. With the vue devtools browser extension, I can see my stores are there with valid values.

Commenting out the use of UserBasket inside WeekSummary reduces the warning count from 4 to 1 and the pinia loglines are logged in console. The only use of UserBasket left is in the Home.vue file for debugg purpses for this issue.

I didn't found any issues on pinia's github page regarding this.

My basket.js if it helps:

import { defineStore } from 'pinia'
import { useAuth } from "@/stores/auth";
import { state as vuestate, socket } from "@/socket.js";
// other nonrelated imports...

export const useBasket = defineStore('basket', {
  state: () => ({basket: {}}),
  getters: {
    // my getters...
  },
  actions: {
    // my actions...
  }
})

Update 2

I successfully created a repro on playcode.io: https://playcode.io/1932830

What I want to note is:

  • I don't know how hot reload works on this site, sometimes it just works when I load the site. Pressing the green arrow then restart or hard restart will cause the warning to appear. Also sometimes pressing the restart fixes it, pressing it again will break it again.
  • In my local environment I don't have the ReferenceError: setImmediate is not defined error in the console like on this site.
  • I commented above some import statement that if I remove that import by commenting it out the issue is fixed. But of course in the full project I use them, they are not just there.

Update 3

The main reason that the solution was hard to find that in my local dev environment the ReferenceError was not shown in my console which made it impossible or at least very hard to find similar SO questions. This was a huge hint. The error was displayed on the repro link which let to solving the issue. Hope others find this usefull.

4
  • A component working after hot reload but not after full page refresh is usually a symptom of broken reactivity. It may be a problem somewhere in the script code of the UserBasket component. Are there any other warnings or errors in console? To confirm the problem being with the component's script code, remove all code from the component and make it as simple as possible. Does it render?
    – yoduh
    Commented Jul 7 at 16:00
  • In current form the question does not provide a way for anyone to repro the issue, making it impossible to debug or test potential fixes. I suggest creating a runnable minimal reproducible example on codesandbox.io or similar. If you can't produce a runnable snippet, at least provide a repo link.
    – tao
    Commented Jul 9 at 16:35
  • 1
    This question is similar to: Why ReferenceError: setImmediate is not defined, when I'm not using it at all?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem.
    – tao
    Commented Jul 10 at 23:31
  • @tao I updated the question why I think it is not similar, if you still think it is thats ok. Do you think it would improve the question readability if I removed the code blocks? The code can be found in the repro link so it would be still accessible in the question. But it would be from a thirdparty service. Let me know
    – Tarakos
    Commented Jul 11 at 15:22

1 Answer 1

1

The error comes from socket.js and UserBasket.vue happens to be the one importing it, via store/basket.js.

The fix, in your case:

  1. Install setimmediate polyfill:
npm i setimmediate
  1. In socket.js:
import 'setimmediate'
  1. In main.js
import { socket } from './socket'

...
export { socket }
  1. in basket.js:
import { socket } from '../main'
// not from '../socket' !!!

See it working.

2
  • So everywhere I use socket I need to import it from main if I understand it correctly?
    – Tarakos
    Commented Jul 11 at 7:39
  • @Tarakos, that's correct. I don't know why, but if you load socket.js into a store before the app is instantiated, you get the error. By re-exporting socket from ./main we make sure the app instance exists before socket code is used.
    – tao
    Commented Jul 11 at 14:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.