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

Universal renderer: lazy() automatically inserts an empty text node, which may or may not be supported by the underlying renderer #2283

Open
Alloyed opened this issue Sep 13, 2024 · 1 comment

Comments

@Alloyed
Copy link

Alloyed commented Sep 13, 2024

Describe the bug

This is a regression caused by c8fe58e as far as I can tell, specifically packages/solid/src/render/component.ts line 381

return createMemo(() =>
      (Comp = comp())
        ? untrack(() => {
            if ("_SOLID_DEV_") Object.assign(Comp!, { [$DEVCOMP]: true });
            if (!ctx || sharedConfig.done) return Comp!(props);
            const c = sharedConfig.context;
            setHydrateContext(ctx);
            const r = Comp!(props);
            setHydrateContext(c);
            return r;
          })
        : ""
    ) as unknown as JSX.Element;

upon upgrading, our proprietary universal render started to fail in cases where the lazy() element was being used, because we never implemented a version of createTextNode() that would intelligently handle the empty string the second half of that ternary.

Your Example Website or App

n/a

Steps to Reproduce the Bug or Issue

  1. create a universal renderer, and implement createTextNode like so:
    createTextNode: function (_text: string): MyNodeType {
         throw new Error("Text nodes not supported!")
    },
  1. create an HTML with a lazy() component inserted.
  2. Notice your error is triggered

Expected behavior

n/a

Screenshots or Videos

n/a

Platform

n/a

Additional context

So the reason we don't support bare text nodes in our renderer is that all of our text live inside a specific base element, like so:

<label text="my actual text" />

so there was never a need to implement text nodes, and it would muddy the waters of our implementation to try. We can work around this issue just by ignoring bare text entirely. that said, if the implementation of a built in component tried to insert any other kind of text, for any reason, we'd still have this problem. One approach may just be to document this behavior, with wording along the lines of: "your renderer must at least support empty string and whitespace-only text nodes. your renderer may ignore them entirely if desired."

@ryansolid
Copy link
Member

I see. Yeah we needed a fixed marker here. Empty text node seemed the easiest because it is mostly invisible in the DOM. We do this in things like Portals as well but I suppose you don't hit that in the universal renderer as well. Documenting it might be the easiest option I think. I'm not sure how else to best handle it.

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

2 participants