I experiencing a problem below. All I know, it's because I added the "type": "module" in my package.json file. But do we have a way to convert the following code in module? I cannot find good resources so far.
const model = require(path.join(__dirname, file))( ReferenceError: require is not defined
My code:
const model = require(path.join(__dirname, file))(
sequelize,
Sequelize.DataTypes
);
db[model.name] = model;
You replicate this by using dynamic imports. Here's an example using your code:
import(path.join(__dirname, file))
.then(mod => {
const model = mod(sequelize, Sequelize.DataTypes);
db[model.name] = model;
});
Note that this is run asynchronously. If you're using a most recent version of Node.js that supports top level awaits or this code is being run inside an async function, then you can use this code insteadd:
const mod = await import(path.join(__dirname, file));
const model = mod(sequelize, Sequelize.DataTypes);
db[model.name] = model;
You are calling a function called require and you receive an error which tells you that it's undefined. This is a good indication that your require function is indeed undefined.
It is quite possible that you wanted to use RequireJS: https://requirejs.org/
You will need to make sure that RequireJS is already loaded and properly initialized by the time you try to call require.
If you are using NodeJS, you need to install RequireJS,like
npm install requirejs
If you are trying to use it in your browser, then you will need to link it via a script tag. Here's a tutorial for more information and practical examples: https://www.tutorialspoint.com/requirejs/index.htm
i am trying to make an api request in a node project using jquery, which I've istalled via npm install jquery but I'm getting the error TypeError: $.post is not a function even after requiring jquery like so: const $ = require('jquery') how can I get Jquery to work? I've seen a lot of examples of people using jquery but the process was not clear to me since I'm new to Node.js
Here is my code
const $ = require('jquery')
$.post("https://ticketsoko.nouveta.co.ke/api/index.php", {
TransactionType: "getEvents"
}, function (data, status) {
var info = JSON.parse(data);
for (var i = 0; i < info.data.length; i++) {
ticketSales[i] = info.data[i].totalTicketsSalesAmount;
events[i] = info.data[i].Events.events_name;
console.log(events[i]);
}
})
Here is step by step hard-to-go-wrong tutorial on how to obtain jQuery into your NodeJs project, then require it in your code and use in a manner similar to what you would do without NodeJs. If you haven't heard of modules and npm and are working with NodeJs, YESTERDAY was the time to have some working knowledge with them.
click here to see how to
On the other hand, WHY are you using jQ for this? You have entire world of modules to your disposal via npm, there are better modules, more fitted to do HTTP requests with like this one:
request module
You have to use a capital Q for jQuery
So it is const $ = require('jQuery') instead of require('jquery').
So, I am using Mocha/Chai for some testing and the item I am testing depends on jQuery. I am using jsdom to help with this. As you can see from code below I have no issue using jQuery from WITHIN the mocha test itself. What I can't seem to get situated is just calling the code that uses jQuery.
When running this in the browser, jQuery is included in a script tag before the ACE_GA module is included so jQuery fully works there.
In examining the code snippet below, there are two lines inside the done() function that have comments with them. The first line that has a comment, simply calls the code from the ACE_GA module, and it does not work. The second line that has a comment, is re-creating some of the code from inside the ACE_GA module (that I was trying to call in the first line), and it works just fine.
To be clear, the line that works just fine:
var productItems = jQuery("[data-" + ACE_GA.VALID_PRODUCT_FIELDS.prefix + "]");
Is simply copying a line from the module's method I'm trying to call, which is giving me problems:
var productItems = ACE_GA.HELPERS.validateOptions(ACE_GA.VALID_PRODUCT_FIELDS.prefix);
What do I need to do to be able to simply call a client library/module and have jQuery work with this, instead of copying/pasting code snippets from the module into the mocha tests?
var chai = require("chai");
var jsdom = require("jsdom");
var jQuery = require("jquery");
var fs = require("fs");
var ACE_GA = require("../main");
var bodyContent = fs.readFileSync(__dirname + "/../test/test.html", "utf8", "r");
global.document = jsdom.jsdom(bodyContent);
global.window = document.defaultView;
global.jQuery = jQuery;
describe("ACE_GA.HELPERS.validateOptions", function() {
it("should select all items with a data-attribute of 'ace-ga-{something}'", function(done) {
jsdom.env({
html: bodyContent,
src: jQuery,
scripts: "http://www.asite.com/path/to/default/js/jquery-1.11.3.min.js",
userAgent: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
done: function(err, window) {
console.log("err", err);
var jQuery = window.jQuery;
//var productItems = ACE_GA.HELPERS.validateOptions(ACE_GA.VALID_PRODUCT_FIELDS.prefix);
/** ^ that won't work and says jQuery requires a window with a document */
var productItems = jQuery("[data-" + ACE_GA.VALID_PRODUCT_FIELDS.prefix + "]");
/** ^ that works just fine and is copy/pasted from the non working method I'm trying to call above */
chai.expect(productItems.length).to.equal(4);
done();
}
});
});
});
For anyone's reference, here is the exact output of the failure error I'm getting
1) ACE_GA.HELPERS.validateOptions should select all items with a data-attribute of 'ace-ga-{something}':
Uncaught Error: jQuery requires a window with a document
at module.exports (C:\Path\To\Project\dev-files\node_modules\jquery\dist\jquery.js:29:12)
at Object.validateOptions (main.js:144:15)
at Object.done (test\gaecTest.js:89:39)
at process.nextTick (C:\Path\To\Project\dev-files\node_modules\jsdom\lib\jsdom.js:320:18)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
From what I can see, in the included module itself (ACE_GA), it's having a problem with jQuery working as I want it to from that context by itself (like defining then calling jQuery() inside mocha is okay but defining jQuery() in mocha and then calling it from inside ACE_GA module does not work the same).
As stated earlier, when running this in the browser, I'm able to define/include jQuery before including the ACE_GA module.
I'm attempting to do something similar here only without running it in the browser and instead running it from node with mocha.
The immediate reason you're running into trouble is that you're not initializing properly the jQuery instance that is loaded directly in node (by opposition to the one you load in the jsdom instance).
When you do require('jquery'), jQuery checks whether there's a document in the global scope. If so, it installs itself in the global scope. In a browser, the upshot is that it installs itself on window, as $ and jQuery. In Node.js, there is no document in the global scope by default. This is also the case in the code you show. When there is no document defined, what you get from require('jquery') is a factory from which you can build a jQuery instance. You have to pass a Window instance to that factory.
You could change your initial code to:
var chai = require("chai");
var jsdom = require("jsdom");
var makeJQ = require("jquery"); // Load the factory.
var fs = require("fs");
var bodyContent = fs.readFileSync(__dirname + "/../test/test.html", "utf8", "r");
global.document = jsdom.jsdom(bodyContent);
global.window = document.defaultView;
global.$ = global.jQuery = makeJQ(window); // Actually make a jQuery instance.
// Load this after, since it depends on jQuery being in the global space.
var ACE_GA = require("../main");
You should then ditch the second window you create with jsdom within the test and just use the one set up at the start of your test file. You can reuse it from test to test by cleaning the DOM tree between tests.
Right now with my ui tests using WebdriverIO, I have this in my configuration file:
var baseUrl = 'http://localhost:3000';
global.testParameters = {
baseUrl: baseUrl
};
This gives me access to my base url in the tests however it has to be fixed in the configuration file and I can't use the --baseUrl option when running wdio command. The reason for this is because from everything I have read, I don't see a way to have access to command line option values in my tests.
Is there a way to access the value of the command line options (specifically --baseUrl) in my actual test files?
You can use the yargs library. Do npm install yargs and in your config file add:
var argv = require('yargs').argv;
var baseUrl = argv.baseUrl;
You can then pass in the baseUrl with --baseUrl <your URL>
You can also make use of the WebdriverIO spec (wdio.conf.js) for configuration and create a separate conf.js file for each baseUrl you'd like to run your tests against
You can pass your base location through command line using -baseUrl= like below
wdio --baseUrl=http://[device IP]
You can pass any argument you need using the same way and can access it in wdio.config.js 'onprepare' event like below
wdio --type=XXX
Then in wdio config
onPrepare: function(config, capabilities) {
if (process.argv !== undefined && process.argv.length) {
process.argv.forEach(arg => {
if (arg.indexOf('--type=') !== -1) {
process.env.type = arg.replace('--type=', '');
}
});
}
},
before: function(capabilities, specs) {
global.type = process.env.type;
}
Now your type is available through-out your workspace as a global variable.
Is it possible to use jQuery selectors/DOM manipulation on the server-side using Node.js?
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);
});
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);
At the time of writing there also is the maintained Cheerio.
Fast, flexible, and lean implementation of core jQuery designed
specifically for the server.
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
Following links
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
request
iconv-lite
cheerio
async
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.
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);
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);
});
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** :
http://quaintous.com/2015/07/31/jqery-node-mystery/
http://www.hacksparrow.com/jquery-with-node-js.html
You have to get the window using the new JSDOM API.
const jsdom = require("jsdom");
const { window } = new jsdom.JSDOM(`...`);
var $ = require("jquery")(window);
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
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();
});
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;
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() {
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!
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.
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
I did it manually easy way without any additional packages or code.
npm i jquery
then I copy the jquery.min.js file from node_modules/jquery/dist directory to public/js
<script type='text/javascript' src='/js/jquery.min.js'></script>
<script>
$(document).ready(function() { console.log( "ready!" ); });
</script>
And it will work. TEST IT
Note copy/pasting the file is not the ideal thing, you could enable the file as a static file by enabling it as a static so expressJS could read it. But it is easier for me to just copy it to the static public directory.
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.
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.
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...
An alternative is to use Underscore.js. It should provide what you might have wanted server-side from JQuery.