我有一个名为util
的模块,其中包含方法getMutedColor
和其他一些模块。 getMutedColor
依赖于同一模块中的另一个rand
。
page.includeJs('https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.10/d3.min.js', function() {
var util = require('./util');
var svg = page.evaluate(pageContext.pageExec, data, meta, util);
/** ... **/
}
我可以在此范围内调用util.getMutedColor()
,但在我的pageContext.pageExec
函数中,util.getMutedColor
不再存在。 util
参数仍然是一个对象,但我无法调用导出方法的任何:
TypeError:'undefined'不是函数(评估'util.getMutedColor()')
有没有办法将自包含模块传递给页面?
答案 0 :(得分:1)
不,这不太可能。如docs中所示:
注意: evaluate函数的参数和返回值必须是一个简单的原始对象。经验法则:如果它可以通过JSON序列化,那就没关系了。
传递给evaluate的函数必须是自包含的,并且传递的数据不能包含使用new
创建的函数或对象。那些被剥夺了。
这意味着您必须将util
对象完全复制到pageExec
函数中。
如果util
太大而无法复制,或者您使用util
的多个功能,则可以尝试不同的内容:
序列化函数并将它们作为字符串传递给evaluate回调函数,然后使用new Function(string)
对它们进行实例化,并将它们绑定到util
对象。
var funcNames = [];
for(var prop in util) {
if (util.hasOwnProperty(prop) && typeof util[prop] === "function") {
funcNames.push(prop);
util[prop] = util[prop].toString();
}
}
util.__funcNames = funcNames; // make it a property of util
page.evaluate(pageContext.pageExec, data, meta, util);
和pageContext.pageExec
内部:
util.__funcNames.forEach(function(funcName){
util[funcName] = new Function(util[funcName]);
});
只有一个包含所有内容的pageContext
函数,您可以使用switch case
一个参数,每次传递给evaluate
以选择其中的正确函数单pageContext
函数。
使用page.injectJs
注入utils。有必要通过检查window
是否存在以及类似的东西来命名工具:
var util = {...};
if (window) {
window.util = util
} else if(module) {
module.exports = util;
}
根据环境的不同,可能会有更好的脚本来执行此操作。