开发者

What are the use cases of jsdom

开发者 https://www.devze.com 2023-03-08 06:53 出处:网络
After reading this Micro templates are dead article. I\'ve become curious: Whether Using the DOM on the server results in cleaner more maintainable code then templating.

After reading this Micro templates are dead article. I've become curious:

  1. Whether Using the DOM on the server results in cleaner more maintainable code then templating.
  2. Whether it's more efficient to use jsdom instead of a templating engine.
  3. How to factor jsdom into the View of a standard MVC s开发者_如何学Cetup.

And generally in what situations would it be better to use a server-side DOM abstraction, like jsdom rather then a templating engine, like EJS or jade.

The question is specific to node.js and other SSJS


Well, I actually needed JSDom for a small project I built over the weekend in node.js. So, on my server, I had to accept a URL to fetch, grab all of the HTML from the given URL, parse it, and display images to the user so that the user could select a thumbnail from that URL. (Kind of like when you drop a link into the Facebook input box) So, I used a module called Request which allows me to fetch HTML on the server-side. However, when that HTML reached my program, I had no way to traverse it like you do with client-side javascript. Because there was no actual DOM, I couldn't say document.getElementById('someId'). Therefore, JSDom came in handy by giving me a "makeshift" DOM that allowed me to traverse the returned HTML. Now, even though I was still on the server side, JSDOM created a window object very similar to the window object in the browser, and created a DOM out of the returned HTML. Now, even on the server, I was able to get all images by calling window.$('img'). I could target and parse the elements like normal. So, this is just one problem where JSDom turned out to be the solution, but it worked amazingly well. Hope this helps some!


  1. Its a nice abstraction that matches a client side engineers take on how the dom is built and modified. In that respect it is 'cleaner' because there is one mental model. Its also nice because we don't have to mix a kluge of disparate syntaxes from a templating language on top of otherwise clean declarative markup as is the case with even the 'stupidest' templating system, such as mustache.

  2. I would NOT say its more efficient to use jsdom for templating. Go take a gander at google wrt to 'memory leaks with jsdom' for instance. jsdom is rad, and is super useful for tasks like weekend projects for crawling sites, doing non-server related tasks, but I think its slow as shit from a high performance web server perspective.

  3. There are a billion ways to factor this. No method has emerged as a 'standard' way. One way that I've seen is to send down an empty 'template', i.e. a block of html that represents a model in some way, and then use that to bootstrap building your end view from a model. From that article, for example:


<li class="contact" id="contact-template">
    <span class="name"></span>
    <p class="title"></p>
</li>

This is the 'view' in the classic respect. In the typical web application, it might look something more like:

<li class="contact">
    <span class="name"><?= $name ?></span>
    <p class="title"><?= $title ?></p>
</li>

To use mvc, one sets up a controller that is vaguely aware of the semantics of the above view and the model it represents. This view is parsed into the/a DOM and accessed via your favorite selector engine. Each time the model this represents changes, you might use change events or callbacks to update the view. For instance:

Lets imagine that 'model' fires a 'change' event every time a property changes.

controller = new Controller({ 
    view: $('#contact-template').clone(), // Assume jquery or whatever
    model: aContact 
});

// Assume some initialization that sets the view up for the first time
// and appends it to the appropriate place. A la:
// this.view.find('.name').text(model.name);
// this.view.find('.title').text(model.title);
// this.view.appendTo('#contacts')

controller.on('model.name.change', function(name){
    this.view.find('.name').text(name);
});

These are what systems like Weld and Backbone.js do for you. They all have varying degrees of assumptions about where this work is taking place (server-side, client-side), what framework you're using (jquery, mootools, etc), and how your changes are being distributed (REST, socket.io, etc).

Edit

Some really useful things you can do with jsdom revolve around integration testing and spidering:

  • https://github.com/mikeal/spider - general purpose web spider that makes use of node's event based processing and gives you jsdom/jquery to help you easily access the DOM in a programatic way
  • https://github.com/assaf/zombie - headless browser testing using jsdom/jquery for integration tests
  • https://github.com/LearnBoost/tobi - similar headless browser testing

Personally, I'd like to see a project that took tobi's approach, but mapped it on top of something like https://github.com/LearnBoost/soda such that we can do cloud based selenium testing without selenese (since imo, it sucks).


A few come to mind:

  1. Sharing views/controllers between server and browser
  2. Data mining / crawling / processing
  3. Transformation for fragments of HTML used in AJAX/realtime stuff
  4. Absolute separation of logic and content by avoiding template tags

And to answer your questions:

  1. maybe. A lot of things affect code quality, but it's a step in the right direction
  2. nope, templating engines will always be faster, since they can pre-compile templates
  3. this probably warrants a new question?


point 2 of your question can be answered by this templating testcase:

go http://jsperf.com/dom-vs-innerhtml-based-templating/300

  • click the button "Run tests".

  • be patient, it compares weld vs. a lot of other template engines and gives you the current benchmarks ...

0

精彩评论

暂无评论...
验证码 换一张
取 消