Open joehoyle opened 3 years ago
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! 😄
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.
@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)());
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.
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)
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
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 arequire
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?