Coder Social home page Coder Social logo

Modules not loading any more? about vm2 HOT 16 CLOSED

fcbrandon avatar fcbrandon commented on June 7, 2024
Modules not loading any more?

from vm2.

Comments (16)

XmiliaH avatar XmiliaH commented on June 7, 2024

What options do you give to NodeVM and how do you run the module?

from vm2.

fcbrandon avatar fcbrandon commented on June 7, 2024

I tried running this example from the README and am having the same issue:

const {NodeVM} = require('vm2');
const vm = new NodeVM({
    require: {
        external: true,
        root: './'
    }
});

vm.run(`
    var request = require('request');
    request('http://www.google.com', function (error, response, body) {
        console.error(error);
        if (!error && response.statusCode == 200) {
            console.log(body); // Show the HTML for the Google homepage.
        }
    });
`, 'vm.js');

from vm2.

XmiliaH avatar XmiliaH commented on June 7, 2024

Did you install the request module with npm install request?

from vm2.

fcbrandon avatar fcbrandon commented on June 7, 2024

I did run npm install request, and I can see it in the node_modules.

For the heck of it, I pulled the code to run into its own file and that ran with no problem.

So I guess loading modules should be working fine, like, there hasn't been a change that broke module loading?

from vm2.

XmiliaH avatar XmiliaH commented on June 7, 2024

There should not be a change that broke module loading. The example worked fine for me. I created a test.js file with the example code and ran:

npm install vm2
npm install request
node test.js

and I got a resopnse back and printed.

from vm2.

fcbrandon avatar fcbrandon commented on June 7, 2024

So then it's something local on my machine?

Here's exactly what I'm seeing:

<redacted>/node_modules/vm2/lib/bridge.js:487
				throw thisFromOtherForThrow(e);
VMError: Cannot find module 'request'
    at DefaultResolver.resolveFull (<redacted>/node_modules/vm2/lib/resolver.js:108:9)
    at DefaultResolver.resolveFull (<redacted>/node_modules/vm2/lib/resolver.js:315:16)
    at DefaultResolver.resolve (<redacted>/node_modules/vm2/lib/resolver.js:103:15)
    at ReadOnlyHandler.apply (<redacted>/node_modules/vm2/lib/bridge.js:485:11)
    at requireImpl (<redacted>vm2/lib/setup-node-sandbox.js:84:28)
    at require (/<redacted>/vm2/lib/setup-node-sandbox.js:165:10)
    at vm.js:2:19
    at VM2 Wrapper.apply (<redacted>/node_modules/vm2/lib/bridge.js:485:11)
    at NodeVM.run (<redacted>/node_modules/vm2/lib/nodevm.js:426:23)
    at Object.<anonymous> (<redacted>/temp/index.js:9:4) {
  code: 'ENOTFOUND'
}

from vm2.

XmiliaH avatar XmiliaH commented on June 7, 2024

I am not able to reproduce your issue, but there should be nothing machine depndent there.
The file structure should be like:

./test.js
./node_modules/request/...

So in your case you should find the request module in <redacted>/temp/node_modules/request/....

from vm2.

fcbrandon avatar fcbrandon commented on June 7, 2024

The request module is definitely there. Again, I can run the 'request' code in its own file, it runs just fine, so it's something specific to vm2.

I just tried the sample in a new Ubuntu VM and it ran just fine (I totally trusted your response, more just to confirm I could get things to run for myself as well.). So there's definitely something with my machine. It's an M1 Macbook Pro; I doubt that has anything to do with it though.

I'll try to uninstall Node/NPM and try it again, hopefully there's just something up with my Node install. I'll report back with status.

So far this is all good news for me; I was starting to get pretty bummed that I'd have to find a new isolation library, which would have been a pain 😆

from vm2.

XmiliaH avatar XmiliaH commented on June 7, 2024

I do not have a M1 Macbook Pro to test. You could set a breakpoint in the function resolveFull in file lib/resolver.js at line 225 and step through the resolve process. The module should be loaded through resolveFull > loadNodeModules > loadAsDirectory > loadAsPackage.

from vm2.

fcbrandon avatar fcbrandon commented on June 7, 2024

There's something up with how the paths are detected, I'm still working on figuring it out though.
The difference it notable at this line:

f = this.loadNodeModules(x, dirs, extList);

		// 6. LOAD_NODE_MODULES(X, dirname(Y))
		f = this.loadNodeModules(x, dirs, extList);
		if (f) return f;

When running on my Macbook, dirs has a length of zero, but in Ubuntu, it looks something like this:

[ 
0: '/home/source/project/node_modules',
1: '/home/source/node_modules',
2: '/home/node_modules'
3: '/node_modules'
]

It's not immediately clear why it's happening for me, but it's clear that on the Macbook vm2 is unable to enumerate paths for node_modules, which is why it keeps failing.

from vm2.

XmiliaH avatar XmiliaH commented on June 7, 2024

That seems to be the problem. The list is generated in genLookupPaths but I do not see why this should not work with the Macbook.

from vm2.

fcbrandon avatar fcbrandon commented on June 7, 2024

Just uninstalled Node and used nvm to reinstall the current LTS - got the exact same issue. 🤔

I'll see if I can debug what's up with genLookupPaths then.

from vm2.

fcbrandon avatar fcbrandon commented on June 7, 2024

Debugging found that options passsed into resolveFull is undefined, which won't it through the check on line 282:

if (typeof options === 'object' && options !== null) {

So the code is never hitting genLookupPaths.

options is set as such over in:

const filename = resolver.resolve(mod, id, undefined, Module._extensions, direct);

On my working Ubuntu instance, the code never hits genLookupPaths either though. On my build, paths come from mod.paths.

So I traced that back, and the paths seem to be based on the options variable passed in at:

run(code, options) {

And this is the first place I'm seeing the difference between my two instances. On the working Ubuntu instance, options is set to 'vm.js'.
image
However, on my Macbook, it's undefined:
image

Sooooo, I went back into the original example code, and manually added an option as 'vm.js':

vm.run(`
    var request = require('request');
    request('http://www.google.com', function (error, response, body) {
        console.error(error);
        if (!error && response.statusCode == 200) {
            console.log(body); // Show the HTML for the Google homepage.
        }
    });`, "vm.js");

And now everything works fine.
I checked the version of Node and NPM on each instance, but they're exactly the same - Node: v18.16.0, NPM: 9.5.1.
I have zero idea why this happens on the Macbook, and not in Ubuntu, but now I can see what is happening, and have a pretty simple work around.

If anyone wants me to try further debugging, send me some instructions and I'll see if I can help figure out what's happening here.

Thanks for brainstorming this with me @XmiliaH - it helps to have someone else to bounce these things off and work through out!!!

from vm2.

XmiliaH avatar XmiliaH commented on June 7, 2024

Sooooo, I went back into the original example code, and manually added an option as 'vm.js':

This is required and is set in the examples. Without it only absolute modules can be loaded.

from vm2.

fcbrandon avatar fcbrandon commented on June 7, 2024

Nonetheless, it works in some scenarios, and not in others.

And if it's required, then I guess we should update README, accordingly?

from vm2.

XmiliaH avatar XmiliaH commented on June 7, 2024

Nonetheless, it works in some scenarios, and not in others.

Yes, there are scenarios where it should not work as one can restrict the lookup paths.

And if it's required, then I guess we should update README, accordingly?

Where should it be updated? The example posted in #520 (comment) has it set.

from vm2.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.