node.js gulp-livereload not refreshing in browser - node.js

I am new to node.js. With the following code the reload task is triggered when files in the dist folder are modified.
I have the livereload plugin in chrome activated. The status is "live reload is connected". Yet the browser is not refreshed automatically.
Anything missing in this code?
const path = require('path');
const gulp = require('gulp');
const nodemon = require('gulp-nodemon');
const es6Pipeline = require('gulp-webpack-es6-pipeline');
const less = require('gulp-less');
var webserver = require('gulp-webserver');
var livereload = require('gulp-livereload');
es6Pipeline.registerBuildGulpTasks(
gulp,
{
entryPoints: {
'bundle': path.join(__dirname, '/src/index.js')
},
outputDir: path.join(__dirname, 'public/generated/js')
}
);
gulp.task('live-server', (done) => {
});
gulp.task('test-server', function () {
var express = require('express'),
serverport = 5000;
var server = express();
server.use(express.static('./dist'));
server.listen(serverport);
console.log("Server started at port: " + serverport);
// Start live reload
livereload({start: true});
gulp.watch('dist/*.*', ['reload']);
});
gulp.task('reload', function () {
console.log("refreshed");
livereload();
});
gulp.task('generate', ['es6Pipeline:build:release']);
gulp.task('run-release', ['es6Pipeline:build:release', 'test-server']);
gulp.task('run-dev', ['es6Pipeline:build:dev', 'test-server']);
gulp.task('default', ['es6Pipeline:watch', 'test-server']);

Have you tried the following ?
gulp.task('reload', function () {
console.log("refreshed");
livereload.listen();
});

Related

How to execute compiled code using the webpack node API?

webpack node API
Here's what I've got:
#!/usr/bin/env node
const webpack = require('webpack');
const config = require('./webpack.config');
const compiler = webpack(config);
const express = require('express');
const app = express();
const os = require('os');
const Chalk = require('chalk');
const Path = require('path');
const networkInterface = process.platform === 'win32' ? 'Ethernet' : 'eth0';
const ip = os.networkInterfaces()[networkInterface].find(x => x.family === 'IPv4').address;
const port = 3000;
// https://webpack.js.org/api/node/
// https://github.com/webpack/webpack-dev-middleware/blob/master/lib/index.js
// https://github.com/webpack/webpack-dev-middleware
const watcher = compiler.watch({
aggregateTimeout: 250,
poll: 50,
ignored: /\bnode_modules\b/
}, (err, stats) => {
const elapsed = stats.endTime - stats.startTime;
console.log(`Recompiled in ${elapsed}ms`)
// How to run the compiled JS ?
})
let interrupted = false;
process.on('SIGINT', () => {
if(!interrupted) {
interrupted = true;
console.log('\b\bShutting down...');
watcher.close(() => {
console.log('Webpack watcher stopped.')
});
server.close(() => {
console.log('Express server stopped.')
});
} else {
console.log('\b\bForcing shut down');
process.exit(2);
}
});
const server = app.listen(port, '0.0.0.0', () => {
console.log(`Listening on ${Chalk.blue(`http://${ip}:${port}`)}`);
})
When the watcher runs the callback, my JS should be ready to execute. How can I do that? There should be something in that stats object, just not sure what to look for because it's huge.
For example, I can get the output filename like:
const assetsByChunkName = stats.toJson().assetsByChunkName;
const outputPath = stats.toJson().outputPath;
const main = Path.join(outputPath, assetsByChunkName.main);
But it's not on disk. How to I read it using webpack's fake file system? Or do I even need to read it, is the output source in memory somewhere? And I suppose I just run it through eval()?
I came up with something that seems to work:
const watcher = compiler.watch({
aggregateTimeout: 250,
poll: 50,
ignored: /\bnode_modules\b/
}, (err, stats) => {
if(err) {
console.error(err);
return;
}
console.log(stats.toString({
chunks: false, // Makes the build much quieter
colors: true, // Shows colors in the console
stats: 'minimal',
}));
router = eval(stats.compilation.assets['main.js'].source()).default;
})
Only problem is that it exits whenever there is a syntax error in a source file.

Web socket doesn't open on other machines

Web soket connection error
I've got a problem with my server. It uses express and express-ws for web sockets. The problem is that this server works fine on the local host. But when i run it with the help of ssh (see localhost.run) and access the site by the given link from another computer (through Chrome), the web socket doesn't open and the next error shows up in the console
main.js:12 WebSocket connection to 'ws://localhost:3000/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED
even though i added cert and key to the server connection. P.S. The site loads too, it's only that the socket doesn't work.
here is the server.js code:
"use strict";
const fs = require("fs");
const credentials = {
key: fs.readFileSync("./key.pem"),
cert: fs.readFileSync("./cert.pem")
};
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const https = require("https");
const PORT = process.env.PORT || 3000;
app.use(express.static(__dirname + "/public/Messenger"));
app.use(express.static(__dirname + "/public/Login"));
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const server = new https.createServer(credentials);
const expressWs = require("express-ws")(app, server);//if i take the
//second argument (server) away, it works fine on localhost:3000, but
//with this it fires the error:
//WebSocket connection to 'ws://localhost:3000/' failed: Connection
//closed before receiving a handshake response
const routes = require("./MVC/Router/router.js"); //importing route
routes(app);
app.listen(PORT, () => {
console.log("listening on port " + PORT);
});
here is the router.js:
"use strict";
module.exports = function(app) {
const database = require("../Controller/controller.js");
// database Routes
app.route("/").get(database.loadPage);
app.route("/login").get(database.loginPageLoad);
app
.route("/signIn")
.get(database.signInPageLoad)
.post(database.signIn);
app
.route("/submitLogin")
.post(database.loginSubmit)
.get(database.showUsers);
app.ws("/", database.sendmsg);
};
which redirects the processing flow to the next part of controller.js:
const CLIENTS = [];
let counter = 0;
exports.sendmsg = (ws, req) => {
console.log(cache.get("lorem"));
ws.on("message", msg => {
if (msg === "connected") {
console.log("connected");
CLIENTS.push([ws, counter]);
ws.send(JSON.stringify({ counter }));
counter++;
} else if (JSON.parse(msg).msg && JSON.parse(msg).ID) {
CLIENTS.forEach(box => {
if (box[1] === msg.ID) {
console.log(`user ${box[1]} is closed`);
box.push("closed");
box[0].close();
} else {
return;
}
});
} else {
sendAll(msg);
}
ws.on("close", () => {
console.log("disconnected");
ws.close();
});
});
};
function sendAll(message) {
for (let i = 0; i < CLIENTS.length; i++) {
if (CLIENTS[i][0].readyState === 1) {
CLIENTS[i][0].send(message);
}
}
}
The last piece of code is just what it does on the server, don't care of it too much. The problem is that the web socket doesn't get open when i enter the link from another computer. How can i solve it?

NodeJs says "ReferenceError: window is not defined" with jsPDF

I am creating a sample project with NodeJs and jsPDF. When I run, it echos ReferenceError: window is not defined. I also used John Gordon answer from here, but again also same problem.
I tried with
var express = require('express');
var jsPDF = require('jspdf');
var app = express();
app.get('/', function(req, res)
{
global.window = {document: {createElementNS: () => {return {}} }};
global.navigator = {};
global.btoa = () => {};
var fs = require('fs');
var jsPDF = require('jspdf');
var jsPDFTable = require('jspdf-autotable');
var doc = new jsPDF();
doc.text("Hello", 10, 10);
var data = doc.output();
fs.writeFileSync('./tmp/storage/pdf/document.pdf', data);
delete global.window;
delete global.navigator;
delete global.btoa;
});
var port = process.env.PORT || 8080;
app.listen(port);
console.log('Server started');
module.exports = app;
All you need to do is to remove your var jsPDF = require('jspdf'); at the top and to have the similar declaration inside your app.get.. (which you already have) function like this,
var express = require('express');
var app = express();
app.get('/', function(req, res)
{
global.window = {document: {createElementNS: () => {return {}} }};
global.navigator = {};
global.btoa = () => {};
var fs = require('fs');
var jsPDF = require('jspdf');
var jsPDFTable = require('jspdf-autotable');
var doc = new jsPDF();
doc.text("Hello", 10, 10);
var data = doc.output();
fs.writeFileSync('./document.pdf', data);
delete global.window;
delete global.navigator;
delete global.btoa;
});
var port = process.env.PORT || 8080;
app.listen(port);
console.log('Server started');
module.exports = app;
Hope this helps!
The specified package jspdf is a client only library and need to be used in a browser environment to work properly.
The description is clear in the package home page:
A library to generate PDFs in client-side JavaScript.
Now, the reason an npm package is available is because bundlers like Webpack and Browserify can load npm packages and convert them into a proper browser compatible script. The require() is not defined in a browser environment and will not work without these bundlers.
So, either choose a library that supports NodeJS like
https://www.npmjs.com/package/pdfkit or shift your PDF related code to browser and work with it.
EDIT:
https://github.com/MrRio/jsPDF/issues/566#issuecomment-382039316
shows that you can use the library in NodeJS env by making the following changes.
In that case, you need to define the global variables before requireing the module.
global.window = {document: {createElementNS: () => {return {}} }};
global.navigator = {};
global.btoa = () => {};
var fs = require('fs');
var jsPDF = require('jspdf');
var jsPDFTable = require('jspdf-autotable');
var app = require('express')();
app.get('/', function(req, res)
{
var doc = new jsPDF();
// ...
}
You can place the script tag either in the head or body tag in the html page, either one is fine. To decide where to place, this answer might be of help

Gulp acting differently on remote server

I run the same gulpfile on local and remote. On local, everything is fine but when on remote, both "vendors" and "assets" tasks are not doing anything and there's no error when I run the gulp. Below is my gulp script -
var gulp = require('gulp'),
gutil = require('gulp-util'),
clean = require('gulp-clean'),
changed = require('gulp-changed'),
concat = require('gulp-concat'),
rename = require('gulp-rename'),
jshint = require('gulp-jshint'),
uglify = require('gulp-uglify'),
less = require('gulp-less'),
csso = require('gulp-csso'),
jade = require('gulp-jade'),
es = require('event-stream'),
embedlr = require('gulp-embedlr'),
refresh = require('gulp-livereload'),
express = require('express'),
http = require('http'),
lr = require('tiny-lr')();
gulp.task('clean', function () {
// Clear the destination folder
gulp.src('dist/**/*.*', { read: false })
.pipe(clean({ force: true }));
});
// Vendor Files
// var vendors = {
// js: [ './bower_components/**/ZeroClipBoard.js'],
// assets: ['./bower_components/**/ZeroClipBoard.swf']
// };
// Compile JS
gulp.task('scripts', function () {
return es.concat(
// Detect errors and potential problems in your JavaScript code
// You can enable or disable default JSHint options in the .jshintrc file
// Concatenate, minify and copy all JavaScript (except vendor scripts)
gulp.src(['./src/js/**/*.js'])
.pipe(concat('main.js'))
.pipe(uglify({mangle: false}))
.pipe(gulp.dest('./dist/js'))
.pipe(refresh(lr))
)});
// Copy Vendor Script and Assets
gulp.task('assets', function () {
return gulp.src(['./bower_components/**/ZeroClipBoard.swf'], {base: './'})
.pipe(gulp.dest('./dist/vendors'));
});
gulp.task('vendors', function () {
return gulp.src(['./bower_components/**/ZeroClipBoard.js'])
.pipe(concat('vendor.js'))
.pipe(uglify({mangle: false}))
.pipe(gulp.dest('./dist/js'));
});
// Compile LESS files
gulp.task('styles', function () {
return gulp.src('./src/less/styles.less')
.pipe(less())
.pipe(rename('styles.css'))
.pipe(csso())
.pipe(gulp.dest('./dist/css'))
.pipe(refresh(lr));
});
gulp.task('templates', function () {
// Compile Jade files
return gulp.src('./src/jade/index.jade')
.pipe(jade())
.pipe(rename('index.html'))
.pipe(gulp.dest('./dist/'))
.pipe(refresh(lr));
});
gulp.task('server', function () {
// Create a HTTP server for static files
var port = 3000;
var app = express();
var server = http.createServer(app);
app.use(express.static(__dirname + '/dist'));
server.on('listening', function () {
gutil.log('Listening on http://localhost:' + server.address().port);
});
server.on('error', function (err) {
if (err.code === 'EADDRINUSE') {
gutil.log('Address in use, retrying...');
setTimeout(function () {
server.listen(port);
}, 1000);
}
});
server.listen(port);
});
gulp.task('lr-server', function () {
// Create a LiveReload server
lr.listen(35729, function (err) {
if (err) {
gutil.log(err);
}
});
});
gulp.task('watch', function () {
// Watch .less files and run tasks if they change
gulp.watch('./src/less/**/*.less', ['styles']);
// Watch .jade files and run tasks if they change
gulp.watch('./src/jade/index.jade', ['templates']);
// Watch .js files
gulp.watch('./src/js/**/*.js', ['scripts']);
});
// The dist task (used to store all files that will go to the server)
gulp.task('dist', ['clean', 'styles', 'templates', 'scripts', 'vendors']);
// The default task (called when you run `gulp`)
gulp.task('default', ['clean', 'styles', 'templates', 'scripts', 'assets', 'vendors', 'lr-server', 'server', 'watch']);

Express.js with Phantom.js

I'm using Greg Franko's great Backbone-Require-Boilerplate and I was thinking about SEO so I found Phantom.js
Now I'm trying to integrate it and found.
http://backbonetutorials.com/seo-for-single-page-apps/
which looks like the answer but just couldn't make this work. I have PhantomJs installed.
and my server.js is
// DEPENDENCIES
// ============
var express = require("express"),
http = require("http"),
port = (process.env.PORT || 8001),
server = module.exports = express();
// SERVER CONFIGURATION
// ====================
server.configure(function() {
server.use(express["static"](__dirname + "/../public"));
server.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));
server.use(server.router);
server.get(/(.*)/, respond);
});
// SERVER
// ======
// Start Node.js Server
var app = http.createServer(server);
app.listen(port);
So how would I ever plug Phantom.js in this?
if you are looking for a node integration with express, please look at this:
https://github.com/Obvious/phantomjs
EDIT:
and here is a working phantomjs node-module:
https://github.com/amir20/phantomjs-node
var phantom = require('phantom');
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.open('https://stackoverflow.com/').then(function(status) {
console.log(status);
page.property('content').then(function(content) {
console.log(content);
page.close();
ph.exit();
});
});
});
});

Resources