Can I use jQuery with Node.js?

JavascriptJquerynode.js

Javascript Problem Overview


Is it possible to use jQuery selectors/DOM manipulation on the server-side using Node.js?

Javascript Solutions


Solution 1 - Javascript

Update (27-Jun-18): It looks like there was a major update to jsdom that causes the original answer to no longer work. I found this answer that explains how to use jsdom now. I've copied the relevant code below.

var jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = new JSDOM();
const { document } = (new JSDOM('')).window;
global.document = document;

var $ = jQuery = require('jquery')(window);

Note: The original answer fails to mention that it you will need to install jsdom as well using npm install jsdom

Update (late 2013): The official jQuery team finally took over the management of the jquery package on npm:

npm install jquery

Then:

require("jsdom").env("", function (err, window) {
    if (err) {
        console.error(err);
        return;
    }
    var $ = require("jquery")(window);
});

Solution 2 - Javascript

Yes you can, using a library I created called nodeQuery

var Express = require('express')
    , dnode = require('dnode')
    , nQuery = require('nodeQuery')
    , express = Express.createServer();
    
var app = function ($) {
    $.on('ready', function () {
        // do some stuff to the dom in real-time
        $('body').append('Hello World');
        $('body').append('<input type="text" />');
        $('input').live('click', function () {
            console.log('input clicked');
            // ...
        });
    });
};

nQuery
    .use(app);

express
    .use(nQuery.middleware)
    .use(Express.static(__dirname + '/public'))
    .listen(3000);

dnode(nQuery.middleware).listen(express);

Solution 3 - Javascript

At the time of writing there also is the maintained Cheerio.

> Fast, flexible, and lean implementation of core jQuery designed > specifically for the server.

Solution 4 - Javascript

A simple crawler using Cheerio

This is my formula to make a simple crawler in Node.js. It is the main reason for wanting to do DOM manipulation on the server side and probably it's the reason why you got here.

First, use request to download the page to be parsed. When the download is complete, handle it to cheerio and begin DOM manipulation just like using jQuery.

Working example:

var
    request = require('request'),
    cheerio = require('cheerio');

function parse(url) {
    request(url, function (error, response, body) {
        var
            $ = cheerio.load(body);

        $('.question-summary .question-hyperlink').each(function () {
            console.info($(this).text());
        });
    })
}

parse('http://stackoverflow.com/');

This example will print to the console all top questions showing on SO home page. This is why I love Node.js and its community. It couldn't get easier than that :-)

Install dependencies:

> npm install request cheerio

And run (assuming the script above is in file crawler.js):

> node crawler.js


Encoding

Some pages will have non-english content in a certain encoding and you will need to decode it to UTF-8. For instance, a page in brazilian portuguese (or any other language of latin origin) will likely be encoded in ISO-8859-1 (a.k.a. "latin1"). When decoding is needed, I tell request not to interpret the content in any way and instead use iconv-lite to do the job.

Working example:

var
    request = require('request'),
    iconv = require('iconv-lite'),
    cheerio = require('cheerio');

var
    PAGE_ENCODING = 'utf-8'; // change to match page encoding

function parse(url) {
    request({
        url: url,
        encoding: null  // do not interpret content yet
    }, function (error, response, body) {
        var
            $ = cheerio.load(iconv.decode(body, PAGE_ENCODING));

        $('.question-summary .question-hyperlink').each(function () {
            console.info($(this).text());
        });
    })
}

parse('http://stackoverflow.com/');

Before running, install dependencies:

> npm install request iconv-lite cheerio

And then finally:

> node crawler.js


The next step would be to follow links. Say you want to list all posters from each top question on SO. You have to first list all top questions (example above) and then enter each link, parsing each question's page to get the list of involved users.

When you start following links, a callback hell can begin. To avoid that, you should use some kind of promises, futures or whatever. I always keep async in my toolbelt. So, here is a full example of a crawler using async:

var
    url = require('url'),
    request = require('request'),
    async = require('async'),
    cheerio = require('cheerio');

var
    baseUrl = 'http://stackoverflow.com/';

// Gets a page and returns a callback with a $ object
function getPage(url, parseFn) {
    request({
        url: url
    }, function (error, response, body) {
        parseFn(cheerio.load(body))
    });
}

getPage(baseUrl, function ($) {
    var
        questions;

    // Get list of questions
    questions = $('.question-summary .question-hyperlink').map(function () {
        return {
            title: $(this).text(),
            url: url.resolve(baseUrl, $(this).attr('href'))
        };
    }).get().slice(0, 5); // limit to the top 5 questions

    // For each question
    async.map(questions, function (question, questionDone) {

        getPage(question.url, function ($$) {

            // Get list of users
            question.users = $$('.post-signature .user-details a').map(function () {
                return $$(this).text();
            }).get();

            questionDone(null, question);
        });

    }, function (err, questionsWithPosters) {

        // This function is called by async when all questions have been parsed

        questionsWithPosters.forEach(function (question) {

            // Prints each question along with its user list
            console.info(question.title);
            question.users.forEach(function (user) {
                console.info('\t%s', user);
            });
        });
    });
});

Before running:

> npm install request async cheerio

Run a test:

> node crawler.js

Sample output:

Is it possible to pause a Docker image build?
	conradk
	Thomasleveil
PHP Image Crop Issue
	Elyor
	Houston Molinar
Add two object in rails
	user1670773
	Makoto
	max
Asymmetric encryption discrepancy - Android vs Java
	Cookie Monster
	Wand Maker
Objective-C: Adding 10 seconds to timer in SpriteKit
	Christian K Rider

And that's the basic you should know to start making your own crawlers :-)


Libraries used

Solution 5 - Javascript

in 2016 things are way easier. install jquery to node.js with your console:

npm install jquery

bind it to the variable $ (for example - i am used to it) in your node.js code:

var $ = require("jquery");

do stuff:

$.ajax({
    url: 'gimme_json.php',
    dataType: 'json',
    method: 'GET',
    data: { "now" : true }
});

also works for gulp as it is based on node.js.

Solution 6 - Javascript

I believe the answer to this is now yes.
https://github.com/tmpvar/jsdom

var navigator = { userAgent: "node-js" };  
var jQuery = require("./node-jquery").jQueryInit(window, navigator);

Solution 7 - Javascript

npm install jquery --save #note ALL LOWERCASE

npm install jsdom --save

const jsdom = require("jsdom");
const dom = new jsdom.JSDOM(`<!DOCTYPE html>`);
var $ = require("jquery")(dom.window);


$.getJSON('https://api.github.com/users/nhambayi',function(data) {
  console.log(data);
});

Solution 8 - Javascript

jQuery module can be installed using:

npm install jquery

Example:

var $ = require('jquery');
var http = require('http');

var options = {
    host: 'jquery.com',
    port: 80,
    path: '/'
};

var html = '';
http.get(options, function(res) {
res.on('data', function(data) {
    // collect the data chunks to the variable named "html"
    html += data;
}).on('end', function() {
    // the whole of webpage data has been collected. parsing time!
    var title = $(html).find('title').text();
    console.log(title);
 });
});

References of jQuery in Node.js** :

Solution 9 - Javascript

You have to get the window using the new JSDOM API.

const jsdom = require("jsdom");
const { window } = new jsdom.JSDOM(`...`);
var $ = require("jquery")(window);

Solution 10 - Javascript

First of all install it

npm install jquery -S

After installing it, you can use it as below

import $ from 'jquery';
window.jQuery = window.$ = $;
$(selector).hide();

You can check out a full tutorial that I wrote here: https://medium.com/fbdevclagos/how-to-use-jquery-on-node-df731bd6abc7

Solution 11 - Javascript

WARNING

This solution, as mentioned by Golo Roden is not correct. It is just a quick fix to help people to have their actual jQuery code running using a Node app structure, but it's not Node philosophy because the jQuery is still running on the client side instead of on the server side. I'm sorry for giving a wrong answer.


You can also render Jade with node and put your jQuery code inside. Here is the code of the jade file:

!!! 5
html(lang="en")
  head
    title Holamundo!
    script(type='text/javascript', src='http://code.jquery.com/jquery-1.9.1.js')
  body
    h1#headTitle Hello, World
    p#content This is an example of Jade.
    script
      $('#headTitle').click(function() {
        $(this).hide();
      });
      $('#content').click(function() {
        $(this).hide();
      });

Solution 12 - Javascript

My working code is:

npm install jquery

and then:

global.jQuery 	= require('jquery');
global.$ 		= global.jQuery;

or if the window is present, then:

typeof window !== "undefined" ? window : this;
window.jQuery 	= require('jquery');
window.$ 		= window.jQuery;

Solution 13 - Javascript

None of these solutions has helped me in my Electron App.

My solution (workaround):

npm install jquery

In your index.js file:

var jQuery = $ = require('jquery');

In your .js files write yours jQuery functions in this way:

jQuery(document).ready(function() {

Solution 14 - Javascript

The module jsdom is a great tool. But if you want to evaluate entire pages and do some funky stuff on them server side I suggest running them in their own context:

vm.runInContext

So things like require / CommonJS on site will not blow your Node process itself.

You can find documentation here. Cheers!

Solution 15 - Javascript

As of jsdom v10, .env() function is deprecated. I did it like below after trying a lot of things to require jquery:

var jsdom = require('jsdom');
const { JSDOM } = jsdom;
const { window } = new JSDOM();
const { document } = (new JSDOM('')).window;
global.document = document;

var $ = jQuery = require('jquery')(window);

Hope this helps you or anyone who has been facing these types of issues.

Solution 16 - Javascript

Yes, jQuery can be used with Node.js.

Steps to include jQuery in node project:-

npm i jquery --save Include jquery in codes

import jQuery from 'jquery';

const $ = jQuery;

I do use jquery in node.js projects all the time specifically in the chrome extension's project.

e.g. https://github.com/fxnoob/gesture-control-chrome-extension/blob/master/src/default_plugins/tab.js

Solution 17 - Javascript

No. It's going to be quite a big effort to port a browser environment to node.

Another approach, that I'm currently investigating for unit testing, is to create "Mock" version of jQuery that provides callbacks whenever a selector is called.

This way you could unit test your jQuery plugins without actually having a DOM. You'll still have to test in real browsers to see if your code works in the wild, but if you discover browser specific issues, you can easily "mock" those in your unit tests as well.

I'll push something to github.com/felixge once it's ready to show.

Solution 18 - Javascript

You can use Electron, it allows hybrid browserjs and nodejs.

Before, I tried to use canvas2d in nodejs, but finally I gave up. It's not supported by nodejs default, and too hard to install it (many many ... dependeces). Until I use Electron, I can easily use all my previous browserjs code, even WebGL, and pass the result value(eg. result base64 image data) to nodejs code.

Solution 19 - Javascript

Not that I know of. The DOM is a client side thing (jQuery doesn't parse the HTML, but the DOM).

Here are some current Node.js projects:

https://github.com/ry/node/wiki (https://github.com/nodejs/node)

And SimonW's djangode is pretty damn cool...

Solution 20 - Javascript

An alternative is to use Underscore.js. It should provide what you might have wanted server-side from JQuery.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohnView Question on Stackoverflow
Solution 1 - JavascriptPhilippe RathéView Answer on Stackoverflow
Solution 2 - JavascriptThomas BlobaumView Answer on Stackoverflow
Solution 3 - JavascriptAlfredView Answer on Stackoverflow
Solution 4 - JavascriptLucio PaivaView Answer on Stackoverflow
Solution 5 - Javascriptlow_rentsView Answer on Stackoverflow
Solution 6 - JavascriptrdzahView Answer on Stackoverflow
Solution 7 - JavascriptNoahView Answer on Stackoverflow
Solution 8 - JavascriptSUNDARRAJAN KView Answer on Stackoverflow
Solution 9 - JavascriptwebcpuView Answer on Stackoverflow
Solution 10 - JavascriptOyetoke TobiView Answer on Stackoverflow
Solution 11 - JavascriptTimbergusView Answer on Stackoverflow
Solution 12 - JavascriptRomanView Answer on Stackoverflow
Solution 13 - JavascriptElio OsésView Answer on Stackoverflow
Solution 14 - JavascriptJakub ObozaView Answer on Stackoverflow
Solution 15 - JavascriptPlabon DuttaView Answer on Stackoverflow
Solution 16 - JavascriptfxnoobView Answer on Stackoverflow
Solution 17 - JavascriptFelix GeisendörferView Answer on Stackoverflow
Solution 18 - JavascriptgonnavisView Answer on Stackoverflow
Solution 19 - JavascriptNosrednaView Answer on Stackoverflow
Solution 20 - JavascriptJohn WrightView Answer on Stackoverflow