Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting webfontloader to work with node.js and jsdom

I have webfontloader working nicely within a browser context. Now I'm trying to see whether I can get it working in a node.js + jsdom context, particularly since webfontloader is available as an npm module.

I have got node + jsdom working to provide sensible output, so I know that part is working. But when I try to integrate webfontloader, to enable web fonts, I come unstuck.

Basically I am using webfontloader module as documented in the README, which is:

var WebFont = require('webfontloader');

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

But try as I may, I get the following error:

ReferenceError: window is not defined

I can get a window object from jsdom:

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

But how do I pass win in to webfontloader for use as window in that context?

Maybe I'm showing my naivety, and asking the impossible.

like image 770
drmrbrewer Avatar asked Dec 22 '15 22:12

drmrbrewer


1 Answers

Unless you have a good reason not to do so, i'd rather recommend you loading webfontloader into jsdom with jsdom.env or jsdom.jsdom, either using the version hosted on Google Hosted Libraries or hosting it yourself. Using jsdom.env it would look like this:

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']
            }
        });
    }
);

If you really need to require webfontloader from a nodejs context, as far as i can tell webfontloader can't be passed a window as a parameter, but you can circumvent this easily by adding a couple of lines to the library.

  1. Run npm install webfontloader
  2. Open "node_modules/webfontloader/webfontloader.js"
  3. Enclose the content of "webfontloader.js" in a module.exports function that takes a window object as a parameter.

The file could look similar to this (not pasting the whole webfontloader library source):

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;
};

I do temporarily store module.exports in a variable to ensure we can require the module in this fashion multiple times, since the webfontloader library will replace the module.exports object.

You can require the library like this without any errors:

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']
        }
    });

});
like image 128
cviejo Avatar answered Oct 08 '22 11:10

cviejo