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

Intermittent "Uncaught ReferenceError: importShim is not defined" error #379

Open
lesantoso opened this issue Jul 5, 2023 · 3 comments
Open

Comments

@lesantoso
Copy link

Hi there. Great work.

I'm not sure if this is a known issue, so apologies if it's a repeat. But I kept getting intermittent Uncaught ReferenceError: importShim is not defined errors while using importShim() from the latest version of ES Module Shims (1.7.3) in the latest version of Chrome (114).

I'm not sure if this is the best practice, but the errors seemed to disappear when I included ES Module Shims with a defer instead of an async attribute.

@guybedford
Copy link
Owner

Thanks for reporting the issue - can you share which line of code is giving the bug? Also if you happen to discover it's as simple as a one-liner to bump the ordering of global assignment of self.importShim = importShim in src/es-module-shims.js, do send a PR.

@lesantoso
Copy link
Author

Chrome doesn't point to any specific bugs in the ES Module Shims file:
Untitled
And here's my code:

<script async src="https://cdn.jsdelivr.net/npm/es-module-shims@1.7.3/dist/es-module-shims.min.js"></script>

<script type="importmap">
{
  "imports": {
    "app": "./app.js"
  }
}
</script>

<script type="module">
  if (navigator.clipboard) { // just some random feature detection
    importShim('app');
  }
</script>

The errors are not easy to reproduce in Chrome since they are intermittent. However, in the latest version of Firefox (115), which I just tested that code with, they appear to be persistent.

By the way, I'm thinking of using the good old import() instead of importShim() for this and a few other reasons. As part of that, I'm considering adding a dummy static import with a bare specifier right at the beginning just to intentionally trigger a static failure in unsupported browsers. I'd love to hear your comments on this approach.

@geigerzaehler
Copy link

geigerzaehler commented Jul 6, 2023

I’m running into the same problem. I can reproduce it when I delay serving es-module-shim.js so that it executes after the type="module" script in the example above.

I believe the way to fix is to ensure that the shim is to use defer instead of async on the script and put it before any module:

<script defer src="https://cdn.jsdelivr.net/npm/es-module-shims@1.7.3/dist/es-module-shims.min.js"></script>

MDN says that

Scripts with the defer attribute will execute in the order in which they appear in the document.

And

The defer attribute has no effect on module scripts — they defer by default.

So when the inline module script is executed, the shim script has already been executed and importShim is defined.

I’ve tested it and it seems to do the trick. Should the documentation be updated?


Here’s a server script to delay serving the shim:

import http from "http";
import { promises as fsPromises } from "fs";

const server = http.createServer(async (req, res) => {
  try {
    await new Promise((resolve) => setTimeout(resolve, 3000));

    res.statusCode = 200;
    res.setHeader("Content-Type", "application/javascript");
    res.setHeader("Access-Control-Allow-Origin", "*");

    const fileContent = await fsPromises.readFile("./es-module-shims.js");
    res.end(fileContent);
  } catch (err) {
    res.statusCode = 500;
    res.end("Error reading file");
  }
});

const port = 3000;
server.listen(port, () => {
  console.log(`Server is running and listening on http://localhost:${port}`);
});

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

No branches or pull requests

3 participants