Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we use a builtin tag to recurse self-reference component ? #2827

Closed
luwuer opened this issue Dec 16, 2020 · 7 comments
Closed

Can we use a builtin tag to recurse self-reference component ? #2827

luwuer opened this issue Dec 16, 2020 · 7 comments
Labels

Comments

@luwuer
Copy link
Contributor

luwuer commented Dec 16, 2020

What problem does this feature solve?

Now vue using filename to assert if need to recursive components themselves.

selfname is inferred from filename
https://github.com/vuejs/vue-next/blob/64d4681e4b9d88e17cd1515014866d43d0424d14/packages/compiler-core/src/transforms/transformElement.ts#L266-L273

This way may has these pitfalls:

  1. Will cause some misunderstanding because it prevent user-need-component resolving like Components with same filename (but different directory) are mistaken for each other and cause infinite rendering loop #2821
  2. Will break recurse when changing the filename without reading code.

If we use a builtin tag:

  1. The first pitfall will not appear because user cant register a component named a builtin tag
  2. Changing filename will no longer affect recurse because the recursively self-reference component mechanism is self-consistent.

What does the proposed API look like?

Use a builtin tag instead of filename assertion, tag name maybe:

  1. self
  2. _self
  3. more...

@yyx990803 @posva @edison1105

@luwuer luwuer changed the title Can we use a builtin tag to recursively self-reference component ? Can we use a builtin tag to recurse self-reference component ? Dec 16, 2020
@posva posva added ✨ feature request New feature or request scope: compiler labels Dec 19, 2020
@posva
Copy link
Member

posva commented Dec 19, 2020

I would say in practice, naming a component the same in different folders is a bad practice (https://v3.vuejs.org/style-guide/#tightly-coupled-component-names-strongly-recommended and all the naming recommendations).

In Vue 2, we used to need a name on the recursive component. Not needing it anymore looks like an improvement but brings the mentioned problems.
What I find problematic is that giving the outer component a name different that its filename does not prevent it to refer to itself on the template:

<template>
  <h1>OUTER COMPONENT</h1>
  <Foo />
</template>
<script>
import Foo from '../inner/Foo.vue'
export default {
  name: 'OuterFoo',
  components: { Foo },
}
</script>

<Foo/> will render this component infinitely

@daniesg
Copy link

daniesg commented Feb 17, 2021

At the very least a console warning would be nice. This would be a very difficult bug to fix in a larger app.

@edison1105
Copy link
Member

ping @HcySunYang @posva @yyx990803

@Philipp-M
Copy link

While it might be a bad practice to name multiple components with the same name, it can indeed be difficult to fix such issues with big codebases (took us some time to find this issue).
And there may be valid use-cases to name components with the same name. E.g. having a views directory and a models directory without having to postfix each component filename with "...View" or "...Model" The directories should be enough to act as a namespace for the components.

@thexeos
Copy link

thexeos commented Mar 24, 2021

Even with moderately sized code-base this suddenly popped up in a few places for us after trying vue/next. Webpack hot-reload took the initial blame, as it seemed the file itself was not being properly loaded (parent component being loaded in place of the child component with the same file-name).

For us, the use case was the self-contained components displayed as separate pages. For example, there is Privacy Policy dialog box under "components", and then there is Privacy Policy page, under "pages". Both file names make sense as just PrivacyPolicy.vue, yet including a "component" on the "page" causes unexpected recursion. The same applies to other simple "footer" pages like T&C, About, Contact.

@HcySunYang
Copy link
Member

@luwuer Can you draft an RFC? If you don't have time, I can do this instead

yyx990803 added a commit that referenced this issue Mar 26, 2021
@yyx990803
Copy link
Member

Since the inferred filename is actually causing breakage, I adjusted its priority in abd129d and it is now used as a fallback only when normal resolution fails.

The issue with adding another built-in tag is that it could technically be a breaking change. I think with the fix in abd129d, it is no longer strictly necessary. If we do want something like that, <component self/> maybe a safer option here.

@github-actions github-actions bot locked and limited conversation to collaborators Oct 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

8 participants