Please be gentle with me. I'm new to async coding and have been thrown headfirst into an intensive project using node to develop and API server. I'm loving it but some things aren't coming naturally.
Our project is built using express js. We have a file, server.js where we instantiate an express server which in turn instantiates our router and so on. I need to integration test this now (partially) complete server. Normally what I do is from the command line run '%node server.js' and then using either python requests or curl make requests and check the responses.
Now I've been tasked with writing a unit and integration test suite so that we can automate our testing going forward. I've been using mocha and now am trying to use supertest for the integration testing. The problem is that supertest expects a server object which it then applies tests to however our file that builds our server object doesn't return anything. I don't want to modify that file so I am stumped as to how to access the server object to use for testing.
My server file looks (in part) like this:
var express = require('express')
var app = express();
// Express Configuration
app.use(express.favicon()); //handles favicon request, which keeps it out of the log when using a browser :)
app.use(express.bodyParser()); //slurps up the body in chunks the node.js way :)
// ...and so on
and my mocha test file looks like this
var request = require('supertest')
, app = require('../server.js')
, assert = require("assert");
describe('POST /', function(){
it('should fail bad img_uri', function(done){
request(app)
.post('/')
.send({
'img_uri' : 'foobar'
})
.expect(500)
.end(function(err, res){
console.dir(err)
console.dir(res)
done();
})
})
})
when I run this test I get a complaint about the app object not having a method named address. My question is, is there a way I can require/call the server.js file so that the app object will be in scope? Or am I going about this wrong. I also played around a little bit with using http.js to make calls directly to the server but didn't have luck that way either. Thanks!
You need to export the app object in server.js:
var app = express();
module.exports = app;
...
Related
I am new to js and I am trying to develop a simple node.js-mysql app. No matter what I do I can't get the standard
var express = require("express");
statement to work.
I have installed node.js and express correctly, express is in package.json. I have a local server running. But this simple line will not work.
On the node.js side at Windows command line I have no error but when I go to localhost:3000 on the browser, I get
'Uncaught Error: Module name "express" has not been loaded yet for
context: _. Use require([])' error at js console.
I tried changing it to
require(['express']`, function (express) {}
as suggested at node.js web site but then at the Windows command terminal I get a different error saying like
'expecting a string but received an array....'.
I have tried import instead of require and I have tried every suggestion that I could find on the Internet. I have been blowing my brains for weeks to get this to work with no success. I am so frustrated that I am seriously thinking about giving up all together. If someone can help I will be forever greatfull to him/her.
My main js code is as follows:
var port = 3000;
// Import or load node.js dependency modules.
var express = require("express");
var app = express();
var path = require("path");
var bodyParser = require("body-parser");
app.use(express.urlencoded({ extended: true })); // to support URL-encoded bodies.
app.listen(port, () => {
console.log(`server is running at http://127.0.0.1:8887`);
});
app.get('/', function(req, res){
res.sendFile("D:/Behran's files/Web projects/havuzlusite/index.html");
});
Require.JS is for loading AMD modules (and is, honestly, obsolete in today's JS landscape).
Node.js modules are either ECMAScript modules (which use import and export) or CommonJS modules (which use require and module.exports).
Even though both AMD and CommonJS modules use a function named require they are not compatible.
There are methods you can use to run ES modules and CommonJS modules in the browser however they can't replace APIs that are provided by runtimes.
Express.js needs to be able to listen for incoming HTTP requests. Browsers do not provide any mechanism to make that possible. Node.js does.
If you want to run Express.js you have to run it using Node.js and not a browser.
Express.js creates an HTTP server. A browser can make requests to it (e.g. if you type http://127.0.0.1:3000 into the address bar.
(Your code says server is running at http://127.0.0.1:8887 but the port constant is set to 3000).
All your Express.js code must run through Node.js.
You can't send a copy of that code to the browser and run it there too.
My goal is this: JS but server-side. My solution, the obvious, node.js. I've used node.js quiet a bit. Mainly for an application, not a web server. The only reason I need to do server-side JS is that I need to use a library that connects to the Discord API. So I have a little test .js file with my node.js in it. It just prints text if it works. Basic. What I need it to do is whenever someone goes to https://example.com/something, it runs the node.js script and if the script ends up with printing "hello", then https://example.com/something will say "hello".
I've done some research on this, I've found ways to deploy a node.js app, which I know how to do. I can't really find anything that I'm looking for though.
You can use express to run a webserver on nodejs
Install express by running "npm install express" in your project folder through command prompt
Create a app.js file with the following code
var express = require('express'); // load the express library
var app = express(); // create an instance of express
var child_process = require('child_process'); //load the child_process module
app.get("/something", function(req, res) { // Setup a router which listens to the site http://localhost/something
child_process.fork("./yourCodeFile.js"); // Launch your code file
});
app.listen(80);
Run node app.js to listen to web connections
Then you put your code into the yourCodeFile.js which has to be be in the same folder as the app.js file, even better you could just write all your code in the app.js code as long as you keep it inside the function inside app.get
You should take a look at cloud-based lambda functions and platforms like AWS Lambda, which run a script in response to an HTTP request. They are relatively new and the architecture used to support this is being called "serverless", which is a simple term, albeit a bit of a misnomer. There are various tools out there to help you build these systems, such as the similarly named Serverless framework, though you can typically still use more traditional server frameworks that you are probably more comfortable with. Either way, you are not responsible for managing any server, including starting it or stopping it.
In terms of constructing a response that you are happy with, you can of course respond with any arbitrary string you want. See the AWS example of a Node.js handler.
exports.myHandler = function(event, context, callback) {
callback(null, "Hello, world!");
}
Lambda functions can also return binary data and work well with static storage systems like Amazon S3. For example, the function can be run in response to the creation of static assets.
Your code should look like this:
const http = require('http');
const url = require('url');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
const pathName =url.parse(req.url).pathname;
if (pathName == '/something') {
res.end('Hello World\n');
} else {
res.end('Please visit /something \n');
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
You should run your file with node youfile.js And when you do curl http://127.0.0.1:3000 you will see
Please visit /something
But when you do curl http://127.0.0.1:3000/something you will see
Hello World
I am having trouble building a node/js app with various frameworks. I keep getting the error require is not defined even though I have followed various browserify tutorials to fix it.
To give a flavour of what I want to do. I want the app to be able to be ran on a server and then I can npm install anything and these things work smoothly. I have been using express, firebase etc to handle some of my issues.
This is an extract of my app.js file:
var express = require('express');
var app = express();
var firebase = require('firebase');
app.get('/', function (req, res) {
res.sendFile(__dirname + '/html/index.html');
});
app.get('/welcome', function (req, res) {
res.sendFile(__dirname + '/html/welcome.html');
});
I have tried to use bundle.js to get require working but it still insists it is not defined.
Browserify will let you transpile some code so it will run in the browser.
It won't let you do things which are fundamentally impossible in the browser (such as running an HTTP server as you are trying to do here).
If you want to run code that requires Node JS then you need to run it through Node JS. Typically via node app.js in your command line shell.
I am using a thesaurus API (altervista) for my JavaScript web app but I want to be able to make lots of synonym requests without worrying about API quotas, etc. I want to self-host a thesaurus on my web host and I would like to send words and receive their synonyms from JavaScript in the browser.
As research I tried node, and within node I was able to get synonyms with these packages:
"natural" and "wordnet-magic"
so then I tried to browserify "natural" and "wordnet-magic" node packages. On attempting to browserify "natural":
"Error: Cannot find module 'lapack'"
"lapack seems to be a native OS-dependent shared library, so it can't be browserified." https://github.com/moos/wordpos/issues/9
Also I had no luck browserifying "wordnet-magic":
"Uncaught TypeError: Cannot read property '_ansicursor' of undefined"
Possibly related (since sqlite3 is in my wordnet-magic packages), instances of same error reported here but still unresolved: https://github.com/mapbox/node-sqlite3/issues/512
My second choice would be a PHP solution should it be impossible in JavaScript. It does not have to use Browserify or Wordnet, but Wordnet would be such an amazing thing to have in the browser. Thanks.
Okay I can get synonyms in the browser (thanks to Stuart Watt):
I followed instructions to setup a javascript wordnet app here:
https://github.com/morungos/wordnet
then did
npm install express
and then ran this code with node:
var express = require('express');
var app = express();
var WordNet = require('node-wordnet');
var wordnet = new WordNet();
app.get('/lookup', function(req, res) {
wordnet.lookup(req.query.word, function(results) {
res.send(results);
});
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
});
and you can then see wordnet in your browser, e.g.
http://localhost:3000/lookup?word=wind
It's visible, it works, and to consume it in your html, see this answer:
https://stackoverflow.com/a/36526208/5350539
I am using Locomotive framework for creating a nodejs web-application.
In config/environments/all.js I have:
var express = require('express')
, poweredBy = require('connect-powered-by')
, util = require('util')
, connectAssets = require('connect-assets')
, redis = require('redis')
, RedisStore = require('connect-redis')(express)
, sessionStore = new RedisStore();
........
........
this.use(express.cookieParser());
this.use(express.bodyParser());
..........
..........
this.use(express.session({
secret: 'LoremIpsumDolorSit_Amet',
store: sessionStore
}));
However the session object is not present in the request object. ie. in a controller instance:
this.req.session is undefined. What am I missing and How do I configure the connect-session middleware to use redis data-store ?
My redis server is running on default port and it shows a client connected when I run my server. The client gets disconnected only when I terminate the server.
I am using Node 0.6.18, redis server version 2.4.8, locomotive version 0.3.3 and express 3.0.4 on Fedora 16.
For sessions to work in express, the three of the following must be in this very order:
this.use(express.cookieParser());
this.use(express.session(...));
this.use(this.router);
In my implementation, I had the third statement above the second.
Apparently, this is a known idiosyncrasy with Express and I am not informed enough about the inner workings of Express to explain why this is the case. Probably someone who has more experience with NodeJS can elaborate on the details.
With this.use(), you add middleware to Express' request/response handling: incoming requests pass through all middleware before ending up at your application, and outgoing responses go back up the middleware chain before being sent back to the client.
The order in which you install middleware matters: if you have one middleware (like express.session) which depends on another middleware (like express.cookieParser, to parse session cookies), you install the dependency first.
In most cases, this.router should be installed last, or almost last (usually followed by an error handling middleware), because it depends on cookies and sessions having been handled before it get called.