Skip to content
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

Experimental vm modules #3068

Closed
d3x0r opened this issue Nov 9, 2020 · 3 comments
Closed

Experimental vm modules #3068

d3x0r opened this issue Nov 9, 2020 · 3 comments

Comments

@d3x0r
Copy link

d3x0r commented Nov 9, 2020

  • Node.js Version: 15.1.0
  • OS: Windows/Linux
  • Scope (install, code, runtime, meta, other?): runtime
  • Module (and version) (if relevant): vm

I was recently updating this service code to use import instead of require since web browsers support that better; and development is driving me to update. Part of the service system shares its API across a websocket, and to enable using import in code, I had to update from using eval() or Function() or even AsyncFunction(), and use vm.SourceTextModule, which gives me the ability during await module.link(() => {}); (the callback to link is modules it further needs, allowing me to request them appropriately), but there are some things which are available from the local environment instead, which has actually already been loaded or could simply be loaded with 'import()'

somethiing like...

module.link((spec) => { 
    return import(spec) 
});

I can pass modules that have been imported already as part of the context object specified to SourceTextModule(code,{context:{path:path,url:url,...})... but modules that haven't already been loaded I would have to instead make a Synthetic module...

function wrapObject(obj){
    if( obj instanceof vm.Module ) return obj;
    if( obj instanceof Promise ) return obj.then( wrapObject );  
	const keys = Object.keys(obj);
  // 'sm' is 'SyntheticModule'
	const sm = new vm.SyntheticModule(keys, ()=>{
                        for( let key of keys )
                            sm.setExport(key,obj[key]);
		}, {context:defaultContext} );
        return sm.link( ()=> {} ).then( ()=>sm.evaluate().then( (result)=>sm ) );
}

linkCallback(spec,ref) { return wrapObject( import(spec ) ) }

This was the previously proposed method I found on nodejs/node#27387 'Modules: Specify or infer module type for new vm.Script'; although this method fails for modules that have a export called import or default

function wrapObjectBad(obj) {
    const str = Object.keys(obj).map((x)=>`export const ${x} = import.meta.mod.${x};`)
            .join('\n');
    const module = new vm.SourceTextModule( str, {
                initializeImportMeta(meta){
                    meta.mod=obj;
                },
    });
       }
    return module;
}

I'm just wondering, since this is 'experimental' why passing existing modules ( ie from just 'import') is so very difficult...

@preveen-stack
Copy link
Contributor

@d3x0r were you able to find any answer to the question? let us know

Copy link

It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment.
If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
Make sure to look at the README file for the most updated links.

@github-actions github-actions bot added the stale label May 11, 2024
Copy link

It seems there has been no activity on this issue for a while, and it is being closed. If you believe this issue should remain open, please leave a comment.
If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
Make sure to look at the README file for the most updated links.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants