phpv8 / v8js

V8 Javascript Engine for PHP — This PHP extension embeds the Google V8 Javascript Engine
http://pecl.php.net/package/v8js
MIT License
1.84k stars 200 forks source link

Do we have to implement our own CommonJS Module by default. #235

Closed TheLarkInn closed 8 years ago

TheLarkInn commented 8 years ago

As I finally busted out php-v8js (5.6.10) I tried to use a CommonJS require('parse5') however the error message out of the box was as follows:

object(V8JsScriptException)[2]
  protected 'message' => string 'V8Js::compileString():1: No module loader' (length=41)
  private 'string' (Exception) => string '' (length=0)
  protected 'code' => int 0
  protected 'file' => string '/data/http/moo/veight/index.php' (length=31)
  protected 'line' => int 6
  private 'trace' (Exception) => 
    array (size=1)
      0 => 
        array (size=6)
          'file' => string '/data/http/moo/veight/index.php' (length=31)
          'line' => int 6
          'function' => string 'executeString' (length=13)
          'class' => string 'V8Js' (length=4)
          'type' => string '->' (length=2)
          'args' => 
            array (size=1)
              ...
  private 'previous' (Exception) => null
  protected 'JsFileName' => string 'V8Js::compileString()' (length=21)
  protected 'JsLineNumber' => int 1
  protected 'JsStartColumn' => int 0
  protected 'JsEndColumn' => int 1
  protected 'JsSourceLine' => string 'require("./index.js")' (length=21)
  protected 'JsTrace' => null
  public 'xdebug_message' => string '<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> V8JsScriptException: V8Js::compileString():1: No module loader in /data/http/moo/veight/index.php on line <i>6</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Fu'... (length=1197)

Is this something the user has to implement themselves? I see some commonjs libs inside the src lib, however I wasn't sure if there was a build error or not.

y8r commented 8 years ago

+1

stesie commented 8 years ago

The build seems correct and V8Js working properly.

V8Js provides a require API method to JS code that must be backed by a custom module loader. V8Js neither makes assumptions from where to load module code (file system, database, whatever) nor how the modules are structured (e.g. with node_modules folders or whatever).

So yes, you need to (at least) provide a module loader (via $v8->setModuleLoader(<callable>)) that resolves a module name to JavaScript source code. By default V8Js however does module path normalisation, that is if your entrypoint code does require('foo/bar') and the module code in turn does (require('./baz') then the module loader PHP function is called with foo/baz.

In case you'd like to override this normalisation behaviour you can override be providing another callable to $v8->setModuleNormaliser

If you're willing to load Node.js modules keep in mind that that can only work as long as all dependencies don't depend on core stuff or modules that need native code. You might want to check out a Gist of mine: https://gist.github.com/stesie/c9143b98355295420470 which shows how to compile coffeescript code with V8Js and run that afterwards