serving a Single Page Angular App using Restify - node.js

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

Related

How does express know this routing?

I create a simple express server and serve the static files
const express = require('express');
const app = express();
app.use(express.static('public'));
app.listen(3000, () => {
console.log('Listening on port 3000')
})
When I head to localhost:3000, the index.html in my public directory renders for the route ' / '. I didn't explicitly write the route in my index.js file. How does express know this?
I've tried changing the file name from index.html to random.html and I get an error. CANNOT GET /
As mentioned in the comments, app.use(express.static('public')) is responsible for this. This will essentially serve all files in the public folder you have in the project. If you have an index.html in the public folder, then that will be served at the / endpoint automatically. This is a convention that most websites follow, and is documented in this SO post.
Here is the relevant documentation on express.static(...): https://expressjs.com/en/starter/static-files.html

Why I'm getting a blank page from running a node server that point to the /dist folder of an Angular app?

My simple node server is:
const express = require('express');
const app = express();
app.get('*', (req, res) => {
res.sendFile(__dirname + '/dist/page/index.html');
})
app.listen(3335, () => { console.log('Server is listening on 3335'); });
But I'm getting the index file that seems not running the main.js
The Angular app, at the moment it's literally a page/component that is app.component.ts, so there is not any routing.
Use express.static() for serving static files.
It is because you have set a response of 'index.html' file for each and every request the server would receive. The first response would be good that's the index.html page only as expected. But, the index.html page must be having some script and css tags to fetch your Angular Javascript code which I assume would be on the same node server. So when the browser would encounter a line like:
<script src="/angularApp.js"></script>
..in your index.html file while parsing it, it would make another request to the node server for http://localhost:<port>/angularApp.js but would get the index.html file as the response as that is what you have set.
Do it like this to serve static files like .html, .css, .js or what have you:
app.use(express.static(path.join(__dirname, '/dist')));

Angular 2 'app-root' not loading on ExpressJS route

Im new to NodeJS and Express but i want a simple '/' route to Angular's default index.html (client/src/index.html) which contains the app-root tag.
The '/' route successfully serves the index.html file but it doesn't expand/load the 'app-root' tag into the component's html so i just get blank page.
Im not sure why it cant resolve the app-root tag when routed from Express. Only if i run Angular by 'ng serve' does the index.html successfully load the contents of the app-root tag.
My structure is as follows:
/client
/e2e
/node_modules
/app
app.component.css/html/ts
app.module.ts
/src
index.html
main.ts
package.json
server.js
server.js
var express = require('express');
var path = require('path');
var port = 80;
var app = express();
// set static folder
app.use(express.static(path.join(__dirname, '/client')));
app.get('/', function(req, res, next){
res.sendFile(__dirname + '/client/src/index.html');
});
app.listen(port, function(){
console.log("Server started on port " + port);
});
It look like you didn't do 'ng build' your angular app because main.ts is still there.
When you do the 'ng serve', angular compiles and serve it using webpack-dev-server.
If you want to serve your app from the your node as static, you need a compiled angular app.
You can do the following
$ cd client && ng build
There will be client/dist directory created where your compiled angular app is located and you can serve that on your express
You can change the directory in you server.js like below
app.use(express.static(path.join(__dirname, '/client/dist')));
res.sendFile(__dirname + '/client/dist/index.html');
Hope this helps

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

AngularJS , Node.js, ExpressJS application integration issue

I have created a RESTful service using Node.js and ExpressJS. Now I would like to implement View part. For this I have chosen AngularJS.
Problem here is, I am not sure how to organize folder structure and how to integrate AngularJS with Node.js and ExpressJS.
I watched this video, but for this no sample source code available.
Let's Get CRUDdy: AngularJS and Node.js Ferrari Example
Project folder structure
ExpressJS file
var express = require('express'),
http = require('http'),
path = require('path'),
photos = require('./routes/photos');
var app = express();
app.configure(function () {
app.use(express.logger('dev')); /* 'default', 'short', 'tiny', 'dev' */
app.use(express.bodyParser());
app.use(app.router);
});
app.get('/photos', photos.findAll);
app.get('/view1', photos.index);
AngularJS:
// Declare app level module which depends on filters, and services
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
When I hit url http://www.domain/view1, it should display index.html. But I am getting 404 code.
Please let me know if you need more info on it.
If you're using AngularJS to implement a single-page experience then you should serve the same front-end code every time, and then have AngularJS take over processing the URLs and displaying the content.
Remember that you are managing two routing systems. One for the front-end and one for the backend. Express routes map to your data, usually returned in JSON format. (You can also render html directly, see Option #1.) Angular routes map to your templates and controllers.
Option #1:
Set static folder to serve front-end code (HTML/CSS/JS/AngularJS).
app.use(express.static(__dirname + '/public'));
Look at these for sample code:
https://github.com/btford/angular-express-seed
https://github.com/btford/angular-express-blog
Directory Structure:
public/
index.html
js/
angular.js
css/
partials/
partial1.html
partial2.html
app/
node_modules/
routes/
web-server.js
Option #2:
Serve the front-end code and backend code on separate servers.
This doesn't mean you have to have two machines.
Here is a workable set up on your local machine with Apache:
Directory Structure:
public/
index.html
js/
angular.js
css/
partials/
partial1.html
partial2.html
node/
app/
node_modules/
routes/
web-server.js
Set up hosts file
127.0.0.1 domain.dev
Set up http://domain.dev/ to point to public/
<VirtualHost *:80>
DocumentRoot "/path/to/public"
ServerName domain.dev
ServerAlias www.domain.dev
</VirtualHost>
Set up http://api.domain.dev/ to point to the running node web-server
<VirtualHost *:80>
ServerName api.domain.dev
ProxyPreserveHost on
ProxyPass / http://localhost:3000/
</VirtualHost>
(Adapted from: http://www.chrisshiplet.com/2013/how-to-use-node-js-with-apache-on-port-80/)
Start (or restart) Apache and run your node server:
node web-server.js
Angular Routes:
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives',
'myApp.controllers'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
index.html:
<!DOCTYPE html>
<html>
<head><title>Angular/Node exmaple</title></head>
<body>
<div id="main" ng-view></div>
</body>
</html>
Express Routes:
app.get('/', photos.index);
app.get('/photos', photos.findAll);
Access these routes in an Angular controller via $http or $resource service:
$http.get('http://api.domain.dev/photos').success(successCallback);
Additional Resources:
https://github.com/ithkuil/angular-on-server/wiki/Running-AngularJS-on-the-server-with-Node.js-and-jsdom
http://briantford.com/blog/angular-express.html
https://stackoverflow.com/a/10444923/243673
I had an existing angular project with a file structure like this (roughly):
/
app/
img/
scripts/
styles/
templates/
index.html
test/
I just created a new express app, and copied the contents of my app directory over to the /public directory in express, after removing all the existing content from /public
Then in the app.js file in express I did the following changes to the default config:
var express = require('express');
var routes = require('./routes');
// ** required my route module
var menu = require('./routes/menu');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
// ** I moved this above the app.router line below, so that static routes take precedence
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
// ** removed the default index route
// app.get('/', routes.index);
// ** defined my route
app.get('/api/menu', menu.list);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Then obviously wrote my route file in express and changed the URL in the angular service to use the new api.
Also there was more work involved deciding where to put the specs and also merging the bower and node dependancies etc but that is probably too specific to my situation to include with this answer but happy to share if anyone might find it useful.

Resources