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

Vite Async Module window onerror triggering capability #13755

Closed
4 tasks done
ediaos opened this issue Jul 9, 2023 · 4 comments
Closed
4 tasks done

Vite Async Module window onerror triggering capability #13755

ediaos opened this issue Jul 9, 2023 · 4 comments

Comments

@ediaos
Copy link

ediaos commented Jul 9, 2023

Description

  1. Background: We have a scenario where we need to retry resource loading when there are exceptions, such as when changing domain names, based on Vite packaging.

  2. Problem: In Vite ESM packaging, dynamic imports cannot trigger window.onerror, making it impossible to listen for errors. For example, dynamic imports in router or code (dynamic imports under ESM can only go through the catch process).

However, in webpack packaging, it will be loaded in the form of a script tag, and I will get onerror, thereby achieving the ability to retry.

Suggested solution

The solution should be globally supported during construction to reduce the complexity of modifying the business side.

When Vite is built under ESM, it converts dynamic imports into script module loading and callback processing, which will not affect the original logic.

function loadAsyncModule(url) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script')
    script.type = 'module'
    script.src = url
    script.onload = (event) => {
      import(event.target.src)
        .then((module) => {
          resolve(module)
        })
        .catch((err) => {
          reject(err)
        })
    }
    script.onerror = (err) => {
      reject(err)
    }
    document.head.appendChild(script)
  })
}

loadAsyncModule('/demo/scripts/module/add-async.js').then(({ default: add }) => {
  console.log('iresult', add(1, 3))
})

Alternative

No response

Additional context

If there are any unclear points, please let me know and I will supplement them.

Validations

@sapphi-red
Copy link
Member

I feel this is similar to #12080. Would window.addEventListener('vite:preloadError', e => console.log(e)) work for you? It's added in 4.4 (#12084).

@ediaos
Copy link
Author

ediaos commented Jul 17, 2023

I feel this is similar to #12080. Would window.addEventListener('vite:preloadError', e => console.log(e)) work for you? It's added in 4.4 (#12084).

Thank you very much for your reply. I carefully read the code submission you provided. From the source code, it seems that vite:preloadError only works for CSS file loading. Based on the element's hook, I was able to intercept addEventListener's error and load events to achieve retry capability.

For asynchronously loaded module modules (non-preload), it is currently not possible to trigger exceptions and retries globally. One solution I can think of is to change the way Vite packages modules by replacing the asynchronous loading of import with a custom loadAsyncModule.

My idea is to see if it is feasible to use the script method instead of asynchronous import. If it is feasible, it could be a common solution for Vite configuration.

@SwatiMaheshwari
Copy link

is there any update on this issue?

@sapphi-red
Copy link
Member

From the source code, it seems that vite:preloadError only works for CSS file loading. Based on the element's hook, I was able to intercept addEventListener's error and load events to achieve retry capability.

No, it does work for JS as well (it had a bug though #15203).
https://stackblitz.com/edit/vitejs-vite-eubg1i?file=main.js,counter.js

I'll close this issue as this is already implemented by #12084

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

No branches or pull requests

3 participants