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

cannot import * as components from '#components' any more #20733

Closed
silverbackdan opened this issue May 8, 2023 · 6 comments
Closed

cannot import * as components from '#components' any more #20733

silverbackdan opened this issue May 8, 2023 · 6 comments

Comments

@silverbackdan
Copy link

silverbackdan commented May 8, 2023

Environment

  • Operating System: Darwin
  • Node Version: v16.16.0
  • Nuxt Version: 3.4.3
  • Nitro Version: 2.4.0
  • Package Manager: npm@8.11.0
  • Builder: vite
  • User Config: -
  • Runtime Modules: -
  • Build Modules: -

Reproduction

In a component I am using

import * as components from '#components'

And had been creating a computed ref like so

const resolvedComponent = computed(() => {
  if (props.uiComponent) {
    return props.uiComponent
  }

  if (!components || !Object.keys(components).includes(uiComponent.value)) {
    return
  }
  // eslint-disable-next-line import/namespace
  return components[uiComponent.value]
})

Describe the bug

Now when the computed ref is called components is undefined

Additional context

I'm not sure if it's related to this or not?
#20547

Additionally, if there is a better way to check for a global component within another component by name and return said component for use in aa dynamic <component> component, that'd be great to know.

If that sentence isn't too confusing.

Logs

No response

@silverbackdan
Copy link
Author

My fix for now has been to do this:
components-web-app/cwa-nuxt-module@d77ac94

I think it'd be good to create the components registered in my module to be able to be imported from a file alias like I had been doing with #components but best practices or suggestions always welcome if you can spare a moment. I'm not sure I like the idea of auto registering these components as global for this functionality - it seems a bit hacky.

@danielroe
Copy link
Member

danielroe commented May 8, 2023

importing all components via (import * as components) will include them all in the bundle - you might as well mark them global.

I think we can also transform this import but it's definitely not behaviour we'd advise in any case, for the negative performance reasons ...

cc: @antfu

@danielroe danielroe changed the title BC Break 3.4.3 import * as components from '#components' cannot import * as components from '#components' any more May 8, 2023
@silverbackdan
Copy link
Author

OK I understand thank you :)
Perhaps having namespaced components for lazy importing would be my preference. I think I need to try and figure out the best way to achieve this.

@antfu
Copy link
Member

antfu commented May 9, 2023

+1 to Daniel. I think this is not a usage we should advise.

A workaround to this is you can make the component you would like to reference this way global and use Vue's resolveComponent to retrieve them.

@silverbackdan
Copy link
Author

I can see why this is not advised so am happy to have an alternative. Are global components lazy loaded?

I think what I'm trying to achieve is similar to #14036

My API is returning data with the name of the dynamic component to be loaded. So I have a resource loader component which is taking this name and then loading that in if it exists. It'd be a shame if I have to bundle every possible component into the main bundle. Or am I missing something in that global components have good performance and aren't all included in the main bundle?

@silverbackdan
Copy link
Author

Thanks both @antfu and @danielroe
I have re-read docs and see that global components are split into individual async chunks for performance so this will do just fine I think. The link for how I fixed the issue currently seems to work fine for me being able to check whether the components exists globally using getCurrentInstance and then returning the component name as a string if it does.
resolveComponent would need a fixed string and not a variable so wouldn't fit my needs.

Thanks again both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants