无法将模块功能传递给Page

时间:2014-08-11 23:13:19

标签: phantomjs

我有一个名为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()')

有没有办法将自包含模块传递给页面?

1 个答案:

答案 0 :(得分:1)

不,这不太可能。如docs中所示:

  

注意: evaluate函数的参数和返回值必须是一个简单的原始对象。经验法则:如果它可以通过JSON序列化,那就没关系了。

传递给evaluate的函数必须是自包含的,并且传递的数据不能包含使用new创建的函数或对象。那些被剥夺了。

这意味着您必须将util对象完全复制到pageExec函数中。

如果util太大而无法复制,或者您使用util的多个功能,则可以尝试不同的内容:

  1. 序列化函数并将它们作为字符串传递给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]);
    });
    
  2. 只有一个包含所有内容的pageContext函数,您可以使用switch case一个参数,每次传递给evaluate以选择其中的正确函数单pageContext函数。

  3. 使用page.injectJs注入utils。有必要通过检查window是否存在以及类似的东西来命名工具:

    var util = {...};
    if (window) {
        window.util = util
    } else if(module) {
        module.exports = util;
    }
    

    根据环境的不同,可能会有更好的脚本来执行此操作。

相关问题