-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
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
Webpack overwrites custom objects passed into resolve.unsafeCache #18129
Comments
I see your problem |
I found two solution:
const unsafeCache = options.unsafeCache;
const normalizedOptions = removeOperations(
resolveByProperty(options, "byDependency", dependencyType)
);
if (unsafeCache !== undefined) {
normalizedOptions.unsafeCache = unsafeCache;
}
return normalizedOptions; This is not a universal solution, we assume that only there a proxy can be used for
const getValueType = value => {
if (value === undefined) {
return VALUE_TYPE_UNDEFINED;
} else if (value === DELETE) {
return VALUE_TYPE_DELETE;
} else if (util.types.isProxy(value)) {
return VALUE_TYPE_ATOM;
} else if (Array.isArray(value)) {
if (value.lastIndexOf("...") !== -1) return VALUE_TYPE_ARRAY_EXTEND;
return VALUE_TYPE_ATOM;
} else if (
typeof value === "object" &&
value !== null &&
(!value.constructor || value.constructor === Object)
) {
return VALUE_TYPE_OBJECT;
}
return VALUE_TYPE_ATOM;
}; All solutions works with your repo. But yeah, that is intresting problem, because we use Want to get some feedback from you |
Another solution like
and
so it give ability to mark Proxy in a browser |
Thank you for the quick response! Options 1 and 2 seem like the safest immediate fixes with minimal impact, though we acknowledge they might not cover all future scenarios. Option 3 (and its browser-compatible variant) do offer a more universal fix. It does seem like the most ideal solution to our specific problem. However, our main concern revolves around potential side-effects across other |
see if this helps const fileSystemAwareCache = new Proxy({}, {
}); |
@jpbriggs408 There is a fix #18152, I decide to avoid proxy check, because it is not universal (we can't undestand when it is a plain object or a proxied object, except node.js utils ), so let's just keep unsafeCache as is and avoid the object creation |
@alexander-akait thank you so much! I think this solution makes a lot of sense. If documentation needs to be updated, I'm happy to take a crack at it. Let me know, and thanks again! |
I don't thank we need document it, because it is like a bug |
Totally reasonable! In webpack's documentation, it isn't clear that an object can be passed, but that is outlined in |
@alexander-akait thank you for this fix, we really appreciate it! Would we be able to get a release cut with this fix in it at your convenience? |
Yeah, this week |
Bug report
When upgrading from Webpack 4 to Webpack 5, we identified an issue where custom Proxy cache objects passed into
resolve.unsafeCache
are overwritten by theremoveOperations
function. This function is executed recursively on resolve options, transforming the Proxy cache into a plain, empty object right before the options are utilized by theenhanced-resolve
library.In
enhanced-resolve
, we should be able to pass a boolean or an object tounsafeCache
. Passing an object allows it to serve as the cache directly. This functionality is crucial for maintaining custom caching logic in complex projects.What is the current behavior?
The custom Proxy cache object is replaced with a plain, empty object due to the recursive execution of
removeOperations
.Steps to Reproduce
I've created a minimal reproducible example here: https://github.com/jpbriggs408/Webpack-UnsafeCache-ModuleBuildError-Repro.
What is the expected behavior?
The custom Proxy cache object should be consistently used for caching across all operations, maintaining its integrity and functionality throughout the Webpack resolution process.
Possible Solutions
resolve.unsafeCache
to preserve custom caching mechanisms.resolve.unsafeCache
enhanced-resolve
is a potential solution, though this has not been explored in depth.module.unsafeCache
with a function to re-resolve requests dynamically for non-existent modules.Notes
Enabling filesystem caching and disabling
resolve.unsafeCache
re-gains some lost perf benefits, though ideally, we should be able to have both. In our (extremely large) monorepo, the overhead of the filesystem check is minimal and having both options is a clear perf benefit. This actually makes Webpack 5 with filesystem caching only marginally slower for us in dev than our Webpack 4 version with the above simple filesystem check enabled for the resolver cache. Also, special thanks to @joebeachjoebeach for helping connect the final dots with this investigation!Other relevant information:
webpack version: 5.89.0
Node.js version: 16.13.2
Operating System: CentOS 7
Additional tools: N/A
Previous Context
I previously opened a GitHub Discussion when I began this investigation.
TL;DR Summary
We've discovered an issue in Webpack 5 where custom Proxy cache objects specified in
resolve.unsafeCache
are overwritten by theremoveOperations
function incleverMerge.js
. This function's recursive operation on resolve options transforms our Proxy cache into a plain, empty object, just before being passed toenhanced-resolve
. Despiteenhanced-resolve
's capability to use an object directly as the cache, this behavior negates the utility of custom Proxy caches, affecting developers working on complex projects.We're seeking insights on preserving custom caching logic within Webpack's ecosystem. Feedback and suggestions would be greatly appreciated to navigate and “resolve” this challenge.
Thanks in advance!
The text was updated successfully, but these errors were encountered: