2012-06-26 23 views
6

códigos en main.js archivo es la siguiente:PhantomJS y RequireJS

 phantom.injectJs("libs/require-1.0.7.js"); 
     require.config(
     { 
      baseUrl: "" 
     } 
    ); 
     require([], function(){}); 

cuando corro "PhantomJS main.js" en la línea de comandos, RequireJS no funciona bien en el main.js. Sé cómo usar requirejs en la página que se ejecuta en el navegador (incluida la forma de phantomjs: page.open (url, callback)), pero no como en el ejemplo anterior. Trato de usar requirejs como main.js, es un problema popular, creo. ¡Gracias!

+0

¿Alguna vez resolver esto? –

+0

Llegué un poco más lejos ... puede obtener acceso a las necesidades reales para requerir una variable como esta: require = null; phantom.injectJs ('target/dependencies/requirejs-tar.gz/require.js'); –

+0

@Thomas, voy a intentarlo, :) – user1395927

Respuesta

1

está malentendido webpage.injectJs()

es para inyectar secuencias de comandos en la página que va a cargar, no en el entorno de tiempo de ejecución PhantomJS.

Así que usar .injectJs() está haciendo que los requisitos carguen en su página, no en phantomjs.exe.

Dicho esto, el entorno de tiempo de ejecución de phantomjs tiene una aproximación de commonjs. RequireJs no se ejecutará allí por defecto. Si te sientes especialmente (MUY) motivado, puedes intentar portar el requerimiento-shim creado para nodejs, pero no funciona de la caja, y requeriría una comprensión increíblemente profunda de los tiempos de ejecución. para más detalles: http://requirejs.org/docs/node.html

una mejor idea: probablemente le debe asegurarse de que tiene las versiones CommonJS de javascript que desea ejecutar. Yo personalmente escribo mi código en mecanografiado para que pueda compilar para commonjs o amd. utilizo commonjs para el código phantomjs, y amd para nodejs y el navegador.

2

Luché por un tiempo. Mi solución no está limpia, pero funciona, y estoy contento con eso debido a la documentación inacabada de api de phantomjs.

Explicación de Wordy

Necesita tres archivos. Uno es su archivo de prueba amd phantomjs que llamaré "amd.js". El segundo es cargar tu página html a la que llamaré "amd.html". Finalmente, la prueba del navegador que llamé "amdTestModule.js".

En amd.html, declare su etiqueta de script por la normalidad:

<script data-main="amdTestModule.js" src="require.js"></script> 

En el archivo de prueba PhantomJS, aquí es donde se pone hacky. Crea tu página y cárgala en el módulo 'fs'. Esto le permite abrir una ruta de archivo relativa.

var page = require('webpage').create(); 
var fs = require('fs'); 

page.open('file://' + fs.absolute('tests/amd.html')); 

Ahora ya que los archivos de forma asíncrona RequireJS cargas, no podemos pasar de una devolución de llamada en page.open y esperar que las cosas van bien. Necesitamos alguna forma de
1) Pruebe nuestro módulo en el navegador y comunique el resultado a nuestro contexto phantomjs. O
2) Indique a nuestro contexto phantomjs que al cargar todos los recursos, ejecutar una prueba.

# 1 era más simple para mi caso. Lo logré a través de:

page.onConsoleMessage = function(msg) { 
    msg = msg.split('='); 
    if (msg[1] === 'success') { 
     console.log('amd test successful'); 
    } else { 
     console.log('amd test failed'); 
    } 
    phantom.exit(); 
}; 

** Vea el código completo a continuación para mi mensaje console.log.

Ahora parece que phantomjs tiene una api de evento incorporada pero no está documentada. También pude obtener con éxito mensajes de solicitud/respuesta de su página.enResourceReceived y de la página.onResourceRequested: lo que significa que puede depurar cuando se cargan todos los módulos necesarios. Sin embargo, para comunicar el resultado de mi prueba, acabo de usar console.log.

Ahora, ¿qué ocurre si el mensaje console.log nunca se ejecuta? La única manera de que pudiera pensar en la solución de esta era utilizar setTimeout

setTimeout(function() { 
    console.log('amd test failed - timeout'); 
    phantom.exit(); 
}, 500); 

Eso debería hacerlo!

Código completo

estructura de directorios

/projectRoot 
    /tests 
    - amd.js 
    - amdTestModule.js 
    - amd.html 
    - require.js (which I symlinked) 
    - <dependencies> (also symlinked) 

amd.js

'use strict'; 
var page = require('webpage').create(); 
var fs = require('fs'); 

/* 
page.onResourceRequested = function(req) { 
    console.log('\n'); 
    console.log('REQUEST'); 
    console.log(JSON.stringify(req, null, 4)); 
    console.log('\n'); 
}; 
page.onResourceReceived = function(response) { 
    console.log('\n'); 
    console.log('RESPONSE'); 
    console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + JSON.stringify(response, null, 4)); 
    console.log('\n'); 
}; 
*/ 

page.onConsoleMessage = function(msg) { 
    msg = msg.split('='); 
    if (msg[1] === 'success') { 
     console.log('amd test successful'); 
    } else { 
     console.log('amd test failed'); 
    } 
    phantom.exit(); 
}; 

page.open('file://' + fs.absolute('tests/amd.html')); 

setTimeout(function() { 
    console.log('amd test failed - timeout'); 
    phantom.exit(); 
}, 500); 

amd.html

<!DOCTYPE html> 
<html> 

<head> 
    <meta charset="UTF-8"> 
</head> 

<body> 
    <script data-main='amdTestModule.js' src='require.js'></script> 
</body> 

</html> 

amdTestModule.js

require([<dependencies>], function(<dependencies>) { 
    ... 
    console.log(
     (<test>) ? "test=success" : "test=failed" 
    ); 
}); 

consola

$ phantomjs tests/amd.js 
amd test successful