Closed nick-klaviyo closed 1 year ago
I would use the following:
--- a/lib/resolver-compat.js
+++ b/lib/resolver-compat.js
@@ -322,8 +322,13 @@ function resolverFromOptions(vm, options, override, compiler) {
}
const resolved = customResolver(x, path);
if (!resolved) return undefined;
- if (externals) externals.push(new RegExp('^' + escapeRegExp(resolved)));
- return resolver.loadAsFileOrDirecotry(resolved, extList);
+ if (typeof resolved === 'string') {
+ if (externals) externals.push(new RegExp('^' + escapeRegExp(resolved)));
+ return resolver.loadAsFileOrDirecotry(resolved, extList);
+ }
+ const {module=x, path: resolvedPath} = resolved;
+ if (externals) externals.push(new RegExp('^' + escapeRegExp(resolvedPath)));
+ return resolver.loadNodeModules(module, [resolvedPath], extList);
};
}
Then the resolve method could look like:
resolve: function (moduleName, dirName) {
return {path: `./node_modules/`};
}
This seems better as using resolver.pathBasename(resolver.pathDirname(resolved))
makes assumptions about the result that may not hold.
Thanks for the quick response @XmiliaH ! I implemented the change you described in #505 along with a test case. Let me know if there's any other changes I should make.
Issue Description
When using the
require.resolve
option for NodeVM, NodeVM's resolver does not use conditional exports when resolving the module at the returned path. As a result, it is not possible torequire
ES modules that only expose a CommonJS entrypoint via therequire
conditional export path.Example and Repro Steps
Environment Info
Device: Macbook Pro, Apple M1 Max (2021) Node Version: v18.12.0 Working Directory: /nick/projects/axios
package.json
index.js
Run
node index.js
Output
Cause
It looks like the custom resolver wrapper will attempt to load the resolved module path as a file or a directory (https://github.com/patriksimek/vm2/blob/master/lib/resolver-compat.js#L326), which will not result in a check for conditional exports.
Proposed Solution
Use
resolver.loadNodeModules
instead ofresolver.loadAsFileOrDirecotry
sinceloadNodeModules
will try to first resolve conditional exports, and then try loading as file or directory.On https://github.com/patriksimek/vm2/blob/master/lib/resolver-compat.js#L326
This change works for me; however, using
resolver.pathBasename(resolver.pathDirname(resolved))
seems kind of weird, so not sure if.loadNodeModules
is the best method to use, but the main idea would be to use similar logic that of.loadNodeModules
.