代码如下:
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 :(得分:3)
我只是挣扎了一段时间。我的解决方案并不干净,但它确实有效,而且由于来自phantomjs的未完成的api文档,我很满意。
您需要三个文件。一个是你的amd phantomjs测试文件,我称之为“amd.js”。第二个是你要加载的html页面,我将其命名为“amd.html”。最后我称之为“amdTestModule.js”的浏览器测试。
在amd.html中,按正常情况声明脚本标记:
<script data-main="amdTestModule.js" src="require.js"></script>
在你的phantomjs测试文件中,这就是hacky的地方。创建页面,然后加载'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和page.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
答案 1 :(得分:1)
你误解了网页.injectJs()
用于将脚本注入要加载的页面,而不是注入到phantomjs运行时环境中。
因此使用.injectJs()会使requirejs加载到您的页面中,而不是加载到phantomjs.exe中。
也就是说,phantomjs的运行时环境具有commonjs的近似性。默认情况下,RequireJs不会在那里运行。如果您觉得特别(非常)有动力,您可以尝试移植为nodejs制作的require-shim,但它不能开箱即用,并且需要对运行时有一个非常深刻的理解。有关详细信息:http://requirejs.org/docs/node.html
更好的主意: 可能你应该确保你有你希望运行的javascript的commonjs版本。我个人用打字稿写我的代码所以我可以为commonjs或amd构建。我使用commonjs代替phantomjs代码,amd代表nodejs和浏览器。