Serve both static and apis in express in production - node.js

I have deployed a express/vue app to production.
I'm finding a bit difficult to serve both static files and APIs from express.
Inside expressfolder/app.js
const app = express()
const path = require('path')
const serveStatic = require('serve-static')
...
// index.html and static/css, static/js - bundle made with npm run build
const DIR_DIST = path.join(__dirname, '../../path/to/dist')
app.use(serveStatic(DIR_DIST))
...
app.get('/tests', (req, res) => {
res.send({msg: 'Hello there!'})
})
When i go to myapp.com, I see the index.html as desired.
If I type directly in the browser myapp.com/tests I see the raw msg "hello there" from express.
If i call the same route via the link inside index.html, I receive this error in chrome
(failed) net::ERR_CONNECTION_REFUSED
It's working on my local machine, so I'm sure it's some kind of messy config I haven't set properly.
Also, I don't want to be able to access /tests directly: vue-router should override that, but it's a lesser problem.
It's probably been asked before, but it's been a while and I haven't found a solution yet.
Thanks.

The error ERR_CONNECTION_REFUSED is a fundamental networking error that occurs before your server code actually gets to run so that would likely have nothing to do with your specific server code.
It probably happens because you have a bad URL in your web page.

Related

Is it possible to host web page with angular.min.js functionality using nodes http module

Is it possible to host web page with angular.min.js functionality using nodes http module?
I'm making a really simple web project that is going to fetch some data and I decided to use angular.js to display data no the page. I tried to read index.html using fs module and sent it as response to the localhost. It seems that angular.min.js, that was included in the pages head section did not load as it would when I run the page in the browser from the file explorer.
angular is a web application, so, please serve the angular using your node.js server and load the app in the web browser.
add a listener of get then send all files that index.html need, it is done.
or use app.use(express.static('public')); which public is your 'public' folder, put all file in dist to serve as a static content.
I use the first option every time but it is trick but functional.
sample code is:
const express = require('express');
const router = express.Router();
const path = require('path');
router.get('/:id',(req,res)=>{res.sendFile(path.join('/path/to your/file/'+req.params.id));});
router.get('/',(req,res)=> res.sendFile(path.join('/path/to/your/file/index.html'));});
module.exports = router;

Using Mixpanel - Node Library in Express

I am currently trying integrate the Mixpanel Node library into a test application that I am building. This is a Node.js application using the express framework.
As per the express docs, I have a JS file to manage the project, a folder called "public" that contains all of my static files, and another folder with the node modules that come with express.
I have two static HTML pages in "public" that I am trying to put mixpanel tracking into. I am running the project locally by running node app.js.
app.js includes:
const express = require('express');
const app = express();
const port = 3000;
const path = require('path');
//Mixpanel Additions
var Mixpanel = require('mixpanel');
var mixpanel = Mixpanel.init('<I am putting my project token here>', {
protocol: 'https'
});
//App Configuration and Init
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/public/page.html'));
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
In my HTML files I try to use mixpanel functions by putting them into script tags:
<script>
mixpanel.track("event")
</script>
But when I run node app.js and view the page in my browser it says:
Uncaught ReferenceError: mixpanel is not defined
I have a pretty poor understanding of node.js, but I am imagining that I need to use app.use(), app.get(), or something along those lines to get the Mixpanel lib loaded into the app. What am I doing wrong? I also realize that my understanding of Express and Node is pretty rudimentary, so any additional knowledge is appreciated, especially if I am way off.
If you want to call mixpanel tracking functions in the browser, you should load the mixpanel library in a script tag on the browser side, as seen here:
https://developer.mixpanel.com/docs/javascript
The purpose of the node.js package is to send events from the server side, like if you wanted to log when page.html is rendered, you could do
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/public/page.html'));
mixpanel.track('event')
});

How to create a node based server to serve REST API and also deploy the application.

I am new to nodeJS server area, need help in understanding how to work with REST API (using express) and deploy the angular application over a singe node server and same ports.
By deploying i want to understand if user hit below url http://localhost:8000/<page_name> then the specified page should open.
And is user hit below url using get or post request
http://localhost:8000/api/<api_name> then a json or a text will be returned.
How to run both the thing over a single node server.
Lets assume, you have all your static files in the /public folder of you app. Generally spoken, if you are using express.static, you should also get your index.html because this is handled by default for each directory.
In your case, as you are using Angular, the routing is handled from the client side (SPA). You should only have one single index.html after building your Angular app. All files from your dist folder should then be placed into your /public folder. Then you need to make sure, that initial file serving provides your index.html like so:
In this example static files are served first, then your API and if nothing is found, you are getting back you index file.
const express = require('express');
const app = express();
// serve static files
app.static(__dirname + '/public'));
// serve your API
app.get('/api/welcome', function (req, res) {
res.send('Welcome');
});
// fallback routing (server side handling)
app.get(/.*/, function (req, res) {
res.sendFile(__dirname + ‘/public/index.html‘
});
app.listen(3000);
Next time please make sure, to give all necessary information in your question ;-)
With the help from Sebastian, so far I can find a solution but its not working when i am hitting URL for different pages.
const express = require('express');
const app = express();
app.use(express.static('public'))
Please provide your suggestions.

ExpressJS static file serve always serves the same file

I have a expressJs setup which looks like this:
// Imports...
const app: express.Application = express();
const port: number = 3001;
const listener = new StatementListenerAPI();
app.use('/listen', listener.getRouter());
app.use('/welcome', router);
if (fs.existsSync('./client')) {
// Running in prod environment with pre built client directory. Serve this.
app.use(express.static('./client'));
}
app.listen(port);
So I have some routers connected to the express app, and at the bottom I declare that the directory client should be served statically. This directory contains an index.html as well as lots of JS, CSS and PNG files. However, no matter which URL I try to access from the express server, it always shows the code of the index.html within the statically served directory. The references to the JS and CSS files used inside the index.html also just return the code of the index.html.
I am using ExpressJS 4.16.3
What am I doing wrong?
Edit: So technically it works if using __dirname + '/client' instead of ./client. What I am now getting is that, when making GET requests from e.g. Postman (therefore "hand-crafting" the HTTP requests), I am always getting the correct results. If I call the resources from within my web browser, it still always shows the website (resolves the index.html). However, now all resources like JS and CSS scripts are being resolved properly, so apperantly Chrome resolves those dependencies properly, I am just wondering why I am still getting the contents of index.html as result when requesting some of the assets or some of the express endpoints via Chrome. API calls via code are working fine, so its only why manual chrome requests show this weird behaviour, at this point I am only asking out of curiosity.
Answer to your original question:
The path supplied to express.static should be relative to the directory from where you launch your node process or an absolute path. To be safe construct an absolute path (ie from the current directory or file). For example:
app.use(express.static(__dirname + '/client'));
Regarding your followup question:
I assume this is because Chrome uses heavy caching and it thinks this folder should return the html file. You can try and reset all caches in Chrome, or just for the page.

Can't see console.log in routes.js using node webkit and express

I am developing a desktop app using node webkit and express. I use sublime build system to debug. I can see client pages log. But in routes I can't see any logs or alert message in sublime console, cmd console and nodewebkit devtool.
app.post('/', function(req, res) {
console.log('Hello');
// my code
});
I am sure it's hit since my page is rendered. Sorry I am new to node-webkit. Thanks for help
It sounds like your routes file isn't being hit. Try including the following in your app.js:
var router = express.Router();
var routes = require('./app/routes.js'); //the path to your routes file
router.use('/',routes);
Also in your routes file you will need a few requires:
var express = require('express'),
app = express().Router();
As far as debugging, I use node-inspector, you can install it via npm install node-inspector. They have instructions on their page of how to use it, but it's basically similar to a Chrome inspector console, you should set a breakpoint on your route function, to see if it's being triggered.
This is documented on the Express page under the express.Router() section at the bottom of the page, you will need to include the Router function in your call to break out your routes into a different file
If that doesn't work, you can post more of your code and we can try to help out.

Resources