-
Notifications
You must be signed in to change notification settings - Fork 20.5k
Description
Problem
My use case is to use jquery to page scrape from within react-native code. I'm using jsdom-jscore to build a document from downloaded html, then trying to pass that document to jquery to be able to parse it.
My code looks like:
var jquery = require('jquery');
jsdom = require('jsdom-jscore');
var someHtmlIDownloaded = '<html><body><h1>Hello world</h1></body></html>';
jsdom.env(
someHtmlIDownloaded,
function (errors, window) {
var $ = jquery(window);
// do something with $ to parse/scrape html body.
}
);
The require('jquery') throws an error:
'document.createElement' is not defined
This occurs within sizzle, in the assert(fn) method.
Why it happens
react-native creates its own global document, but createElement is not supported on this document object. When jquery is loaded in this environment, because there is a global.document, it assumes document.createElement exists, and tries to attach itself to that document. The check that passes can be found here and looks like:
module.exports = global.document ?
factory( global, true ) :
function( w ) {
if ( !w.document ) {
throw new Error( "jQuery requires a window with a document" );
}
return factory( w );
};Temp fix
I was able to fix this locally by:
Building jquery from source using command:
grunt custom: -ajax,-ajax/jsonp,-ajax/load,-ajax/parseJSON,-ajax/parseXML,-ajax/script,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-css,-css/addGetHookIf,-css/curCSS,-css/defaultDisplay,-css/hiddenVisibleSelectors,-css/support,-css/swap,-css/var/cssExpand,-css/var/getStyles,-css/var/isHidden,-css/var/rmargin,-css/var/rnumnonpx,-effects,-effects/Tween,-effects/animatedSelector,-dimensions,-offset,-deprecated,-event,-event/alias,-event/support,-wrap,-deferred,-core/ready
Altering the built jquery code to never assume there is a global document:
module.exports = function( w ) {
if ( !w.document ) {
throw new Error( "jQuery requires a window with a document" );
}
return factory( w );
};And I require that custom build js in my code:
var jquery = require('dist/jquery.js');And it works!
Actual Solution?
What is the proper way to fix this? Should we check if the createElement method exists on the document before deciding to pass it to the factory?