无法将模块功能传递给Page [英] Cannot pass module functions to 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:
-
序列化这些函数,并将它们作为字符串传递给评估回调,您可以在其中使用
new Function(string)
实例化它们并将它们绑定到util
对象.
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 theutil
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屋!