patriksimek / vm2

Advanced vm/sandbox for Node.js
MIT License
3.86k stars 293 forks source link

Work in a bundle #528

Open lijingmu opened 1 year ago

lijingmu commented 1 year ago

I use webpack to create a bundle, vm2 is one dependency. webpack can work well with following config:

ignoreWarnings: [
        {
                message: /Can't resolve 'coffee-script'/,
        },
]
module: {
        parser: {
                javascript: {
                        commonjsMagicComments: true
                }
        }
}

when I run the project I encountered:

Error: ENOENT: no such file or directory, open 'xx/dist/bridge.js'

I think it is because below:

vm2/lib/vm.js
    const bridgeScript = compileScript(`${__dirname}/bridge.js`,
        `(function(global) {"use strict"; const exports = {};${fs.readFileSync(`${__dirname}/bridge.js`, 'utf8')}\nreturn exports;})`);
    const setupSandboxScript = compileScript(`${__dirname}/setup-sandbox.js`,
        `(function(global, host, bridge, data, context) { ${fs.readFileSync(`${__dirname}/setup-sandbox.js`, 'utf8')}\n})`);

vm2/lib/nodevm.js
        if (!cacheSandboxScript) {
            cacheSandboxScript = compileScript(`${__dirname}/setup-node-sandbox.js`,
                `(function (host, data) { ${fs.readFileSync(`${__dirname}/setup-node-sandbox.js`, 'utf8')}\n})`);
        }

vm2/lib/nodevm.js
     if (!cacheEventsScript) {
    const eventsSource = fs.readFileSync(`${__dirname}/events.js`, 'utf8');
    cacheEventsScript = new VMScript(`(function (fromhost) { const module = {}; module.exports={};{ ${eventsSource}
            } return module.exports;})`, {filename: 'events.js'});
     }

I have to copy these files to dist. Any suggestions or workaround? Thanks

lijingmu commented 1 year ago

Finally I use scripts to bundle them, it works well now.

1. add post build in NPM script
"build": "webpack --config ./webpack.prod.config.js && node prepare-package.js postBuild",

2. copy files from node_modules to output directory after build in prepare-package.js
const postBuild = async () => {
  await cpvm2("bridge.js");
  await cpvm2("events.js");
  await cpvm2("setup-sandbox.js");
  await cpvm2("setup-node-sandbox.js");
};

3. add them in package.json files property to bundle them
karlhorky commented 1 year ago

Seems like this is causing all Puppeteer bundled scripts to fail as well (eg. bundling with esbuild):

@patriksimek any idea what could be causing this?

karlhorky commented 1 year ago

Oh it seems like vm2 has been incompatible with bundling for years, hope the approach of using fs.readFileSync() and similar to read files inside of node_modules on runtime can be reconsidered 🤞