QwikDev / qwik

Instant-loading web apps, without effort
https://qwik.dev
MIT License
20.6k stars 1.29k forks source link

[🐞] Qwik runtime importing from wrong q:base origin after user interaction in cross-origin container #5050

Closed jerimiahwelch closed 3 months ago

jerimiahwelch commented 12 months ago

Which component is affected?

Qwik Runtime

Describe the bug

Hello,

We are excited to use Qwik Containers to create a Cross-Origin Micro Frontend, but we are seeing that the Qwik runtime is not importing from the specified q:base origin after user interaction.

As shown in the qwik containers documentation, we are inserting a Cross-Origin Qwik Container:

Screenshot 2023-08-28 at 4 18 28 PM

Steps to reproduce

  1. Load minimal reproduction in Chrome: https://wompme.blob.core.windows.net/7910/qwikContainerCorsImportIssue.html
  2. Scroll down to pagination section at bottom of page
  3. Click on Page 2

Expected behavior

  1. All JS should load from Cross-Origin q:base property of https://care-core.pages.dev/build/

Observed behavior

  1. Some JS loads from q:base origin of https://care-core.pages.dev/build/
  2. Some JS is loading from page origin of https://wompme.blob.core.windows.net/build Screenshot 2023-08-28 at 4 28 41 PM

Reproduction

https://wompme.blob.core.windows.net/7910/qwikContainerCorsImportIssue.html

Steps to reproduce

See repro steps in description.

System Info

System:
    OS: macOS 13.4.1
    CPU: (12) arm64 Apple M2 Pro
    Memory: 604.58 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.2.0 - /opt/homebrew/bin/node
    npm: 9.6.6 - /opt/homebrew/bin/npm
    pnpm: 8.6.10 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 116.0.5845.110
    Chrome Canary: 118.0.5976.0
    Safari: 16.5.2

Additional Information

No response

mhevery commented 12 months ago

Cool! Would love to know more about your goals so that I can better prioritize this.

You can also reach me on Discord @mhevery

jerimiahwelch commented 12 months ago

Hi @mhevery ,

We are transitioning away from AMP + PWA and we liked that Qwik had better performance and more flexibility.

We are building with Qwik for production. We haven't released yet, but here is our current qwik demo site: https://care.womp.it/

This clinic search list component is part of a website that we will provide at a dedicated domain(s). In addition to the regular site, our client Piedmont health would like to show health appointments on their blog pages. This will help people find the right kind of medical appointment more easily.

This is what we are trying to build, but you need a local proxy to see it properly at the moment. Screenshot 2023-08-30 at 7 20 49 AM

We are hoping to use containers in this cross-origin context to reuse the clinic search component and not need to develop it twice. We would prefer to use containers instead of iframes for the improved performance as well as providing the parent document more analytics transparency, a/b test control, and CSS control. These have all been issues with our current shadow-dom based web components.

After some testing and CSS hardening, the qwikloader works with this approach on the Piedmont site. The only issue is the component importing JS from the parent domain after user interaction.

We are also interested in using this MicroFE container approach for some of our internal tools so that different teams can develop and release portions of the site independently. The blog client-side script approach in this ticket is intended for minimal work on the healthcare network's side, but we are also exploring Server-side Container composition for other tools https://blog.cloudflare.com/fragment-piercing/.

I work for https://dexcare.com/. We help people find the right kind of appointment with their healthcare network.

mhevery commented 12 months ago

OK, I dug into it a bit, and the issue is coming from Vite.

const a = o(_(()=>i(()=>import("./q-0777dc25.js"), ["build/q-0777dc25.js", "build/q-a741c7da.js", "build/q-47bdf09a.js", "build/q-683653e0.js", "build/q-0815ac35.js", "build/q-d2a0a80e.js", "build/q-e4ce1e98.js", "build/q-5b5c912e.js", "build/q-85384b7b.js", "build/q-f2327580.js", "build/q-6db0b552.js", "build/q-6febb18e.js", "build/q-3a50c098.js", "build/q-d42d0c15.js", "build/q-121ac03d.js"]), "s_U4biimqwnQ0"))

The problem is that vite sees q-0777dc25.js and it knows that q-0777dc25.js imports q-0777dc25.js (and so on) so it wants to be smart and pre-fetch all of these to avoid the waterfall problem. So it takes the array and inserts it into the DOM as <link rel="modulepreload" as="script" crossorigin="" href="/build/q-e480eacf.js"> so that the browser does prefetching. But the browser document is on a different domain, hence the errors. Interestingly these are just that, errors, but the application should be fully functional as those fetches have no purpose other than to avoid waterfall.

image

Related issues on this problem: https://github.com/vitejs/vite/issues/5214, https://github.com/vitejs/vite/issues/3133, https://github.com/vitejs/vite/issues/5120,

Possible fix: https://github.com/vitejs/vite/pull/9938

Add this to your vite.config.js

    build: {
      modulePreload: {
        resolveDependencies: (url, deps, opts) => {
          return deps.map((v) => 'http://myserver/' + v);
        },
      },
    },

https://vitejs.dev/config/build-options.html#build-modulepreload

jerimiahwelch commented 12 months ago

@mhevery ,

Thank you so much for your time on this! And so quickly too. It's been a whirlwind of a morning, but we will be able to try out this solution by early next week.

That matches what we were seeing. The functionality was working, but it was making duplicate requests to the origin.

We currently are setting the q:build attribute to match the server at runtime instead of compile time (below), so that q:base will match the deployment environment without the need for config files. We will dig into Vite module preload and try to see if something similar is possible as well.

Screenshot 2023-08-31 at 1 09 17 PM

mhevery commented 12 months ago

Can this issue be closed?

PatrickJS commented 3 months ago

I'm closing this and we're adding better base support https://github.com/QwikDev/qwik/pull/6017

please reopen if there is still an issue