不能将模块函数传递给页[英] Cannot pass module functions to Page

问题描述

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

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

推荐答案

不,这不可能.如 docs 中所示:

<块引用>

注意:评估函数的参数和返回值必须是简单的原始对象.经验法则:如果可以通过 JSON 序列化就可以了.

您传递给评估的函数必须是自包含的,并且您传递的数据不能包含使用 new 创建的函数或对象.那些被剥离了.

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

如果util太大而无法复制,或者如果你使用util的多个功能,你可以尝试不同的东西:

  1. 序列化函数并将它们作为字符串传递给评估回调,您将在其中使用 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 函数,您可以使用带有每次传递给 evaluate 的参数的 switch case 来选择单个 pageContext 函数内的正确函数.

  3. 使用 page.injectJs 注入实用程序.有必要通过检查 window 是否存在类似的东西来命名 utils:

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

    可能有更好的脚本来执行此操作,具体取决于环境.

本文地址:https://www.itbaoku.cn/post/1739917.html