Using connect-livereload in an Express node app - node.js

Following this great article on how to use npm as a build tool, I would like to implement it when building a nodejs express web app.
My node app is created on port 8080, this is a simplified version of my server.js file:
var env = process.env.NODE_ENV
var path = require('path');
var express = require('express');
var logger = require('morgan');
var routes = require('./routes');
var app = express();
app.set('port', process.env.PORT || 8080);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.engine('jade', require('jade').__express)
var Oneday = 86400000;
app.use(express.static(__dirname + '/www', {
maxAge: env == 'development' ? 0 : Oneday
}));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, '/public'), {
maxAge: env == 'development' ? 0 : Oneday
}))
if (env == 'development') {
// var liveReloadPort = 9091;
app.use(require('connect-livereload')({
port: 8080
// src: "js/"
// port: liveReloadPort
}));
}
routes.blog(app);
routes.frontend(app, passport);
app.use(function(err, req, res, next) {
console.log(err.stack);
res.status(500).send({
message: err.message
})
});
app.listen(app.get('port'));
console.log('Server starting on port: ' + app.get('port'));
The file that I'm watching before needing to reload is in www/js.
I am using npm as a build tool and before launching server.js with npm I launch a separate process that does watchify source/js/app.js -v -o wwww/js/bundle.js
I did checked that watchify works correctly, updating as I save my files. But there is no livereload once a file is changed.
The error I get in the console is:
Uncaught SyntaxError: Unexpected token <
and I can see that connect-livereload inserted this script in the html:
<script>
//<![CDATA[
document.write('<script src="//' + (location.hostname || 'localhost') + ':8080/livereload.js?snipver=1"><\/script>')
//]]>
</script>
<script src="//localhost:8080/livereload.js?snipver=1"> </script>
I tried also to use live-reload as mentionned in the original article but without success and I am not sure it's the right plugin to use as live-reload launches a server, when I already start one with express.
Any ideas?

connect-livereload only inserts the script into the html (so that you don't need a browser plugin).
you still need a separate livereload server, try node-livereload, grunt-contrib-connect or grunt-contrib-watch ... since you want to use npm as build tool, the first one should be recommendable.
then you would have to change the livereload port to the running live-reload server port (default port is 35729):
app.use(require('connect-livereload')({
port: 35729
}));
The server you tried: live-reload should work as well.
Can you try and start it with:
live-reload [<path>...] --port=35729 --delay=someDelay
and change the connect-livereload option to:
app.use(require('connect-livereload')({
src: "localhost:35729"
}));

This answer shows how to set up livereload to refresh changes to both front and backend files to browser. It might be of help to you. https://stackoverflow.com/a/60542132/5032692

Related

How to fix recent node.js errors from my apps?

const express = require("express");
const path = require("path");
var hbs = require("express-handlebars");
const morgan = require("morgan");
const middlewares = require("./middlewares/middlewares");
const PORT = process.env.PORT || 3002;
var app = express();
// setup static file service
app.use(express.static(path.join(__dirname, "static")));
//Setup app port
app.set("port", process.env.PORT || PORT);
// setup handlebars and the view engine for res.render calls
app.set("view engine", "html");
app.engine(
"html",
hbs({
extname: "html",
defaultView: "default",
layoutsDir: __dirname + "/views/layouts/",
partialsDir: __dirname + "/views/partials/"
})
);
app.get("/", (req, res) => {
res.send("Hello world");
});
app.use(morgan("common"));
app.use(middlewares.errorHandler);
app.use(middlewares.ignoreFavicon);
app.use(middlewares.notFound);
var server = app.listen(app.get("port"), () =>
console.log(`Server started...Listening on port: ${PORT}`)
);
This is my basic server setup. Whenever I request a route I get the following errors in my console. I had to add middleware ignoring this route as well. "GET /favicon.ico HTTP/1.1"
Uncaught TypeError: Cannot convert undefined or null to object
at Function.keys ()
at contentscript.bundle.js:72
at S.Object.isExtensible.Object.isExtensible.e.___hb.e.___hb (contentscript.bundle.js:29)
[Honeybadger] Unable to send error report: no API key has been configured.
is there more of a stack trace? Also, when you say "console", do you mean in the Node console, or in the browser console? It looks like the log message is from our client-side JavaScript package, which I would expect in the browser. If you're catching errors in your Node application, you should use our Node.js package.
In honeybadger.js, ___hb can sometimes appear in stack traces because the function was wrapped by our library, but the error is often still in your project code. I would suggest configuring Honeybadger with an API key if you're trying to diagnose errors in production.
Related docs:
https://docs.honeybadger.io/lib/javascript/index.html
https://docs.honeybadger.io/lib/node.html

Parse-Server, email-verification bug?

I have been stuck longer than I would like, with a problem related to email verification when creating an account on Parse-Server (/Heroku). Though I made a few post on the issue, I was not lucky enough (or maybe did not formulate things clearly enough) to get significant help. So I decided to do it all over again, this time giving a precise step by step way to reproduce the bug, for anyone interested in taking a close look. If what I do is right from start to end, then there must be a bug. If on the other hand I do something wrong (this is most probably the case), I hope somebody can point out the mistake.
Here is the process, start by creating an app on heroku, using the following commands at the terminal:
git clone https://github.com/parse-community/parse-server-example.git
mv parse-server-example linkbugapp808
cd linkbugapp808/
npm install #parse/simple-mailgun-adapter --save
heroku create linkbugapp808
heroku addons:create mongolab:sandbox
heroku config:set APP_ID=ABCDEF-12345678:xytzt_SSTTJJZ
heroku config:set MASTER_KEY=MMMMM-87878787:wwyyssaa_PPGHYU
heroku config:set SERVER_URL=https://linkbugapp808.herokuapp.com/
heroku config:set PARSE_PUBLIC_SERVER_URL=https://linkbugapp808.herokuapp.com
Of course if the name I use "linkbugapp808" is taken or you don't like it you may choose another one.
Set the index.js file as this (fixing the mailgun parameters that need to be fixed, to fit you environment):
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var path = require('path');
var mongo = require('mongodb');
var MongoClient = mongo.MongoClient;
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
if (!databaseUri) {
console.log('DATABASE_URI not specified, falling back to localhost.');
}
var api = new ParseServer({
databaseURI: databaseUri,
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID,
masterKey: process.env.MASTER_KEY,
serverURL: process.env.SERVER_URL,
publicServerURL: process.env.PARSE_PUBLIC_SERVER_URL,
appName: 'LinkBugApp',
verifyUserEmails: true,
emailAdapter: {
module: '#parse/simple-mailgun-adapter',
options: {
fromAddress: 'from#somemail.com',
domain: 'some.domain',
apiKey: 'key-apiKey-mailgun-apiKey'
}
}
});
var app = express();
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
app.set('port', (process.env.PORT || 5000));
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);
// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
res.status(200).send('I dream of being a website. Please star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpServer);
Next run the following command in the terminal (inside the linkbugapp808 root folder):
git add . && git commit -m "update linkbugapp808" && git push heroku master
At this point the app is created on Heroku and ready to go.
Then from an iOS app create an account on the Parse-Server we just set above.
All seems to go fine.
The user for whom the account was created will receive a mail similar to this one:
Hi,
You are being asked to confirm the e-mail address usermail#xmail.com with LinkBugApp
Click here to confirm it:
https://linkbugapp808.herokuapp.com/apps/ABCDEF-12345678:xytzt_SSTTJJZ/verify_email?token=SiYyk9NgVkcwhXXWlEdEUTjyz&username=ausrnamex
When clicking the confirmation link inside the mail this is what one can see (not exactly what is expected from a sign up confirmation link):
Cannot GET /apps/ABCDEF-12345678:xytzt_SSTTJJZ/verify_email?token=SiYyk9NgVkcwhXXWlEdEUTjyz&username=ausrnamex
I have tried with several browsers, but the result is identical.
Why do we get into this situation?

Angular2 application with NodeJS not loading everything

I'm experimenting with Angular2 and, with the quick start guide on their official documentation, I'm definitely up and running. However, if I want to do any APIs on the server or host it on the cloud it seems I'll need to use Node. I think I have everything set correctly in the server.js file, yet when I run it it seems like it's not loading everything from SystemJS and I get the following errors:
Here is the Node code:
var express = require("express");
var bodyParser = require("body-parser");
var app = express();
var System = require('systemjs');
// loads './app.js' from the current directory
System.import('app').then(function(m) {
console.log(m);
});
// Config
app.set('port', (process.env.PORT || 3000));
app.use('/app', express.static(__dirname + '/app'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.listen(app.get('port'), function() {
console.log('MEAN app listening on port ' + app.get('port'));
});
app.get('*', function(req, res) {
res.sendFile(__dirname + '/index.html');
});
I'm not sure what I'm missing to include in the Node side that gets included when running lite-server from npm start that is included from the Angular2 quick start guide.
When you are telling express where to look for the static files, you have to include where your js files will be as well.
For example, in one of my projects I have it like so
app.use('/css', express.static(path.resolve(appPath, 'css')));
app.use('/lib/css', express.static(path.resolve(appPath + '/lib', 'css')));
app.use('/lib/js', express.static(path.resolve(appPath + '/lib', 'js')));
app.use('/assets', express.static(path.resolve(appPath, 'assets')));
app.use('/node_modules', express.static(path.resolve(appPath, 'node_modules')));
app.use('/app', express.static(path.resolve(appPath, 'app')));
I believe that might be your issue or hopefully set you in the right path.

Deploy node.js app on heroku succeeds but doesn't work

I have a very simple, straight-forward node.js app [1] I want to deploy on heroku. Although I'm able to deploy it, the page can't be accessed in the browser.
I followed the advices from the 'Getting Started with Node.js on Heroku' guide [2]. When I run the application using node index.js locally, I'm able to access the application at http://localhost:8080/index.jade, however, when I try to access it on heroku at http://immonow.herokuapp.com:8080/index.jade it would throw me a ERR_CONNECTION_REFUSED HTTP error code.
How I deployed my app:
git commit -am "made changes" // commit changes
git push origin master // push to git
heroku create // create heroku app
git push heroku master // push to heroku
heroku ps:scale web=1 // start workers
My node.js server:
#!/usr/bin/env node
var http = require('http')
, jade = require('jade')
, static = require('node-static')
, jadeRe = /\.jade$/
, path = process.argv.slice(2)[0]
, fileServer = new static.Server(path || '.')
http.createServer(function (req, res) {
if (req.url.match(jadeRe)) {
res.writeHead(200, {'Content-Type': 'text/html'})
res.end(jade.renderFile('.' + req.url, {
filename: '.' + req.url.replace(jadeRe, '')
}))
} else {
req.addListener('end', function () {
fileServer.serve(req, res)
}).resume()
}
}).listen(8080)
Any help would be appreciated.
[1] https://github.com/takahser/immonow
[2] https://devcenter.heroku.com/articles/getting-started-with-nodejs#introduction
Since I was not able to get it to work using the http package, I decided to use express instead. As for the port, I had to do it as follow
var port = process.env.PORT || 3000;
app.listen(port);
in order to get it to work [1].
Here is my full working server:
/**
* Module dependencies.
*/
var express = require('express');
// Path to our public directory
var pub = __dirname + '/public';
// setup middleware
var app = express();
app.use(express.static(pub));
app.use("/css", express.static(__dirname + '/css'));
app.use("/font", express.static(__dirname + '/font'));
app.use("/img", express.static(__dirname + '/img'));
app.use("/js", express.static(__dirname + '/js'));
app.use("/video", express.static(__dirname + '/video'));
// Set our default template engine to "jade"
// which prevents the need for extensions
// (although you can still mix and match)
app.set('view engine', 'jade');
app.get('/', function(req, res){
res.render('index');
});
app.get('/*', function(req, res){
console.log(req.url.replace("/",""));
res.render(req.url.replace("/",""));
});
// change this to a better error handler in your code
// sending stacktrace to users in production is not good
app.use(function(err, req, res, next) {
res.send(err.stack);
});
/* istanbul ignore next */
if (!module.parent) {
var port = process.env.PORT || 3000;
app.listen(port);
console.log('Express started on port 3000');
}
[1] see: Node.js port issue on Heroku cedar stack
Things I had to do..
Create a Procfile in the root directory (a file literally called Procfile, no extension).
Inside Procfile, type:
web: node server.js
Add a script and engine to package.json
"scripts": {
"start": "node server.js"
}
"engines": {
"node": "8.9.3"
}
Update port in server.js
var port = process.env.PORT || 8080;
And why..
To explicitly declare what command should be executed to start your app. Heroku looks for a Procfile specifying your process types
For the script, if no Procfile is present in the root directory during the build process, your web process will be started by running npm start. For the engine, to specify a Node version that matches the runtime you’re developing with and want to use on Heroku.
Heroku already assigns your app a port and adds it to the env, so you can't set the port to a fixed number.
Resources:
https://devcenter.heroku.com/articles/getting-started-with-nodejs#introduction
https://devcenter.heroku.com/articles/troubleshooting-node-deploys
https://devcenter.heroku.com/articles/deploying-nodejs

Node.js "Uncaught SyntaxError: Unexpected token <" when loading socket.io.js

I have simple application to test socket.io using node.js and express framework
There are some files relating to my app
File server.js
var express = require('express');
var env = process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var app = express();
var http = require('http');
var server = http.createServer(app);
var config = require('./server/config/config')[env];
require('./server/config/express')(app, config);
/////////////////////////// Database ////////////////////////////////
require('./server/config/mongoose')(config);
/////////////////////////// Passport ////////////////////////////////
require('./server/config/passport')();
/////////////////////////// Routes ////////////////////////////////
require('./server/config/routes')(app);
/////////////////////////// Socket ////////////////////////////////
require('./server/config/socket')(server);
/////////////////////////// Port ////////////////////////////////
app.listen(config.port);
console.log("Listening on port " + config.port + '...');
File express.js
var express = require('express'),
stylus = require('stylus'),
passport = require('passport');
module.exports = function(app, config){
function compile(str, path){
return stylus(str).set('filename', path);
};
app.configure(function(){
app.set('views', config.rootPath + '/server/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({secret: 'test whiteboard unicorns'}));
app.use(passport.initialize());
// using session
app.use(passport.session());
// config Stylus middleware
app.use(stylus.middleware({
src: config.rootPath + '/public',
compile: compile
}));
app.use(express.static(config.rootPath + '/public', { redirect : false }));
});
}
script.jade
script(type="text/javascript", src="/vendor/jquery/dist/jquery.min.js")
script(type="text/javascript", src="/vendor/angular/angular.js")
script(type="text/javascript", src="/vendor/bootstrap/dist/js/bootstrap.min.js")
script(type="text/javascript", src="/vendor/toastr/toastr.min.js")
script(type="text/javascript", src="/vendor/restangular/dist/restangular.min.js")
script(type="text/javascript", src="/vendor/lodash/dist/lodash.min.js")
script(type="text/javascript", src="/vendor/jquery-minicolors.min.js")
script(type="text/javascript", src="/socket.io/socket.io.js")
When I start with nodemon server.js, node.js console runs quite OK
[nodemon] starting `node server.js`
connect.multipart() will be removed in connect 3.0
info - socket.io started
Listening on port 3030...
However, when I open browser and test app, I see errors in console
Uncaught SyntaxError: Unexpected token < jquery-minicolors.min.js:1
Uncaught SyntaxError: Unexpected token < socket.io.js:1
I just don't know why these errors happens and how to fix them
Thanks
This means that jquery-minicolors.min.js is actually an html document. make sure that the route is correct.
You're getting the same error on socket.io.js, make sure that when you hit "localhost:3030/socket.io/socket.io.js" that you are actually getting something.
Either way, the "unexpected <" comes from a 404 error html page.
I am running an app built using JQuery Html and Css on browser using VS 2017 IDE. The app wouldn't run with a Chrome spinning wheel.
I unchecked the below checkbox and the app started running.
It might help someone some day.
I had this error too when setting up the server using node.js. The problem was that in server.js file I initialized the socket.io library with http argument before I created the server.
So I had
var http = require('http');
const io = require('socket.io', 'net')(http);
http.createServer(function(res,req) {
...
});
Corrected it to:
var http = require('http').createServer(handler);
const io = require('socket.io', 'net')(http);

Resources