2012-06-26 50 views
6

代码是这样的:phantomjs和文件main.js requirejs

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

当我在命令行运行“phantomjs main.js”,requirejs不能很好的工作main.js.我知道如何在浏览器中运行的页面中使用requirejs(包括phantomjs的方式:page.open(url,callback)),但不像上面那样。我尝试使用main.js之类的requirejs,我认为这是一个流行的问题。谢谢!

+0

你有没有想出解决办法? –

+0

我还有一点点......你可以访问实际的requirejs require变量,如下所示: require = null; phantom.injectJs('target/dependencies/requirejs-tar.gz/require.js'); –

+0

@Thomas,我会尝试你的方式,:) – user1395927

回答

1

你误会webpage.injectJs()

它是注入脚本到您加载的页面,不进phantomjs运行环境。

因此使用.injectJs()会将requirejs加载到您的页面中,而不是加载到phantomjs.exe中。

也就是说,phantomjs的运行时环境具有commonjs的aproximation。 RequireJs默认不会在那里运行。如果你觉得特别的(非常)动机,你可以尝试移植为nodejs制作的require-shim,但它不能直接使用,并且需要对运行时间有非常深刻的理解。了解更多详情:http://requirejs.org/docs/node.html

一个更好的主意: 或许你应该确保你有你想运行的JavaScript CommonJS的版本。我个人写我的代码打字稿,所以我可以建立commonjs或amd。我使用commonjs作为phantomjs代码,amd作为nodejs和浏览器。

2

我只是挣扎了一段时间。我的解决方案不是干净的,但它的工作原理,我对此感到满意,因为来自phantomjs的未完成的api文档。

啰嗦的解释

您需要三个文件。一个是你的amd phantomjs测试文件,我将其称为“amd.js”。第二个是你要加载的html页面,我将命名为“amd.html”。最后是我称之为“amdTestModule.js”的浏览器测试。

在amd.html,声明你的脚本标签按正常:

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

在你phantomjs测试文件,这是它得到哈克。创建你的页面,并加载到'fs'模块中。这使您可以打开相对文件路径。

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

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

现在既然requirejs异步加载文件,我们不能只是传递一个回调到page.open和期望事情能够顺利进行。我们需要一些方法来
1)在浏览器中测试我们的模块,并将结果传回给我们的phantomjs上下文。或
2)告诉我们的phantomjs上下文,在加载所有资源时,运行测试。

#1对我来说比较简单。我通过以下方式实现了这一点:

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

**请参阅以下完整代码以获取我的console.log消息。

现在phantomjs显然有一个事件api内置,但它是无证的。我也成功地能够从他们的page.onResourceReceived和页面获取请求/响应消息。onResourceRequested - 意味着您可以在所有需要的模块加载时进行调试。为了传达我的测试结果,我只使用了console.log。

现在如果console.log消息从未运行,会发生什么情况?我能想到的解决这个唯一的办法是使用的setTimeout

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

应该这样做!

全码

目录结构

/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" 
    ); 
}); 

控制台

$ phantomjs tests/amd.js 
amd test successful