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

Error "undefined is not an object (evaluating 'e[c].call')" When runtime chunk is slow to load #634

Closed
dr3 opened this issue Sep 25, 2020 · 18 comments
Assignees
Labels

Comments

@dr3
Copy link

dr3 commented Sep 25, 2020

🐛 Bug Report

When the runtime chunk is slow to load, loadableReady will run regardless.
This causes some errors (depending on the browser)

undefined is not an object (evaluating 'e[c].call') - Safari & Chrome
Cannot read property 'call' of undefined - All browsers
can't access property "call", e[c] is undefined - Firefox

Related to #558

To Reproduce

Steps to reproduce the behavior:

To replicate this I used express to serve JS bundles, allowing me to simulate it being slow to load

  1. Slow down the bundle. I used this in my express routing
app.use('*/runtime~app.*.js', async (req, res, next) => {
  await new Promise(resolve => setTimeout(resolve, 5000));
  next();
});
  1. Load the page in Safari 13 or 14 (seems to be the easiest browser to replicate)
  2. See error
    image

Note, the error only happens after loadableReady has completed and the hydration begins. This doesn't happen if you don't use loadableReady.

Expected behavior

loadableReady continues to wait for the runtime chunk to avoid the error

Link to repl or repo (highly encouraged)

Please provide a minimal repository on GitHub.

Issues without a reproduction link are likely to stall.

Run npx envinfo --system --binaries --npmPackages @loadable/component,@loadable/server,@loadable/webpack-plugin,@loadable/babel-plugin --markdown --clipboard

Paste the results here:

## System:
 - OS: macOS 10.15.5
 - CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
 - Memory: 4.76 GB / 16.00 GB
 - Shell: 5.7.1 - /bin/zsh
## Binaries:
 - Node: 12.18.0 - ~/.nvm/versions/node/v12.18.0/bin/node
 - Yarn: 1.21.1 - ~/.yarn/bin/yarn
 - npm: 6.14.4 - ~/.nvm/versions/node/v12.18.0/bin/npm
## npmPackages:
 - @loadable/babel-plugin: 5.13.0
 - @loadable/component: 5.13.2
 - @loadable/server: 5.13.1
 - @loadable/webpack-plugin: 5.13.0
@open-collective-bot
Copy link

Hey @dr3 👋,
Thank you for opening an issue. We'll get back to you as soon as we can.
Please, consider supporting us on Open Collective. We give a special attention to issues opened by backers.
If you use Loadable at work, you can also ask your company to sponsor us ❤️.

@theKashey
Copy link
Collaborator

This doesn't happen if you don't use loadableReady.

What else you can use?

See error

So the error you can see is the real error - not undefined is not an object..., but ...expected to be available. And the question is "why"

@prateekr1
Copy link

A similar situation I tried to explain in the below comment

#558 (comment)

I think this bug is related to the order of runtime chunk.

Currently, I am using the following config in webpack

optimization: {
    runtimeChunk: false,
  },

and is working fine for me.

@qingzhou729
Copy link

@prateekr1 In issue 558, the problem is not completely solved, is it?

@dr3
Copy link
Author

dr3 commented Oct 19, 2020

Yeah disabling the runtime chunk meerly avoids the issue. There is still a larger issue. I still wanted to use the runtime chunk.

In my project I had to fork @loadable/server to make the runtime chunk not async (the rest still are), doing something similar to #526

@prateekr1
Copy link

@prateekr1 In issue 558, the problem is not completely solved, is it?

@yukiyang0729
yes, the problem still exists when the Webpack config is having

optimization: {
    runtimeChunk: true,
  },

@theKashey
Copy link
Collaborator

So, once again - how to replicate?

@theKashey theKashey self-assigned this Oct 20, 2020
@dr3
Copy link
Author

dr3 commented Oct 20, 2020

@theKashey I am able to reproduce this consistently by slowing down the loading of the runtime chunk. I do this by serving the files via express and using this code to slow the runtime one down

app.use('*/runtime~app.*.js', async (req, res, next) => {
  await new Promise(resolve => setTimeout(resolve, 5000));
  next();
});

@qingzhou729
Copy link

Yeah disabling the runtime chunk meerly avoids the issue. There is still a larger issue. I still wanted to use the runtime chunk.

In my project I had to fork @loadable/server to make the runtime chunk not async (the rest still are), doing something similar to #526

Is this scheme applied in the project?

@qingzhou729
Copy link

@theKashey hello, can you support this config #526

@dr3
Copy link
Author

dr3 commented Oct 20, 2020

In my fork i changed assetToScriptTag to

function assetToScriptTag(asset, extraProps) {
  const props = handleExtraProps(asset, extraProps)
  const { async, ...rest } = props

  return `<script ${async ? 'async' : ''} data-chunk="${asset.chunk}" src="${
    asset.url
  }"${getSriHtmlAttributes(asset)}${extraPropsToString(asset, rest)}></script>`
}

and then use

extractor.getScriptTags(asset => ({
   async: !!asset && !asset.filename.includes('runtime~app'),
}))

Obs not ideal, we should try and fix the core issue. But this stopped us getting errors for now

@theKashey
Copy link
Collaborator

That strange, as long as runtime-chunk is the one who actually triggers script execution.

@theKashey
Copy link
Collaborator

Hey! I've created an example based on this issue and it's... ☹️ working.
If someone can help me break it - it will be much appreciated.

The async tag definitely is a problem here, and replacing it by defer(still async!) should solve the problem. However - we need to know what exactly is broken to fix this problem once and for all.

@iwyvi
Copy link

iwyvi commented Oct 21, 2020

@theKashey I modified the example and it would reproduce the error almost every time.

In this example , I have three js files: runtime, main, letters. If these files are loaded by the following order:
main -> letters -> runtime, we will get the same error mentioned above every time.

I may find the reason:

const loadedChunks = window.__LOADABLE_LOADED_CHUNKS__

loadableReady only checks whether the loadable required chunks are listed in window.__LOADABLE_LOADED_CHUNKS__, but can't assure these chunks have already been loaded by webpack. Because letters has no relationship with main, so despite letters has not been installed, webpack runs main and loadableReady will resolve.

So if script files are loaded by following order, it will cause the error:

all the chunks listed in __LOADABLE_REQUIRED_CHUNKS__ are loaded after any of entry file and its dependent chunks, and runtime is loaded at last.

I think it will be solved if we can remove async in runtime's <script> when getScriptTags.

@theKashey
Copy link
Collaborator

theKashey commented Oct 22, 2020

Thank you @iwyvi, the problem has been found. Loadable Ready working in a synchronous way :(

@theKashey
Copy link
Collaborator

Not fixed until a new version is released.

@theKashey theKashey reopened this Oct 22, 2020
@theKashey
Copy link
Collaborator

5.14.1 has been released 🥳

@stale
Copy link

stale bot commented Dec 21, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Dec 21, 2020
@stale stale bot closed this as completed Dec 29, 2020
fivethreeo pushed a commit to fivethreeo/loadable-components that referenced this issue Nov 16, 2022
* chore(tests): make breaking case for webpack4

* fix: loadableReady should not resolve synchronously, fixes gregberge#634

* chore(size): commit size change
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants