Node.js Support
gtrak opened this issue · 16 comments
Not sure if this is a good idea...
I'm trying to get a nodejs test-runner working for a node-webkit project, however hickory relies on DOM APIs not present in node.js (works fine in the real app).
Alternatively, I can try to find a way to use node-webkit as a test runner.
Actual Error:
return Node[[cljs.core.str(a), cljs.core.str("_NODE")].join("")];
^
ReferenceError: Node is not defined
at hickory.core.node_type (/home/gary/my-project/target/testing.js:31175:10)
at Object.<anonymous> (/home/gary/my-project/target/testing.js:31177:49)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:902:3
Hey, sorry that's not working for you. I don't really do JS, and I don't do CLJS at all, so I basically have no idea what you said. But I believe the reason for depending on DOM APIs is discussed starting here: #7 (comment)
Anything JS-related, I usually defer to @jeluard. Maybe he'll chime in.
I only use ClojureScript in browsers and I don't have nodejs experience.
Indeed the current ClojureScript support relies on the DOM API. Even if there was a good nodejs/browser parsing library (to my knowledge this is not the case?) it would probably still be better to rely on the browser native API for consistency and performance.
I am not sure what is the recommended practice to support both browsers and nodejs with different implementations. In this case it would probably be simple to detect the lack of DOM API and switch to a different implementation at runtime. But you would need to have a nodejs implementation then.
I might investigate (when I have time) if we can re-use something from React, since I think I might be able to run this in a node context.
Some cursory searching about react people trying to do the same thing reveals this is the thing to use: https://github.com/tmpvar/jsdom
Putting it here for reference.
Indeed jsdom looks like you can actually use extend-type
, when you do a deep require (eg. require("jsdom/lib/jsdom/level1/core").dom.level1.NodeList
)
This seems to work thanks to a well structured code in both hickore.core
and jsdom
. I can now use the same parser on both platforms that I target with the same source: node.js (npm library code) and browser (part of an app).
Looks like this is a big problem for those of us that want to use Nashorn, as jsdom doesn't work there. Still investigating...
@sritchie I ditched jsdom
because it was too slow, and ended up writing small wrapper around node-libxml
. I found that hickory only uses a few DOM methods, so as long as you can provide a lightweight wrapper around javax.xml
objects, all should work as expected.
Hm, it looked like the big monster that was missing was the DOMParser, Node and NodeList elements. I was considering just switching over to Sablono with its hiccup style of React components. Would you be willing to share the code for your minimal wrapping? I'd love to help bundle it up for others to use, if you're interested.
—
Sent from Mailbox
On Wed, Nov 5, 2014 at 3:02 AM, Dušan Maliarik notifications@github.com
wrote:
@sritchie I ditched
jsdom
because it was too slow, and ended up writing small wrapper aroundnode-libxml
. I found that hickory only uses a few DOM methods, so as long as you can provide a lightweight wrapper aroundjavax.xml
objects, all should work as expected.Reply to this email directly or view it on GitHub:
#17 (comment)
Bump. @davidsantiago @jeluard
Hey guys, I'm working on a server side rendered app using Reagent, CLJS, and Node. https://github.com/savaki/reagent-nodejs
Node was blowing up and I realized that Hickory relies on the DOM, which isn't available in Node. I'm getting the exact exception as @gtrak
Anyone been able to solve this issue? I see that @skrat made a pull request but hasn't been merged.
I understand @skrat is using libxml-dom as a polyfill to the browser DOM API. I might be wrong so take that with a grain of salt.
This sounds like the best approach and doesn't require changes to hickory.
Thanks, libxml-dom seems to be helping: loading hickory in Node actually works now.
But once I start using parse-fragment
an exception TypeError: Cannot call method 'createHTMLDocument' of undefined
hickory.core.parse_dom_with_write = (function parse_dom_with_write(s) {
var doc = document.implementation.createHTMLDocument("");
var doctype_el = (doc["doctype"]);
if(cljs.core.truth_(hickory.core.extract_doctype.call(null,s))){
} else {
hickory.core.remove_el.call(null,doctype_el);
}
Any suggestions @skrat ?
@hzhu Because there's no implementation
property on document
object. Feel free to fork libxml-dom
and send in a PR. I might do this myself but can't give you any estimate.
Just for the record, hickory does not work either in a React Native environment (using re-natal on an android device)... I've got the same error as above (Node is not defined
).