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

ModuleLoader isn't passing the original $path #286

Closed ranaharoni closed 7 years ago

ranaharoni commented 7 years ago

Hi there,

I just noticed that a the module loader arg for the path does not pass the real path specified in the require argument.

// JS
var someInclude = require('../../components/myInclude.jsx')
...
// PHP
...

$v8js->setModuleLoader(function($path) {
    var_dump($path); exit;
});

...
// var_dump Output
string(25) "components/myInclude.jsx"

Is there any good reason it to omit the . and .. from the $path argument or is it just a bug?

AlexMasterov commented 7 years ago

This is not a bug. You need to write your own a loader, ad hoc.

A good example.

stesie commented 7 years ago

@ranaharoni this behaviour is caused by the "normalising" step of V8Js' require implementation. What it tries to do is resolve relative path names (like you're trying to give) to absolute ones, so the module loader callback is provided absolute path names.

Some simple example

// from root context
require('foo/bar'); // this calls the module loader with 'foo/bar'

// in foo/bar
require('./baz'); // this calls the module loader with 'foo/baz'

// still in foo/bar
require('../blar');  // this calls the module loader with 'blar'

So if you do not want that path normalisation by V8Js you need to provide some custom normalisation routine. So if you really really want no normalisation at all you can do something like

$v8->setModuleNormaliser(function($basedir, $load) { return [ '', $load ]; } );

However generally that is a bad idea if you require modules from other modules ...