qwik: [๐] When try to load component dinamically via import I get error
Which component is affected?
Qwik Rollup / Vite plugin
Describe the bug
Hi ๐
Currently, I can import any component by this way, the normal way:
import { $, component$, useClientEffect$, useStore } from "@builder.io/qwik";
import ComponentA from "~/components/component-a";
import ComponentB from "~/components/component-b";
import ComponentC from "~/components/component-c";
export default component$(() => {
const tree = useStore(
[
{ tag: "ComponentA", type: 1 },
{ tag: "ComponentB", type: 1 },
{ tag: "div", type: 0, class: "bg-green-400", content: "Hello" },
],
{
recursive: true,
}
);
const changeComponent = $(() => {
tree[0].tag = "ComponentC";
});
useClientEffect$(() => {
// @ts-ignore
window.changeComponent = changeComponent;
});
const components: Record<string, any> = {
ComponentA: ComponentA,
ComponentB: ComponentB,
ComponentC: ComponentC,
};
return (
<>
<div>
<div>
{tree.map((element) => {
if (element.type === 0) {
const Tag = element.tag as any;
return <Tag class={element.class}>{element.content}</Tag>;
}
if (element.type === 1) {
// Works fine
// const Component = components[element.tag];
// Works fine
// const Component = await import(`~/components/component-a`)
// Fail
const Component = await import(`~/components/${element.tag}`)
return <Component key={element.tag} />;
}
})}
</div>
<button onMouseDown$={changeComponent}>Click me</button>
</div>
</>
);
});
I tried it with success:
const Component = await import(`~/components/component-a`)
But, if I wanna import some component dynamically (async) like:
const Component = await import(`~/components/${element.tag}`)
It fails ๐ช with error:
[plugin:vite-plugin-qwik] Dynamic import() inside Qrl($) scope is not a string, relative paths might break
In Vite, you can pass it with /* @vite-ignore */
comment, but I tried it too with no success.
Is there some way to achieve successfully this?
Reproduction
Steps to reproduce
npm install && npm start
System Info
System:
OS: Linux 5.0 undefined
CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 0 Bytes / 0 Bytes
Shell: 1.0 - /bin/jsh
Binaries:
Node: 16.14.2 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 7.17.0 - /usr/local/bin/npm
npmPackages:
@builder.io/qwik: ^0.15.2 => 0.15.2
@builder.io/qwik-city: ^0.0.128 => 0.0.128
vite: 3.2.4 => 3.2.4
Additional Information
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 1
- Comments: 18 (6 by maintainers)
@mrclay If the dynamicity is not about the on-demand loading but the programable loading by name as here, then I think it is still relevant
Yes, the above is possible with caveats.
Here is one way to do in Qwik: https://stackblitz.com/edit/qwik-starter-j55lca (but depending on your requirements it may be done differently)
@mhevery hey I mean the path or name of a component is read dynamically for the current user or page and I need to load it dynamically. So like mentioned by @oceangravity:
Is this possible with Qwik? I find that issue a lot, like if everyone is just building static sites but in big apps you need to load components dynamically based on information related to the user or a product.
@appinteractive
Sorry for the oversight, itโs actually possible to import.meta.glob without
eager:true
Rectified example:
This doesnโt seem to add much to dev server starting time and it does allow me to improve my mdx editing DX quite a lot.
So in my .mdx files,
instead of doing
where I have to add weird conditional logic with Slots if I want to pass different components (in my case I also have /registry/default, so I would have to find a way to display the right components based on user config).
I can simply do
And let my component handle everything for me ๐ .
@mhevery what do you think of import.meta.glob as an alternative to dynamic import? If itโs not an issue for the optimizer I think it should be presented in the docs as it can significantly improve the DX for some use cases (especially in .mdx files where thereโs no typescript auto-complete).
This would require a bit more testing (especially in prod), but I can work on a docs PR if you like the idea.
@appinteractive it is possible to make a vite plugin that creates such a registry object from a directory of Qwik components. But manually maintaining the registry probably takes less time than writing and maintaining the plugin
This error happens even with no dynamic content. As long as youโve got a back quote in the
import()
function, vite throw the error:Itโs my understanding that if you build Qwik components correctly, thereโs no reason to use dynamic import(). The in-browser runtime loads everything on-demand already.