Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
332 views
in Technique[技术] by (71.8m points)

node.js - nodejs cannot find module 'zombie' with PHP mink

I'm trying out Mink (PHP) on Ubuntu 14.04; I basically did the following:

$ apt-show-versions nodejs
nodejs:amd64/trusty 0.10.45-1nodesource1~trusty1 uptodate
$ npm -v
2.15.1
$ sudo npm install -g zombie
npm WARN engine [email protected]: wanted: {"node":"^4.0.0"} (current: {"node":"0.10.45","npm":"2.15.1"})
...
[email protected] /usr/lib/node_modules/zombie
├── [email protected]
├── [email protected]
...

$ ls /usr/lib/node_modules/zombie/node_modules/
babel-runtime  bluebird  debug  eventsource  iconv-lite  jsdom  lodash  mime  ms  request  tough-cookie  ws

So, basically, even if I get a warning, the modules build, and should be in the directory /usr/lib/node_modules.

Then I do:

mkdir test_php_mink
cd test_php_mink/
composer require behat/mink
composer require behat/mink-zombie-driver

As a check:

test_php_mink$ ls
composer.json  composer.lock  vendor

... it seems all composer files are there.

Finally, as per http://mink.behat.org/en/latest/drivers/zombie.html (and also Cannot find module 'zombie' · Issue #84 · assaf/zombie · GitHub), I'm trying this script:

<?php

# composer autoload:
require_once __DIR__ . '/vendor/autoload.php';

echo "safe_mode: '" . ini_get("safe_mode") ."'
"; # have PHP 5.5.9, safe_mode is removed

putenv("NODE_PATH=/usr/lib/node_modules");
echo "NODE_PATH is: '" . getenv ( "NODE_PATH" ) . "'
"; # OK, is there

# NOPE:
#$driver = new BehatMinkDriverombieDriver();

$driver = new BehatMinkDriverombieDriver(
  new BehatMinkDriverNodeJSServerombieServer()
);

$session = new BehatMinkSession($driver);

// start the session
$session->start();
?>

This script, unfortunately, still fails with:

$ php test_php_mink.php 
safe_mode: ''
NODE_PATH is: '/usr/lib/node_modules'
PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'Server process has been terminated: (8) [
module.js:340
    throw err;
          ^
Error: Cannot find module 'zombie'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/path/to/test_php_mink/vendor/behat/mink-zombie-driver/bin/mink-zombie-server.js:3:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
]' in /path/to/test_php_mink/vendor/behat/mink-zombie-driver/src/NodeJS/Server.php:413
Stack trace:
#0 /path/to/test_php_mink/vendor/behat/mink-zombie-driver/src/NodeJS/Server.php(306): BehatMinkDriv in /path/to/test_php_mink/vendor/behat/mink-zombie-driver/src/NodeJS/Server.php on line 413

How can I get this basic example to run?


EDIT: Played around a bit more with this, and discovered that when I specify the environment variable on the command line:

$ NODE_PATH=/usr/lib/node_modules php test_php_mink.php
safe_mode: ''
NODE_PATH is: '/usr/lib/node_modules'
PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'Server process has been terminated: (8) [
/usr/lib/node_modules/zombie/node_modules/jsdom/lib/jsdom/level2/html.js:238
var nonInheritedTags = new Set([
                           ^
ReferenceError: Set is not defined
...

... then the module seems to be found! So my question basically reduces to: how can I change the NODE_PATH environment variable from my php script, so I wouldn't have to specify it on the shell - since apparently putenv("NODE_PATH=/usr/lib/node_modules"); does not really work for me...

As for the new error, there is Installing Zombie.js Error: ReferenceError: Set is not defined. What am I doing wrong? - apparently this is due to the version mismatch that I got a warning for (npm WARN engine [email protected]: wanted: {"node":"^4.0.0"} (current: {"node":"0.10.45","npm":"2.15.1"})), so I guess I'll have to install nvm so I can install the right nodejs version; and I also noticed in /usr/lib/node_modules/zombie/README.md:

Zombie 4.x is tested to work with io.js 1.6 or later.
If you need to use Node 0.12 or earlier, consider using Zombie 2.x. ...
To install Zombie.js you will need io.js:
```bash
$ npm install zombie --save-dev
```

... and I think that can also be installed with nvm; so I'll give that a try...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, found some sort of a method which seemingly works - but I'd still like someone more knowledgeable to answer.

Anyways, the trick is - zombie can accept a path to the nodejs binary; so if you cannot really pass environment variables for nodejs from PHP, then make a shell script which will set these environment variables, and then call nodejs.

First this was my install:

# remove previous
sudo npm uninstall -g zombie --save-dev
sudo apt-get remove --purge nodejs && sudo apt-get autoremove --purge

# install new
curl -o- https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
nvm install iojs-v3.3.1
npm list -g --depth=0
nvm install 4.0.0
npm list -g --depth=0
npm -g install zombie --save-dev

The problem with nvm is that it installs in a user directory, and I'd like to test my scripts both on my user machine and remote server, where my uids are completely different. Regardless, using a custom executable helps a bit with that. So, create a script in a "global" location, I chose /home, so I'll need sudo to create files there:

sudo touch /home/node_pth.sh

... then paste in the following content:

#!/bin/bash
export NODE_PATH=/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules
#echo ARGS ARE "$@" | tee -a /tmp/node.log
/home/USERNAME/.nvm/versions/node/v4.0.0/bin/node "$@"

... of course, replacing the paths with your correct ones; then finally make it executable:

sudo chmod +x /home/node_pth.sh

Now we can use the following test_php_mink.php PHP file:

<?php

$nodeModPath = "/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules"; # correct NODE_PATH, but will not help
$nodePath = "/home/node_pth.sh"; # shell script that sets NODE_PATH, then calls node executable

echo "NODE_PATH is: '" . getenv ( "NODE_PATH" ) . "'
"; #
putenv("NODE_PATH=".$nodeModPath);
echo "NODE_PATH is: '" . getenv ( "NODE_PATH" ) . "'
"; # is there - but still doesn't help with call

# composer autoload:
require_once __DIR__ . '/vendor/autoload.php';

echo "safe_mode: '" . ini_get("safe_mode") ."'
"; # have PHP 5.5.9, safe_mode is removed


$driver = new BehatMinkDriverombieDriver(
  //~ new BehatMinkDriverNodeJSServerombieServer()
  # copy defaults here for everything but nodeBin;
  # see vendor/behat/mink-zombie-driver/src/NodeJS/Server.php
  new BehatMinkDriverNodeJSServerombieServer("127.0.0.1", 8124, $nodePath, null)
);

$session = new BehatMinkSession($driver);

// start the session
$session->start();
?>

... OR, I just realized there is setNodeModulesPath($nodeModulesPath) in vendor/behat/mink-zombie-driver/src/NodeJS/Server.php, so we can drop the proxy bash executable altogether:

<?php

$nodeModPath = "/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules"; # correct NODE_PATH, but will not help via putenv

echo "NODE_PATH is: '" . getenv ( "NODE_PATH" ) . "'
"; #
putenv("NODE_PATH=".$nodeModPath);
echo "NODE_PATH is: '" . getenv ( "NODE_PATH" ) . "'
"; # is there - but still doesn't help with call

# composer autoload:
require_once __DIR__ . '/vendor/autoload.php';

echo "safe_mode: '" . ini_get("safe_mode") ."'
"; # have PHP 5.5.9, safe_mode is removed

$zsrv = new BehatMinkDriverNodeJSServerombieServer();
$zsrv->setNodeModulesPath($nodeModPath . "/"); # needs to end with a trailing '/'

$driver = new BehatMinkDriverombieDriver( $zsrv );

$session = new BehatMinkSession($driver);

// start the session
$session->start();

?>

Anyways, when this script is called, it outputs:

$ php test_php_mink.php
NODE_PATH is: ''
NODE_PATH is: '/home/USERNAME/.nvm/versions/node/v4.0.0/lib/node_modules'
safe_mode: ''

... and as there are no errors, I'm assuming it is all fine now...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...