You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a similar but different issue to the one fixed in #9093 which @jondlm mentioned in his comment here: #9093 (comment)
The issue seems to be that, in certain cases, Parcel isn't properly blocking execution until all modules have been downloaded and added to the parcelRequire module map.
This results in errors which look like:
Uncaught (in promise) Error: Cannot find module '3qBDj'
at newRequire (main.js:61:19)
at newRequire (experience-1.0d761226.js?1691102495451:53:18)
at newRequire (dependency-1.8d0776f1.js?1691102495603:53:18)
at newRequire (dependency-1.8d0776f1.js?1691102495603:45:18)
at localRequire (dependency-1.8d0776f1.js?1691102495603:84:35)
at bMz2a.lodash (dependency-1.8d0776f1.js?1691102495603:582:15)
at Function.newRequire (dependency-1.8d0776f1.js?1691102495603:71:24)
at experience-1.0d761226.js?1691102495451:595:27
at async Promise.all (index 0)
at async exports.default (experience-1.0d761226.js?1691102495451:582:52)
During the initial lazy build and load, either the shared dependency (lodash in the example) should be inlined into both of the modules which depend on it or their execution should be blocked until the shared bundle is downloaded.
The two async bundles (dependency-1, dependency-2) get downloaded and executed immediately before the shared asset bundle has had time to download and resolve which results in them being unable to resolve the references to the shared asset (lodash).
If this function returned an array with both the target bundle (dependency-1 or dependency-2) and the shared bundle, then I believe that the rest of the logic would work correctly.
🔦 Context
This is blocking us from being able to use Parcel in devmode because of our heavy usage of dynamic imports throughout the application. We really need --lazy in order for it to be feasible for us to run the application, but, because of the ordering and shared bundle issue here, we bump into errors unexpectedly throughout the application.
flowchart TD
A(main.ts) -->|async| B(experience-1)
B -->|async| C(dependency-1)
B -->|async| D(dependency-2)
subgraph loaded simultaneously with `Promise.all`
direction RL
C
D
end
C --> E(lodash)
D --> E
Loading
It looks like the lazy mode algorithm sees either dependency-1 or dependency-2 (whichever races first) and decides to split lodash into a shared bundle. It does this correctly but it doesn't correctly detect there should be multiple loaders that should block the execution of the dependency-* file that depends on the shared bundle. On the failing first page load we're hitting this case. Then on the subsequent load we're hitting this case and the code correctly waits for the shared bundle to load before executing the sync code.
It's not clear yet whether this is a fundamental limitation of trying to split shared bundles out when Parcel has only seen part of the graph. It seems like there's a fix lurking somewhere here but we haven't nailed it down yet.
Our workaround for the moment is to crank minBundles to a really large number. That causes the bundler to simply inline lodash into both bundles and the first load works correctly.
I'm getting this in the latest version v2.11.0 where whenever i use both import("my-lib") and somewhere else import from "my-lib"; it throws unknown module found and fails to build (watch mode only!).
🐛 bug report
This is a similar but different issue to the one fixed in #9093 which @jondlm mentioned in his comment here: #9093 (comment)
The issue seems to be that, in certain cases, Parcel isn't properly blocking execution until all modules have been downloaded and added to the
parcelRequire
module map.This results in errors which look like:
🎛 Configuration (.babelrc, package.json, cli command)
Here's a repo with the steps to reproduce the issue: https://github.com/natan-stripe/lazy-testbed/tree/main
🤔 Expected Behavior
During the initial lazy build and load, either the shared dependency (
lodash
in the example) should be inlined into both of the modules which depend on it or their execution should be blocked until the shared bundle is downloaded.The way it works on subsequent loads is that the bundles get grouped together with a
Promise.all
from the logic here: https://github.com/parcel-bundler/parcel/blob/v2/packages/runtimes/js/src/JSRuntime.js#L481. On initial load, though, the array ofloaderModules
does not include the shared bundle.😯 Current Behavior
The two async bundles (
dependency-1
,dependency-2
) get downloaded and executed immediately before the shared asset bundle has had time to download and resolve which results in them being unable to resolve the references to the shared asset (lodash
).💁 Possible Solution
I'm not familiar enough with Parcel's internals still to be able to suggest a good fix, but, I think the issue is most likely in the logic of
bundleGraph.getBundlesInBundleGroup
which is used here: https://github.com/parcel-bundler/parcel/blob/v2/packages/runtimes/js/src/JSRuntime.js#L349If this function returned an array with both the target bundle (
dependency-1
ordependency-2
) and the shared bundle, then I believe that the rest of the logic would work correctly.🔦 Context
This is blocking us from being able to use Parcel in devmode because of our heavy usage of dynamic imports throughout the application. We really need
--lazy
in order for it to be feasible for us to run the application, but, because of the ordering and shared bundle issue here, we bump into errors unexpectedly throughout the application.💻 Code Sample
https://github.com/natan-stripe/lazy-testbed/tree/main
🌍 Your Environment
The text was updated successfully, but these errors were encountered: