Components with same filename (but different directory) are mistaken for each other and cause infinite rendering loop
Version
3.0.4
Reproduction link
https://github.com/jakesgordon/vue-infinite-loop-bug
Steps to reproduce
- Create an empty vue project
- From your App component include a custom component from
./outer/Foo.vue
- From your outer component include an inner component from
./inner/Foo.vue
- Expected: The App is rendered with the outer component containing the inner component
- Actual: The outer component is rendered in an infinite loop and a "Maximum call stack size exceeded" error occurs.
What is expected?
It should render the outer component that contains the inner component and we should see...
OUTER COMPONENT
INNER COMPONENT
What is actually happening?
It renders the OUTER COMPONENT repeatedly in an infinite loop and raises a "Maximum call stack size exceeded" error
This only seems to happen if (a) the filenames are the same (in this case both Foo.vue) AND (b) the outer component imports the inner component using the same name (in this case Foo). If the filenames vary in any way this bug is not reproducible, or if the outer component imports the inner component with a different name (Bar) then this bug is not reproducible.
I ran into this bug in the context of having an outer
I'm 99% sure this was working for me for a couple of weeks and something happened today that broke but I'm unable to identify exactly what changed.
Of course there is a simple workaround for me to be more explicit in my naming and actually call them LoginPage vs LoginForm
FYI: I'm on Ubuntu Linux and testing in both Chrome and Firefox latest. I hit this in a project using Snowpack, but this repro case was developed using a simple Vite project.
Don't need to have the same filename, just make sure that the parent and child components keep the same component name.
You need to name them differently. Using a component in its own template allows for recursive components
It is indeed done deliberately. If we compare filename
here, maybe we can avoid this problem.
Strange timing, but I bumped into a very similar issue yesterday, and have spent the past day trying to reduce my code down to isolate the issue.
The main difference with my issue is that I'm name
ing the component differently in the two different components, which I thought would get around the recursion issue. And the other difference being that this is only happening in some built versions not all, and not at all locally.
I had a setup like this (simplified example):
// src/components/Modal.vue
<template>
<div>
<slot></slot>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "Modal",
});
</script>
// src/views/Home/Modal.vue
<template>
<Modal>
<p>Hello this is the home modal</p>
</Modal>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import Modal from "@/components/Modal.vue";
export default defineComponent({
name: "HomeModal",
components: {
Modal,
},
});
</script>
Despite the name
property on the component being different and them being in different directories, the fact the name of the file for both is Modal.vue
caused the error RangeError: Maximum call stack size exceeded
.
This error only occurred when the files were built, not when serving for localhost. Strangely, it didn't always occur in built versions. When I was building with docker locally the issue didn't come up, but it did when building the docker image on Jenkins. This leads me to think that maybe it's due to a recent node version change. We use node:lts-alpine
in the image, and so it may well be using different versions of node on my local machine vs Jenkins. The fact that this issue was created 12 hours ago and I discovered the problem yesterday, makes me think the bug has been recently introduced and is probably related to that.
note: I'm using vue
version 3.0.3
.
@fredrivett It's relate to version of @vue/compiler-sfc
.
Using a component in its own template allows for recursive components after this commit 67d1aac6ae683a3a7291dff15071d1eeacb7d22a.
I think it works fine in v3.0.3
.
if use "@vue/compiler-sfc": "3.0.4"
will be encountered this problem.