无法将模块功能传递给Page [英] Cannot pass module functions to Page

查看:96
本文介绍了无法将模块功能传递给Page的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为util的模块,其中包含方法getMutedColor和其他一些方法. getMutedColor依赖于同一模块中的另一个rand.

I have a module called util with the methods getMutedColor and some others. getMutedColor relies on another called rand in the same module.

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参数仍然是一个对象,但是我不能调用导出方法的 any :

I can call util.getMutedColor() just fine within this scope but in my pageContext.pageExec function, util.getMutedColor no longer exists. The util parameter is still an object, but I cannot call any of the exported methods:

TypeError:未定义"不是一个函数(正在评估"util.getMutedColor()")

TypeError: 'undefined' is not a function (evaluating 'util.getMutedColor()')

是否可以将自包含模块传递给页面?

Is there a way to pass a self-contained module to a page?

推荐答案

不,这实际上是不可能的.如文档:

No, it is not really possible. As seen in the docs:

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

Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.

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

The function that you pass to evaluate must be self-contained and the data that you pass cannot contain functions or objects that are created with new. Those are stripped.

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

This means that you must copy the util object completely into the pageExec function.

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

If util is too big to copy or if you use multiple functions of util, you can try different things:

  1. 序列化这些函数,并将它们作为字符串传递给评估回调,您可以在其中使用new Function(string)实例化它们并将它们绑定到util对象.

  1. Serialize the functions and pass them as strings to the evaluate callback where you would instantiate them with new Function(string) and bind them to the util object.

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函数内部选择​​合适的函数.

  • Have only a single pageContext function which contains everything and you can use a switch case with a parameter that is passed every time to evaluate to select the proper function inside of the single pageContext function.

    使用 page.injectJs 注入utils.必须通过检查window是否存在类似的东西来为utils命名空间:

    Use page.injectJs to inject the utils. It would be necessary to namespace the utils in by checking if window is present with something like that:

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

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

    Probably there are better scripts out there to do this depending on the environment.

    这篇关于无法将模块功能传递给Page的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆