Restructing app into server-side & client-side containers - node.js

What I'm trying to achieve is splitting up app.js in separate pieces. That's so far successful. My structure looks like this so far:
package.json
app.js
app/
- server/
- views/
- router.js
- public/
- css/
- images/
- js/
- robots.txt
Sounds good? Inside my app.js I have the following code:
http.createServer(app).listen(app.get('port'), function() {
console.log("app:" + app.get('port') + " running through express server.");
})
I feel that my http:createServer is so little and so vulnerable that I want to extend it. Is there a way to put it inside ./app/server/http.js and include the toobusy module (that, with the examples seems too hard for me).
Is there a solution?

If I understand your question correctly, all you need to do is create a app/server/http.js file and place this code inside:
var toobusy = require('toobusy'),
app = require('../../app');
var server = http.createServer(app);
server.listen(app.get('port'), function () { ... });
process.on('SIGINT', function() {
server.close();
// calling .shutdown allows your process to exit normally
toobusy.shutdown();
process.exit();
});
Then you can do one of two things:
1) Inside your package.json file, set the main field to app/server/http.js and you can start your app with npm start if thats your thing.
2) The other option (preferred, IMO) is to create an index.js file in the root of your project that looks something like:
module.exports = require('app/server/http');
And then you can simply start your server with
$ NODE_ENV=production node /path/to/project <arguments go here>
Either way, you'll get the benefits of toobusy while achieving the separation you desire.

Related

deploy module to remote server that is running node.js

I'm working on my app.js in node.js
-- trying to deploy server-side script.
Many fine node.js modules need a require('something');
I use NPM locally, which works for require, as modules are nicely visible in the local node_modules folder structure. but now I'm ready to upload or bundle to a host. I can't run npm on this hosted server.
const Hapi = require('hapi');
will result in
Error: Cannot find module 'hapi'
because I don't know how to copy/install/bundle/ftp files to my host.
Hapi is just an example. Most anything that has a require will need something on the host.
I used webpack to create a server side bundle.js but just sticking bundle.js under /node_modules doesn't do anything.
Most modules have a complex folder structure underneath --- I'm trying to avoid copying a ton of folders and files under /node_modules. Ideally, I want to combine the modules into a bundle.js and have those modules visible to app.js
but I am open to other ideas.
I have not yet tried using webpack to bundle app.js TOGETHER with the various modules. Have you had luck with that approach?
thanks.
I've tried to upload hapi files a folder-ful at a time, reaching a new require('something') error at every step.
'use strict';
const Hapi = require('hapi'); // <-- how can I deploy hapi on my node.js server?
// Create a server with a host and port
const server=Hapi.server({
host:'localhost',
port:8000
});
// Add the route
server.route({
method:'GET',
path:'/hello',
handler:function(request,h) {
return'hello world';
}
});
// Start the server
async function start() {
try {
await server.start();
}
catch (err) {
console.log(err);
process.exit(1);
}
console.log('Server running at:', server.info.uri);
};
start();
one approach that worked: using webpack to bundle the back end js.
thanks to
https://medium.com/code-oil/webpack-javascript-bundling-for-both-front-end-and-back-
end-b95f1b429810
the aha moment... run webpack to create bundle-back.js then
tie bundle-back.js to my node server
**You start your backend server with ‘bundle-back.js’ using:
node bundle-back.js
In other words, include app.js in the bundle with the modules.

Cannot get correct static files after refreshing except index page

When I refresh page on index route (/) and login page (/login), it works fine.
However, my website gets error as I refresh on other routes, for example /user/123456.
Because no matter what the request is, the browser always gets HTML file.
Thus, both of the content in main.css and main.js are HTML, and the browser error.
I have already read the README of create-react-app.
Whether I use serve package ($serve -s build -p 80) or express, it will produce the strange bug.
Following is my server code:
//server.js
const express = require('express');
const path = require('path');
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', (req, res) => {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
const PORT = process.env.PORT || 80;
app.listen(PORT, () => {
console.log(`Production Express server running at localhost:${PORT}`);
});
Edit: I have figured out where caused the problem.
I created a new project, and compared it to mine. The path of static files in the new project is absolute, but in my project is relative.
As a result, I delete "homepage": "." in the package.json.
//package.json
{ ....
dependencies:{....},
....,
- "homepage": "."
}
Everything works as expected now. How am I careless...
I have figured out where caused the problem.
I created a new project, and compared it to mine. The path of static files in the new project is absolute, but in my project is relative.
As a result, I delete "homepage": "." in the package.json.
//package.json
{ ....
dependencies:{....},
....,
- "homepage": "."
}
Everything works as expected now. How am I careless...
If your route /user/** is defined after app.get('/*', ... it might not match because /* gets all the requests and returns you index.html.
Try without the * or declare the other routes before.
First, I thought you misunderstood the server part. In your case, you use serve as your server. This is a static server provided by [serve]. If you want to use your own server.js, you should run node server.js or node server.
I also did the same things with you and have no this issue. The followings are what I did:
create-react-app my-app
npm run build
sudo serve -s build -p 80 (sudo for port under 1024)
And I got the results:
/user/321
I guessed you might forget to build the script. You can try the followings:
remove build/ folder
run npm run build again
Advise: If you want to focus on front-end, you can just use [serve]. It will be easy for you to focus on what you need.

Webpack + Express: How to serve static resources in /node_modules from the server

I am trying to use webpack to generated a bundle.js file for a node module. The bundle.js file will be used in the client browser.
Here is the problem, the project has some dependencies that use static files in the node_modules directory. For example, the path of one of the static file is
/node_modules/node-pogo-signature/lib/proto/Signature.proto
When I try to run the bundle.js file in the browser, I get this error
GET http://localhost:3000/proto/Signature.proto 404 (Not Found)
If I copy the the Signature.proto file into my /public folder, the bundle will then find it. However, manually copying static files from /node_modules to /public can be tedious and hard to maintain.
Is there a better way to do it?
var myfile = require('./node_modules/node-pogo-signature/lib/proto/Signature.proto');
Then you may add it to a route, for example if you use express this is how you can display the content of the package.json file:
// create a new express server
var express = require('express'); // We use express as web server http://expressjs.com
var app = express();
// serve the files out of ./public as our main files
app.use(express.static(__dirname + '/public'));
// start server on the specified port and binding host
app.listen(appEnv.port, '0.0.0.0', function() {
console.log("server started");
});
// Shows content of package.json
var myfile = require('./package.json');
app.get('/showfile', function (req, res){
if (debug) {
console.log("showfile received a request");
};
res.send(myfile);
});
You just have to add /showfile at the end of the url , for example : http://localhost:6006/showfile

Unable to get connect-livereload to work with express server in gulp task

I am working off of Yeoman's gulp-webapp generator. I have modified my gulp serve task to use my Express server, rather than the default connect server it ships with. My issue is with Livereload functionality. I am trying to simply port the connect-livereload to work with my Express server rather than having to install new dependencies. It's to my understanding that most connect middleware should work fine with Express, so I am assuming connect livereload is compatible with Express 4.
Here are the contents of the relevant tasks in my gulpfile:
gulp.task('express', function() {
var serveStatic = require('serve-static');
var app = require('./server/app');
app.use(require('connect-livereload')({port: 35729}))
.use(serveStatic('.tmp'));
app.listen(3000);
});
gulp.task('watch', ['express'], function () {
$.livereload.listen();
// watch for changes
gulp.watch([
'app/*.ejs',
'.tmp/styles/**/*.css',
'app/scripts/**/*.js',
'app/images/**/*'
]).on('change', $.livereload.changed);
gulp.watch('app/styles/**/*.css', ['styles']);
gulp.watch('bower.json', ['wiredep']);
});
gulp.task('styles', function () {
return gulp.src('app/styles/main.css')
.pipe($.autoprefixer({browsers: ['last 1 version']}))
.pipe(gulp.dest('.tmp/styles'));
});
gulp.task('serve', ['express', 'watch'], function () {
require('opn')('http://localhost:3000');
});
With this simple setup, when I run gulp serve in my cmd everything spins up fine and I can accept requests at http://localhost:3000.
Now if I go and change the body's background color from #fafafa to #f00 in main.css and hit save, my gulp output will respond with main.css was reloaded, as seen in the bottom of this screenshot.
However, my webpage does not update. The background color is still light-grey instead of red.
Is there perhaps a conflict between my express server config and the way gulp handles its files? Is my Express server forcing the use of app/styles/main.css rather than the use of .tmp/styles/main.css? Shouldn't the livereload script handle the injection of the new temporary file?
Thanks for any help.
EDIT:
I was able to move forward a bit by adding livereload.js to the script block of my index file, like so:
<script src="http://localhost:35729/livereload.js"></script>
I am now able to get live changes pushed to the client. Why was this file not getting injected before? How can I ensure this is getting used programatically as opposed to pasting it into my files?
I was able to get past this issue by removing the app.use(require('connect-livereload')({port: 35729})) from my gulpfile, along with a couple of other lines, and having that instantiate in my Express server's app.js file.
My gulpfile's express task now looks like this:
gulp.task('express', function() {
var app = require('./server/app');
app.listen(3000);
});
I added in the connect-livereload just above where I specify my static directory in Express:
if (app.get('env') === 'development') {
app.use(require('connect-livereload')());
}
app.use(express.static(path.join(__dirname, '../app')));
Once I started using this setup, I was getting the livereload.js script injected into my document, and client-side changes are now auto-refreshed just how I wanted.
Hope this helps someone!

serving a Single Page Angular App using Restify

I am new to AngularJs and wanted to start learning it. I was going to use Restify as my api/backend and was hoping it was possible to serve static files up for the route /.
app layout is something like this..
/nodesprinkler
node_modules/
public/
css/
main.css
bootstrap.css
js/
angular.js
app.js
...
img/
...
index.html
favicon.ico
server.js
routes.js
...
My server.js looks like so:
var restify = require('restify'),
app = module.exports = restify.createServer();
app.listen(8000, function() {
console.log('%s listening at %s', app.name, app.url);
});
/* Client Side Route */
app.get('/', restify.serveStatic({
directory: 'public',
default: 'index.html'
}));
module.exports.app = app;
routes = require('./routes');
How can i get Restify to serve up my static assets so it'll work like a regular express app works? I know restify is based off express, so there must be something simple that i'm missing. It will serve up / as index.html but any of my css and js files I dont have access to.
try express.static()
before app.listen put
app.use(express.static(__dirname+"/public"))
The docs
Try this:
app.get("/css|js|img/", restify.plugins.serveStatic({
directory: "./public"
}));
app.get(
"/.*/",
restify.plugins.serveStatic({
directory: "./public",
file: "index.html"
})
);
I'm creating my futur startup with the same technologies: Restify (that I rewrite) and Angular JS for the single app view.
I've tried of lots of solutions and the best one for me is :
Keep a WS with Restify (or what you want) WITHOUT any static files... I serve it with a dedicated server (python for dev, NGinx for production).
I know this is not the expected answer but give it a try.
python -m http.server on your angular directory is so simple :p

Resources