2012-08-08 5 views
16

In einem PhantomJS-Skript möchte ich ein benutzerdefiniertes Modul laden, aber es scheint, relative Pfade funktionieren nicht in PhantomJS?PhantomJS require() ein relativer Pfad

script.js:

var foo = require('./script/lib/foo.js'); 
foo.bar('hello world'); 
phantom.exit(); 

foo.js:

exports.bar = function(text){ 
    console.log(text); 
} 
  • Nach fs.workingDirectory ich im guten Verzeichnis bin
  • foo.js ist nicht in der Lookup Weg des Phantomjs

Am Ich vermisse etwas?

EDIT:

inject() ist nicht Revelant weil ich kein JS zu einer HTML-Seite injizieren muß, sondern mein eigenes Modul laden, wie erforderlich (‚fs‘), aber mit einem relativen Pfad.

Antwort

12

Nach viel Zeit für die gleiche Sache suchen, hier ist das, was ich verstanden, obwohl ich falsch sein könnte:

  • PhantomJS nicht verwendet Knotens require, aber seine eigene require, so die Dinge anders
  • sind, wenn sie einen relativen Pfad zu PhantomJS der Bereitstellung require wird immer als relativ zu dem Verzeichnis aktuelle Arbeits interpretiert
  • PhantomJS nicht implementiert der Knoten __dirname, und als solche gibt es keine direkte Möglichkeit, das Verzeichnis des Skriptes

Die Lösung, die ich am wenigsten störend empfunden haben:

  • bei Verwendung von PhantomJS rein, ohne casperjs:

    require(phantom.libraryPath + '/script/lib/foo.js') 
    
  • bei Verwendung von casperjs:

    var scriptName = fs.absolute(require("system").args[3]); 
    var scriptDirectory = scriptName.substring(0, scriptName.lastIndexOf('/')); 
    require(scriptDirectory + '/script/lib/foo.js') 
    
0

haben Sie injectJs (Dateiname)

Auszug Form PhantomJS Dokumentation zu nutzen versucht:

Spritzt externen Skriptcode aus der angegebenen Datei. Wenn die Datei nicht im aktuellen Verzeichnis gefunden werden kann, wird libraryPath für zusätzliche Suche verwendet.

Diese Funktion gibt true zurück, wenn die Injektion erfolgreich war, andernfalls gibt sie false zurück.

+5

Inject wird verwendet, um eine .js-Datei in die Headless-Seite zu injizieren. Ich benutze es, um eine jquery.js in eine bestimmte Seite zu injizieren. Ich muss mein eigenes Modul laden, wie ich es mit request ('fs') gemacht habe. Aber ich würde gerne einen relativen Pfad wie in NodeJS verwenden –

+0

So scheint phantom.injectJs() für meinen einfachen Fall zu arbeiten. Die Zieldatei sollte kein Modul sein. Es scheint, es gibt eine Diskussion über die ML. –

0

Welche PhantomJS-Version verwenden Sie? Unterstützung für von Benutzern bereitgestellte Module wurde in 1.7 hinzugefügt.

3

Um ein eigenes Modul, der richtige Weg, laden Sie es zu tun ist, module.exports zu verwenden, wie folgt aus: foo.js

function bar(text) { 
    console.log(text); 
} 

exports.bar = bar 

Und in script.js (der ausgeführt wird, mit Phantomjs-Skript.js):

var foo = require('./script/lib/foo'); 
foo.bar('hello world'); 
phantom.exit(); 
+1

Wie ist das anders als die Frage? –

2

Meine Lösung eine Ressource-Datei (wie sagen wir mal eine json Datei) innerhalb eines phantomjs Unterordner von einem äußeren Ordner wie in dieser Struktur zu laden:

├── consumer.js 
├── assets 
    ├── data.json 
    ├── loader.js 

Vermeintliche dass data.json Belastung durch die consumer sein muss Modul und dass dieses Modul von woanders auf diesem Computer außerhalb des Projektstammordners aufgerufen wird, funktioniert fs.workingDirectory nicht, da es der Pfad der aufrufenden Datei ist. Also dieses Problem zu lösen, habe ich ein einfaches loader Modul innerhalb des assets Ordner, in dem die Dateien, die ich zu ladende:

(function() { 

var loader = { 
    load : function(fileName) { 
     var res=require('./'+fileName); 
     return res; 
    } 
} 
module.exports=loader; 

}).call(this); 

ich das deshalb nennen loader Modul aus dem consumer Modul wie

var loader=require('./data/loader'); 
var assets=loader.load('data.json'); 

und das war's.

HINWEIS. Die require hier ist die phantomjs erfordern nicht die node Version, so dass es ein bisschen anders funktioniert. In diesem Fall war data.json ein JSON-Array ohne module.exports Deklaration. Das Array wird in der Variablen assets direkt beim Aufruf der Methode loader.load(fileName) gesichert.