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

Support for ES Modules #456

Open
joehoyle opened this issue Nov 25, 2020 · 6 comments
Open

Support for ES Modules #456

joehoyle opened this issue Nov 25, 2020 · 6 comments

Comments

@joehoyle
Copy link

I believe recent versions of V8 have native support for ESM modules (https://v8.dev/features/modules). I don't think this is bridged to V8Js via the setModuleLoader though (which perhaps just does something like provide a require function declaration to the JS runtime).

Reading https://stackoverflow.com/questions/52023157/how-would-one-enable-and-use-es6-modules-in-the-v8-javascript-engine, it looks like this is a new set of APIs on the V8 API. So, would this be possible to integrate into v8js?

@chrisbckr
Copy link
Contributor

NodeJS uses the ".mjs" file extension, the package.json "type" field, or the --input-type flag. How this can be implemented? V8Js::executeModule()?
And if after that I call V8Js::executeScript()? It's possible? Every module has their unique context. They will share the context of the scripts that are executed with V8JS::executeScript() like browsers do?

Just throwing some thoughts about how this can be implemented! 😄

@redbullmarky
Copy link
Collaborator

It feels like the only way to implement it natively would be to essentially treat the initial executed code as a module itself, so that import would work similar to require Perhaps wrapping the executed code with an internal entry script of sorts.

I managed to get something working a year or two back, albeit using babel to transpile code before executing. Just not in a native way.

@redbullmarky
Copy link
Collaborator

@chrisbckr This was part of the original test I played around with:

<?php
// requires babel standalone from here:
// https://github.com/babel/babel-standalone
$v8 = new \V8Js();

// code to transpile
$v8->sourceCode = <<<EOF
import * as stuff from './foo';

a = () => {
    print("hello there from inside an arrow function!!...");
    return "return value from a function";
}
EOF;

// actual transpiler code
$script = <<<EOF
Babel.transform(PHP.sourceCode, {presets:['es2015']}).code;
EOF;

// include babel & execute our transpiler
$v8->executeString(file_get_contents(__DIR__ . '/babel.min.js'));
$transpiled = $v8->executeString($script);

// v8js's return mechanism and 'strict' mode...V8Js's return mechanism requires 
// assigning to an undefined variable.
$transpiled = str_replace('"use strict"', '', $transpiled);

echo "TRANSPILED TO:\n\n" . $transpiled . "\n\n\n";
echo "-----------\nEXECUTING:\n\n";

// now execute the transpiled code
$v8 = new \V8Js();
$v8->setModuleLoader(function($filename) { 
   print("Loading {$filename} via ES6 module...\n"); 
});
print_r($v8->executeString($transpiled)());

@chrisbckr
Copy link
Contributor

I will look on this to use here for now, I really liked. Today I have typescript compiler embedded, like deno do. 😅
So, why not babel? 😆

But to run es6 modules on v8 it's a little different than "normal" scripts, maybe some of the commonjs implementation can be reused but with de v8's module calls.

@joehoyle
Copy link
Author

joehoyle commented Feb 21, 2023

FYI I've also / mostly moved work from v8js to php-deno (https://github.com/joehoyle/php-deno) which has support for Es6 modules natively (and also have the TypeScript compiler via swc embedded)

@chrisbckr
Copy link
Contributor

I implemented a basic compileModuleString, executeModule and executeModuleString.
Lacks imports resolution. It just return the referrer module itself for testing purposes.
If someone is interested, my code is here:
https://github.com/chrisbckr/v8js/tree/php8-es6_modules

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

3 participants