2012-08-08 28 views
16

En un guión PhantomJS me gustaría cargar un módulo personalizado pero parece rutas relativas no lo hacen obras en PhantomJS?PhantomJS requieren() una ruta relativa

script.js:

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

foo.js:

exports.bar = function(text){ 
    console.log(text); 
} 
  • Según fs.workingDirectory estoy en el directorio buena
  • foo.js no está en la búsqueda camino de PhantomJS

Am Me falta algo?

EDIT:

inyección() no es revelant porque no necesitar inyectarse una JS a una página HTML pero en vez cargar mi propio módulo como require ('fs'), pero con una ruta relativa.

Respuesta

12

Después de mucho tiempo en busca de lo mismo, aquí es lo que entendí, aunque puedo estar equivocado:

  • PhantomJS no utiliza de Nodo require, pero su propia require, así que las cosas son diferentes
  • al proporcionar una ruta relativa a PhantomJS de require, que siempre se interpreta como relativa al directorio de trabajo actual
  • PhantomJS no implementa nodo de __dirname, y como tal, no hay manera directa para que el directorio de su script

La solución que encontré menos molesto:

  • si se utiliza PhantomJS puros, sin casperjs:

    require(phantom.libraryPath + '/script/lib/foo.js') 
    
  • si utilizando casperjs:

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

has necesitado utilizar injectJs (nombre de archivo)

extracto forma PhantomJS documentación:

inyecta código de script externo desde el archivo especificado. Si el archivo no puede puede encontrar en el directorio actual, LibraryPath se utiliza para aspecto adicional hasta.

Esta función devuelve verdadero si la inyección se realiza correctamente, de lo contrario vuelve falsa.

+5

Inject se utiliza para inyectar un archivo .js en la página sin cabeza. Lo uso para inyectar un jquery.js en una página determinada. Necesito cargar mi propio módulo como lo hice con require ('fs'). Pero me gustaría utilizar una ruta relativa como en NodeJS –

+0

Así que phantom.injectJs() parece funcionar para mi caso simple. El archivo de destino no debe ser un módulo. Parece que hay alguna discusión sobre el LD. –

0

Qué PhantomJS versión que se ejecuta? El soporte para los módulos proporcionados por el usuario se agregó en 1.7.

3

Para cargar su propio módulo, la forma correcta de hacerlo es utilizar module.exports, así: foo.js

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

exports.bar = bar 

Y en script.js (que se ejecuta con el script phantomjs.JS):

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

¿Cómo es eso diferente de la pregunta? –

2

Mi solución para cargar un archivo de recursos (como digamos un archivo json) dentro de una subcarpeta phantomjs de una carpeta externa como en esta estructura:

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

Se supone que data.json debe haber carga por el consumer módulo y que este módulo es llamado por otra parte en esta máquina, fuera de la carpeta raíz del proyecto, el fs.workingDirectory no funcionará, ya que será la ruta del archivo de la persona que llama. Así que para solucionar esto, hice un módulo sencillo loader dentro de la carpeta assets, donde los archivos que desea cargar son:

(function() { 

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

}).call(this); 

lo tanto, pido el módulo loader del módulo consumer como

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

y eso es todo.

NOTA. El require aquí es el phantomjs no requiere la versión node, por lo que funciona de manera un poco diferente. En este caso, el data.json era una matriz json sin declaración module.exports. La matriz se respaldará en la variable assets directamente al llamar al método loader.load(fileName).