laverdet/isolated-vm

Cannot get returned value after bundling using webpack

Henry-Le-CS opened this issue · 5 comments

According to the author and discussion, when using external libraries, I may have to use Webpack to bundle the code. However, I cannot get the value from the code after I bundled it into a Js file.
Here is my simple code before bundling:

// prebundle.js
const _ = require('lodash')

;(()=>{
    const array = [1, 2, 3, 4, 5]
    const chunkedArray = _.chunk(array, 2)

    console.log('Original Array:', array)
    console.log('Chunked Array:', chunkedArray)

    return JSON.stringify(chunkedArray)
})();

After the file is bundled, I could run it using node bundle.js.

Here is how i integrated it with isolated-vm:

const ivm = require('isolated-vm');
const fs = require('fs');

 const code = fs.readFileSync('./bundle.js', 'utf-8');
// const code = '(()=> {return "hello world"})()'

const isolate = new ivm.Isolate({ memoryLimit: 8 /* MB */ });
const context = isolate.createContextSync();

(async () => {
    try {
        const script = await isolate.compileScript(code);
        const result = await script.run(context);
        console.log(result);
    } catch (error) {
        console.error(error?.message);
    }
})();

Did I miss something on this issue ? How can I import a module, bundle then inject the bundled code in isolated-vm properly in this case where you have code that needs external libraries ( assume that they do not involve filesystem, network, etc) ? As you can see, (()=> {return "hello world"})() would work just fine.

Obviously there would be differences between prebundled and bundled file. But how could we expect the bundled file to return a value for us to catch after compiling and running the script here ?
Please provide a working snippet if you can as I am new to Webpack stuff.

I'm not sure what you're asking. Maybe this is a question about Webpack?

import ivm from 'isolated-vm';
const isolate = new ivm.Isolate;
const context = await isolate.createContext();
console.log(await context.eval('"hello world"'));

This sample evaluates a simple program containing only an expression statement "hello world". The outer nodejs isolate then logs it. You just need to scale up from here.

But if I need to import external libraríe like lodash (to do something ) then return a single value. I would also need to bundle it into a large js file then eval it in the isolate.
But using bundling method does not ensure the returned of the value. Is this expected ?

I'm still not sure what you're asking, my friend. Try posting an example program here along with a description of what you would expect it to output.

Okay. In my issue above, you can see there is a js file (prebundle.js) that needs external libraries to run.
I need to put this code into isolate to run. It is expected to return chunkedArray after we eval the code.

But since I imported the module lodash, I had to go through steps like bundling the code using webpack into a large js file, then actually put that bundled code into the isolate's code. But this no longer give me the chunkedArray.

So what could I do here to obtain the returned value after bundling ? or did I do something wrong that you can help me with ?

If you replace your entire program with this:

const fs = require('fs');
console.log(eval(fs.readFileSync('./bundle.js', 'utf-8')));

What do you see? I don't think this is a question about isolated-vm. I think that you're asking a question about Webpack but it's hard to be sure with the information that you've provided. I might recommend trying esbuild too since it can be easier to get it running for new developers. Good luck!