How do I compile jade on request rather than just server start? - javascript

I'm looking to compile my jade on server request/response that way I can make changes to the jade file and see it in real time, rather than having to restart the server every time. This is the fake mockup I have so far.
var http = require('http')
, jade = require('jade')
, path = __dirname + '/index.jade'
, str = require('fs').readFileSync(path, 'utf8');
function onRequest(req, res) {
req({
var fn = jade.compile(str, { filename: path, pretty: true});
});
res.writeHead(200, {
"Content-Type": "text/html"
});
res.write(fn());
res.end();
}
http.createServer(onRequest).listen(4000);
console.log('Server started.');
I hope I made myself clear!

You're only reading the file once, on server startup. If you wanted to have it read changes you'd have to read it on request, meaning your mock-up would look more like:
function onRequest(req, res) {
res.writeHead(200, {
"Content-Type": "text/html"
});
fs.readFile(path, 'utf8', function (err, str) {
var fn = jade.compile(str, { filename: path, pretty: true});
res.write(fn());
res.end();
});
}
Something like that would read the file every time, which is probably okay for development purposes, but if you only wanted to reload/process the file when something changed, you might use a file watcher (fs.watch might fit this bill).
Something like this (just an untested example as an idea):
var fn;
// Clear the fn when the file is changed
// (I don't have much experience with `watch`, so you might want to
// respond differently depending on the event triggered)
fs.watch(path, function (event) {
fn = null;
});
function onRequest(req, res) {
res.writeHead(200, {
"Content-Type": "text/html"
});
var end = function (tmpl) {
res.write(tmpl());
res.end();
};
if (fn) return end(fn);
fs.readFile(path, 'utf8', function (err, str) {
fn = jade.compile(str, { filename: path, pretty: true});
end(fn);
});
}

Related

How to make my server fetch js file instead of fetching html again?

I have an index.html which uses bundle.js file. It works fine in the local machine. But when try to do the same thing with server, it just shows only html file content. when looked at the code in console instead of regular js code the bundle.js file contains same html code. This the server code I have used.
var http = require('http');
var fs = require('fs');
const PORT=3012;
fs.readFile('./index.html', function (err, html) {
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
}).listen(PORT);
});
In order to serve your bundle.js file and another files without using express or another already made tested and preferred way, you can serve any file you like (see "routeToFile" function).
//Return the file path you want to serve to that request url
const routeToFile = ({url}) => {
if(url === '/'){
return './index.html';
}
return `.${url}`;
}
With "mimeTypes" array you can guess the right mime type by just checking the file extension (mimeTypes[fileExtension]).
//File mime types for content type response
const mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpg'
};
If there is an error, for instance if the file don't exist, just send the error code, or a page you like too (see "onError" function)
//If the file is missing or there is an error
const onError = (error, response) => {
if(error.code == 'ENOENT') {
response.writeHead(404);
}
else {
response.writeHead(500);
console.error(error);
}
response.end();
}
Finally, the main function to run all of this, will be:
//Create the http server
http.createServer((req, res) => {
const filePath = routeToFile(req)
const fileExtension = String(path.extname(filePath)).toLowerCase();
const contentType = mimeTypes[fileExtension] || 'application/octet-stream';
fs.readFile(filePath, function(error, content) {
if (error) {
return onError(error, res)
}
else {
res.writeHead(200, { 'Content-Type': contentType });
res.end(content, 'utf-8');
}
});
}).listen(PORT, () =>{
console.log(`server start at port ${PORT}`);
});
Don't forget the requires, or it won't run :D
const http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = 3012

how to run different .js file in one server.js file in NODE JS?

this is demo.js file and i want to use this file in server.js file so that i can use diffrent js files in one server file.
Demo.js:
app.get('/add User', function (req, res) {
var MongoClient = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/project';
MongoClient.connect(url, function (err, db) {
var collection = db.collection('users');
collection.find({name: 'shruti'}).toArray(function (err, result) {
console.log(, result);
db.close();
});
Server.js:
var a = require('./demo.js');
vr http=require("http");
var server = http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"});
response.write(a);
res.end();});
server.listen(7860);
A possible sample would look like :
demo.js
var myModule = {
defineRoutes: function(router){
//do something...
}
}
module.exports = myModule;
server.js
var myModule = require('demo.js');
myModule.defineRoutes(router);
As stated, you need to export.
When you do:
var item = require("mymodule");
Require returns an object, which is a reference the value of module.exports for that given file - in your case demo.js.
You can write your modules a few ways as some people have shown you. Because it is encapsulated you basically are identifying what is public or can be called. Few ways to write it - you could also do:
module.exports = {
yourCall: function () {
console.log("stuff here");
}
};
As stated by #ishann, who is dead on here, you are writing something you assume might be populated. Going to a database and returning is an asynchronous call - so it will take time to go do that and then for the results to be returned.
Based on your structure - ideally what you want to do is assign the route ( "/addUser" ) which will pass in the response object to you:
app.get('/add User', function (req, res) {
var MongoClient = mongodb.MongoClient;
var url = 'mongodb://localhost:27017/project';
MongoClient.connect(url, function (err, db) {
var collection = db.collection('users');
collection.find({name: 'shruti'}).toArray(function (err, result) {
console.log(, result);
db.close();
// set the type
res.writeHead(200, {"Content-Type": "application/json"});
res.write(result);
});
Just looks like your code needs a bit of reorg, but separting concerns is good. You might want to also check out Express as a framework for node.

How to add a callback in this function for gzip

Here is my code:
/*jshint globalstrict: true*/
var zlib = require('zlib');
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html', 'Content-Encoding': 'gzip'});
var text = "Hey this works!";
zlib.gzip(text, function (_, result) {
res.end(result);
});
}).listen(8081);
I want to add a callback to the above code to follow the node.js async concept. How do I do that? Also, I am pretty new to node.js
var callback = function (err, result) {
// gzip has finished, do any thing you want here,
// also add if about the 'err' as mscdex said.
res.end(result);
}
zlib.gzip(text, callback);
callback is a function,you already added it .

How to serve (uploaded) images using Meteor

I have this Meteor application in which it is possible to upload images. The uploading parts seem to work. I store the images in .uploads. Now I would like to make these images accessable by the following URL
http://localhost:3000/uploads
After a bit of googling I was able to create the following server side code:
var fs = Meteor.require('fs');
if (Meteor.isServer) {
WebApp.connectHandlers.stack.splice(0, 0, {
route: '/uploads',
handle: function (req, res, next) {
var path = process.env.PWD + '/.' + req.originalUrl.substr(1);
fs.readFile(path, {encoding: 'binary'}, function (err,data) {
if (err) {
throw err;
}
res.writeHead(200, {
'Content-Type': 'image/png'
});
//res.setEncoding("binary"); // this method does not exist
res.write(data);
res.end();
});
}
});
}
This code works, the path constructed is correct and in the browser I receive the 200 code, except it cannot display the image. Something is wrong with the data the browser receives. I checked the image on disk which is fine. So the code above must do something wrong with the data. Any suggestions what that might be?
Here is the code I found after googling (and works for me) a few days ago when I wanted to do what you need to do
files are in .screenshots directory mapped to :
http://localhost:3000/screenshots
code :
//directly serve screenshot files from /.screenshots dir
var fs = Npm.require('fs');
WebApp.connectHandlers.use(function(req, res, next) {
var re = /^\/screenshots\/(.*)$/.exec(req.url);
if (re !== null) { // Only handle URLs that start with /screenshots/*
var filePath = process.env.PWD + '/.screenshots/' + re[1];
var data = fs.readFileSync(filePath, data);
res.writeHead(200, {
'Content-Type': 'image'
});
res.write(data);
res.end();
} else { // Other urls will have default behaviors
next();
}
});

NodeJS throw new TypeError

When i try to run my JS file i get this error:
http.js:783
throw new TypeError('first argument must be a string or Buffer');
I was following this tutorial which didn't seem to mention the problem Tutorial Link
My JS file has:
var http = require('http'),
fs = require('fs'),
sanitize = require('validator').sanitize;
var app = http.createServer(function (request, response) {
fs.readFile("client.html", 'utf-8', function (error, data) {
response.writeHead(200, {'Content-Type': 'text/html'});
response.write(data);
response.end();
});
}).listen(1337);
var io = require('socket.io').listen(app);
io.sockets.on('connection', function(socket) {
socket.on('message_to_server', function(data) {
var escaped_message = sanitize(data["message"]).escape();
io.sockets.emit("message_to_client",{ message: escaped_message });
});
});
I have Socket.io and validator installed in my node_modules folder. I'm quite new to this sort of stuff and looks like this tutorial wasn't a good starting choice, I can't seem to get it working.
You're not doing any error checking, and I'd bet that readFile is throwing an error. This means data is undefined, so when you try to response.write(data), the http module throws an error.
Always check the error parameter in your callback functions, and handle it appropriately.
fs.readFile("client.html", 'utf-8', function (error, data) {
if (error) {
response.writeHead(500, {'Content-Type': 'text/html'});
response.write(error.toString());
} else {
response.writeHead(200, {'Content-Type': 'text/html'});
response.write(data);
}
response.end();
});

Categories