【问题标题】:Getting webfontloader to work with node.js and jsdom让 webfontloader 与 node.js 和 jsdom 一起工作
【发布时间】:2015-12-28 18:43:47
【问题描述】:

我有webfontloader 在浏览器上下文中运行良好。现在我想看看我是否可以让它在 node.js + jsdom 上下文中工作,特别是因为 webfontloader 可以作为 npm module 使用。

我已经让 node + jsdom 工作以提供合理的输出,所以我知道这部分正在工作。但是当我尝试集成 webfontloader 来启用网络字体时,我就陷入了困境。

基本上,我使用的是 README 中记录的 webfontloader 模块,即:

var WebFont = require('webfontloader');

WebFont.load({
  google: {
    families: ['Droid Sans', 'Droid Serif']
  }
});

但尽我所能,我得到以下错误:

ReferenceError: 未定义窗口

我可以从 jsdom 获得一个window 对象:

            // Get the document and window
            var doc = jsdom.jsdom('<!doctype html><html><body><div id="container"></div></body></html>'),
                win = doc.defaultView;

但是我如何将 win 传递给 webfontloader 以在该上下文中用作 window

也许我在表达我的天真,并要求不可能的事情。

【问题讨论】:

  • 你试过在 jsdom.env(....) 上下文中加载 WebFont 吗?
  • 你试过下面的答案了吗?
  • 还没有。抱歉,还没有机会。不过,它确实看起来完全合理,我真的很期待试一试。感谢您的详细回答。

标签: javascript node.js webfont-loader


【解决方案1】:

除非您有充分的理由不这样做,否则我建议您将webfontloaderjsdom.envjsdom.jsdom 一起加载到jsdom.jsdom,或者使用托管在Google 托管库上的version 或托管它自己。使用jsdom.env 看起来像这样:

var jsdom = require("jsdom");

jsdom.env( 
    '<!doctype html><html><body></body></html>', 
    ['https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js'], 
    function(err, win) {

        var WebFont = win.WebFont;

        WebFont.load({
            google: {
                families: ['Droid Sans', 'Droid Serif']
            }
        });
    }
);

如果你真的需要 nodejs 上下文中的 webfontloader,据我所知 webfontloader 不能作为参数传递一个窗口,但是你可以通过向库中添加几行来轻松地绕过这个。

  1. 运行npm install webfontloader
  2. 打开“node_modules/webfontloader/webfontloader.js”
  3. 将“webfontloader.js”的内容包含在以window 对象作为参数的module.exports 函数中。

该文件可能与此类似(未粘贴整个 webfontloader 库源):

module.exports = function(window){

    var exportsBackup = module.exports;

    /* Web Font Loader v1.6.16 - (c) Adobe Systems, Google. License: Apache 2.0 */
    (function(){function aa(a,b,c){r ...

    var loaderObject = module.exports;
    module.exports   = exportsBackup;

    return loaderObject;
};

我确实将 module.exports 临时存储在一个变量中,以确保我们可以多次以这种方式请求模块,因为 webfontloader 库将替换 module.exports 对象。

您可以像这样要求库而不会出现任何错误:

var jsdom = require("jsdom");

jsdom.env( "https://nodejs.org/", [], function(err, win) {

    var WebFont = require('webfontloader')(win);

    WebFont.load({
        google: {
            families: ['Droid Sans', 'Droid Serif']
        }
    });

});

【讨论】:

  • 使用编辑webfontloader.js 以启用window 作为参数传递的巧妙建议,我现在可以在没有引用错误的情况下实际调用WebFont.load() 函数。但现在我遇到了与这里描述的完全相同的问题:stackoverflow.com/q/34163339/4070848——换句话说,尝试加载 webfont 总是到达inactive 分支,并且永远不会成功加载。您能否使用jsdom 成功加载网络字体?我尝试将自定义 userAgent 传递给 jsdom 以尝试欺骗 webfontloader,但无济于事。
  • 好的,我去看看。但首先,新年快乐!
  • 新年快乐(快到了!)...有些是在新的一年,有些则不是!
  • 在 github 上有几个关于这个的未解决的问题,好像 jsdom 中不支持 font-face,所以不确定你是否可以轻松解决这个问题,即使你改变了 UA。跨度>
  • 好的,看来我的计划被挫败了(无法让 webfonts 与 phantomjs 或 jsdom 一起使用):-( 感谢您对此进行调查。您有 github 链接吗?如果这是 jsdom 的一个基本问题,我仍然会将您的答案标记为正确(并奖励赏金!),因为它似乎是正确的(就实际让 webfontloader 与 jsdom 一起玩而言,即使 jsdom 不想回放!)
猜你喜欢
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 2017-10-14
  • 2014-01-12
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
相关资源
最近更新 更多