-
-
Notifications
You must be signed in to change notification settings - Fork 384
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
isReady returns true even though bundles are not all loaded #400
Comments
Potential ways to fix this: Ideal way: Check that bundles are loaded along with modules, but I cannot figure out a way to list which chunks needs to be requireEnsured to load a given module (webpack/webpack#8847 maybe?) Workaround way: When calling |
Hello @ephys, I think we need help from webpack to fix it. They should provide a method to be able to check if a module is completely loaded. Do we have a correct solution to know if a module is completely loaded? |
require.weak is returning an object with keys. |
If someone has a better solution than the one implemented, please feel free to submit a PR. Else we have to speak with webpack to add the missing method. |
This particular issue is biting me as well. Our application has a slightly different use case than @ephys. We use a mixture of SSR + SPA interactions, so the way I duplicated it was adding a delay on one of the chunks for a page, and then doing multiple single page navigations. After doing a few, I navigated back to the first page. The module for that page was loaded, but the delayed chunk was not. isReady returned true because the module was loaded. The loadSync function was fired, and it attempted to import code that didn't exist in the loaded modules resulting in a One option is to change isReady to use The other option is to convince weback (maybe on this issue: webpack/webpack#5429) to expose the array they use to keep track of chunks similar to how they expose the Thoughts? |
Track module states by our own.
|
This is the line that causes our application to throw the error. My initial understanding of that line was that it was loading the component synchronously in order to support SSR. The underlying component is already rendered, and assumed to be ready due to the initial payload scripts loading before it gets run. I'm interested in the idea of loading the modules async all the time on the client, but how would you support SSR if you have to wait for the asyncRequire to resolve? |
So, in short - we are in trouble! Let me explain (and document) the problem:
Let's make a pause here, and recall what aggressive code splitting in webpack 4 is - it might split your code up to 5 chunks by default. However - In short - |
I'm still lacking insight into how you're going to support SSR if you keep track of the import promises, but I'll let you run that out. Here's a repro with steps in the readme: https://github.com/ColinxLLC/webpack-undefined-chunk-repro
|
Thank you the example, I will try to solve the problem on weekend. |
After talking to @neoziro I've realized that my approach would not play well with loadable SSR model. resolve: function resolve() {
if (true) {
return /*require.resolve*/(250);
}
return eval('require.resolve')("../Login");
}
// to
resolve: function resolve() {
if (true) {
// aka [__webpack_require__.e(0), __webpack_require__.e(2), __webpack_require__.e(1), __webpack_require__.e(3), __webpack_require__.e(63)]).then(__webpack_require__.bind(null, 250)
return [0, 2, 1, 3, 63, 250]
}
return eval('require.resolve')("../Login");
} How it's actually might work const chunks = [];
// overload import
const original = __webpack_require__.e;
__webpack_require__.e = chunkId => chunks.push(e);
// run import function
requireAsync();
// unmock
__webpack_require__.e = original;
// all required chunks are stored in `chunks` Then isReady, would be aware of all required chunks, and I don't quite like this solution, but another way is to resolve all required chunks inside loadable webpack plugin, and I am not sure how... |
Ok, there is a very simple way to handle this case:
Plus - on a ServerSide we shall execute |
For what it's worth, I'm running into what looks like a similar issue when using MinChunkSizePlugin. Essentially, given this:
I don't think this is related specifically to MinChunkSizePlugin, but rather is a result of the chunk dependency tree generated by it, and loadable doing a |
Yep, exactly our problem. |
We're also having the same problem, and what makes it hard is how sporadic things are. |
Ok, so:
|
Any update on this issue? |
Waiting for @neoziro approval. |
Hi @neoziro, is there a plan for a release with this fix? The bug is pretty painful and it'd be great to be able to move past it. Thanks! |
Thank you @theKashey :) |
🐛 Bug Report
My app will randomly crash depending on the load order of my bundles because
loadable()
'sisReady
doesn't check that all bundles that are needed are loaded (only the main one is checked).To Reproduce
Steps to reproduce the behavior:
Ok so this is pretty difficult to reproduce because it depends on the load order of different files
I have the following piece of code:
which is being transpiled by
@loadable/babel-plugin
&@loadable/webpack-plugin
into this:In this piece of code, you can see that
requireAsync
first loads the bundles 0, 2, 1, 3 and 63 before loading module 250 (module 250 is contained by bundle 63 and depends on code present in 0, 2, 1, 3).Now, I have a separate piece of code that will eventually cause the whole react tree to re-render as soon as another file is loaded (a workaround for react-router which still uses the old context api - I re-render the react tree once the proper locale file is loaded).
Because the whole react tree re-renders, the component generated by
loadable()
is re-built from scratch.When that component constructs, it calls
isReady
to check if it should userequireSync
orrequireAsync
. ButisReady
only checks that bundle 63 is loaded because it only checks for module 250. So if 0, 2, 1, or 3 are not loaded yet, it will load module 250 which will crash withcannot read property .call of undefined
because module 250 will attempt to load a module from one of the other bundlesExpected behavior
isReady
is smart enough to detect whether all modules are loaded or notLink to repl or repo (highly encouraged)
I will attempt to produce one but it's very difficult to get the timing right
Run
npx envinfo --system --binaries --npmPackages @loadable/component,@loadable/server,@loadable/webpack-plugin,@loadable/babel-plugin --markdown --clipboard
Paste the results here:
The text was updated successfully, but these errors were encountered: