Используйте модуль node от casperjs

Возможно ли установить модуль node, установленный через npm, а затем require он из casperjs script?

(Я вижу много сообщений и инструментов для запуска casper или phantom изнутри node.js, но это не то, что я пытаюсь сделать.)

Кажется, что данные casperjs говорят, что это возможно, но показывают только ручные модули игрушек, которые на самом деле ничего не делают. Модуль реального мира, который я пытаюсь установить, это imap, но на данный момент я не могу заставить работать какой-либо модуль, даже встроенные, такие как net. Простой пример:

npm install imap
echo "var test = require('imap');" > test.js
casperjs test.js

Дает мне:

CasperError: Can't find module imap

/usr/local/src/casperjs/bin/bootstrap.js:263 in patchedRequire
test.js:1

(я вижу модуль imap из npm ls, и я могу использовать его отлично от node.js script.)

Или, альтернативно, со встроенным модулем:

echo "var test = require('net');" > test.js
casperjs test.js

Жалуется "Не могу найти сеть модуля"


Я npm --version 1.4.14 и nodejs --version из v0.10.29. Интересно, слишком ли старые люди? (Каспер - 1.1.0-бета, а phantom - 1.9.7, оба из которых являются последними версиями.)

Ответы

Ответ 1

PhantomJS и SlimerJS (двигатели, которые используются для CasperJS) не являются модулями Node.js. Они могут быть установлены через npm для удобства. У них есть другая базовая инфраструктура модулей, которая отличается от Node.js.

Вы не сможете использовать imap или любой модуль, который зависит от модуля net. Как указывает Фанч, есть модули, которые могут работать внутри среды выполнения phantomjs.

Если модуль использует только некоторые функции некоторого встроенного модуля Node.js, вы можете попытаться изменить реализацию, чтобы использовать API, который предоставляет phantomjs. Я не думаю, что это легко. Большую часть времени вы столкнетесь с стеной.

В случае imap это довольно безнадежно. Вы даже не можете повторно реализовать require("net").Socket, потому что WebSockets не поддерживаются в phantomjs (по крайней мере, в версии 1.9.7).

Ответ 2

Вот пример с модулем цветов:

var colors = require('colors');


 casper.test.begin('\n*Colors module*\n', function suite(test) {
    casper.start()
    .thenOpen('https://www.google.fr/', function() {
        console.log("test require\n".zebra);
        console.log("test require\n".rainbow);
        console.log("test require\n".red.underline.bold);
      })
    .run(function() {
            test.done();
    });
});
  • node -модулями
    • цвета
  • testnode.js

casperjs test testnode.js

вывод:

casper + colors module -npm-

Кажется, что это не так просто, когда требуемый модуль имеет зависимости.

Ответ 3

В моем случае я хотел загрузить underscorejs. Подчеркивание представляет собой ряд функций и не имеет сложных взаимодействий с объектами javascript, поэтому нет проблем, требующих только файла javascript, а затем доступа к его функциям.

Я начал с поиска корня в моей установке nodejs (из CLI):

node --help

Это привело меня к поиску пути node:

echo $NODE_PATH

Что было:

/usr/local/lib/node_modules/

Подчеркивание было

/usr/local/lib/node_modules/underscore/underscore.js

Итак, моя заключительная инструкция require в моем CasperJS script была.

var _ = require('/usr/local/lib/node_modules/underscore/underscore.js');

Теперь в моем script я тестирую, загружается ли underscorejs:

this.echo(_.now());

И я вижу текущее время.

CAVEAT: поскольку это выполняется асинхронно, если вы поместите свой оператор _.now() сразу после запроса, он даст вам ошибку объекта undefined. В качестве примечания, я использую Casper 1.1, который использует функцию require() функции PhantomJS. Если вы используете < Casper 1.1, я не думаю, что это потребует.

UPDATE: Так как это так, я использую функцию CasperJS then() для синхронного загрузки моих утилит, чтобы объявить мои переменные в глобальной области. Вот как это выглядит:

//at the top of the file-ish, declare variables that will hold loaded libraries.
var utils, _;
var casper = require('casper').create(); //create casper
casper.start('http://example.com'); //start casper at URL.

casper.then(function loadRequires(){ //load the requirements
    utils = require('utils', function(){this.echo('utils loded')});
    _ = require('/usr/local/lib/node_modules/underscore/underscore.js');
});

casper.then(function myAwesomeStuff() {
    this.echo(_.now()); //now, access the loaded requirements
    utils.dump('this stuff is soooo awesome!!!!!!!!!!!!!!!!!!!!');
    //do stuff on the page you opened in the start function here.
    );
});

Вы можете больше узнать о прототипе Каспера и методе then() в документах API: http://casperjs.readthedocs.org/en/latest/modules/casper.html#casper-prototype