trying to render two different pages using two different entry points webpack - node.js

My webpack is partitioned to produce two outputs...
entry: {
a: './src',
b: './Authentication'
},
devtool: 'source-map',
output: {
path:'/',
filename: 'scripts/[name].js',
publicPath: '/'
},
So one of my html file (login.html) will call...
<script type="text/javascript" src='scripts/a.entry.js'></script>
And the other (index.html) calls...
<script type="text/javascript" src='./scripts/b.js'></script>
Now each of these pages is a different route. Obviously index.html will be the main so in my server I did...
var path = require('path');
...
app.use(express.static(path.resolve('public')));
...
app.get('/', function(req, res){
res.sendFile(path.resolve('public/index.html'));
});
Everything renders find when I test it on local. But now I want to access the second login.html on a different route, I added this...
app.get('/login', function (req, res) {
res.sendFile(path.resolve('public/login.html'));
});
But when I go to localhost:3000/login I get this error...
GET http://localhost:3000/scripts/a.entry.js 404 (Not Found)
The output is not found. Why is this so???

You configured your bundle for login.html to be named “a”, not “a.entry”. Try changing your script tag to:
<script src='scripts/a.js'></script>
(you don't need type="text/javascript" anymore in 2016)

Related

How to return a 404 Not found page in an Express App?

I have an express app, in which I have the following code:
app.get('*', (req, res) => {
res.send('404', {
title: 404,
name: 'James Olaleye',
errorMessage: 'Page not found',
});
});
However, My IDE is warning about this message:
express deprecated res.send(status, body): Use
res.status(status).send(body) instead
And with the above code, My Browser is returning the following payload as a JSON object:
{
"title": 404,
"name": "James Olaleye",
"errorMessage": "Page not found"
}
What I want, is to display a 404 Not found page to the user, how can this be achived?
You have two seperate problem
1: you are using an old way to response to the request insted use this res.status(STATUS_CODE).send(BODY)
2: you are sending a json yet you want to display a 404 page in this case you need to send a html template
so your code should look like this
app.get('*', (req, res) => {
res.status(404).send("<div>404 Not Found</div>");
});
I updated your question a bit to make it clearer for future references.
the method res.send is deprecated, among other things because it's usages is too ambiguous. A server response, can be a lot of things, it can be a page, it can be a file, and it can be a simple JSON object (which you have here).
In your case, when you run res.send(404,{ /*...*/ }), the express app assumes you want to send a JSON object, so it does just that.
There are multiple possible ways, to achieve what you want, but I will stick to the most simple solution.
If you want to display an HTML page, in the most simplest form, you can actually just change your piece of code to do this instead:
app.status(404).send(`<h1>Page not found</h1>`)
This will essentially, show a page, instead of a JSON object.
You can even define the whole HTML file if you like:
app.status(404).send(
`
<html>
<!DOCTYPE html>
<head>
<title>404</title>
</head>
<body>
<h1>James Olaleye</h1>
<h1>Page Not Found</h1>
</body>
</html>
`
)
This would be the fastest way to achieve what you want.
A step further, would be to create an HTML file some where in your app, and to send the HTML file instead.
If your source code looks like this:
/
src/
index.js
htmls/
404.html
<!-- htmls/404.html -->
<html>
<!DOCTYPE html>
<head>
<title>404</title>
</head>
<body>
<h1>James Olaleye</h1>
<h1>Page Not Found</h1>
</body>
</html>
// src/index.js
const express = require('express');
const app = express();
const path = require('path');
const PORT = 3000;
app.get('/', function(req, res) {
const options = {
root: path.join(__dirname, '..', 'htmls')
};
res.sendFile('404.html', options, function (err) {
if (err) {
next(err);
} else {
console.log('Sent:', fileName);
}
});
});
This would allow you to have multiple HTML files which you can send around.
There are like I stated, other options as well, but that would make this answer way too long and out of scope. If you are interested, you can research Using template engines with Express and start with the following link.
Happy coding :)

react express Uncaught SyntaxError: Unexpected token <

I understand this error is not the reason for the failing. It is failing because in my index.html file i have:
<body><noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="text/javascript" src="/static/js/main.f4a49fba.js"></script>
</body>
That script tag src is failing and returning the same file contents as the index.html itself. This causes it to render HTML (hence < unexcpected from <!DOCTYPE html>).
I am trying to have both express server with /graphql and react together. The working solution is using express.static middlewear shown below. Problem is the working solution breaks the /graphql endpoint so I cannot return any data.
app.use(express.static(path.join(__dirname, 'client/build')));
I need to get this working so it first allows the previous enpoints (/graphql) before checking static pages so I am trying to use this:
app.get('*', (req, res) => {
res.sendFile('index.html', { root: path.join(__dirname, 'client/build/') });
});
This is successfully getting pulled back but failing to work because main.f4a49fba.js in the script tag does not want to load. I tried changing it to /client/build/static/js/main.f4a49fba.js but still wont load. This is using a build file for production.
UPDATE:
I replaced my code with below which helped but for some reason even though I have /graphql above this it is still being run when a full address is being run.
app.get('*', (req, res) => {
const link = (req.path == '/' ? 'index.html' : req.path);
const root = path.join(__dirname, 'client/build');
res.sendFile(link, { root: root }, (error) => {
if (error) {
res.sendFile('/', { root: root });
}
});
});
I am getting this now when a graphql request comes in which seems like it is missing the first /graphql and going to my updated function above. It is very strange and sticking the graphql full address at the end of whatever current page I am in.
http://localhost:3000/dashboard/accounts/my.herokuapp.com/graphql 404 (Not Found)

Creating HapiJs server that can serve complex web pages

I have just started learning Node.js and hapi.js. What I am trying to accomplish now is build a REST web server that should also have a web interface for configuration and statistics collection.
I found that Inert plugin allows serving static pages and, as I understand, this limits me to loading a single web page that consists of a single file.
However, what I do not understand is whether it is possible to setup hapi.js to serve a full dynamic webpage with css, js and other files referenced within its body.
Am I heading the wrong direction with this or else how can I setup my scenario?
You can serve multiple static files from a specified directory.
Just tried out inert with hapi, using this example:
https://github.com/hapijs/inert#static-file-server
Inert has no problem serving multiple static files from a given directory, e.g public.
So you'll have no issue serving multiple static html, css, js files from a specified dir. You can then build a dynamic JSON api using Hapi, and have that consumed by your js client-side code, served from static js files in your public dir.
If you are needing templating, where you generate dynamic content on the serverside, hapi can do that out of the box, check out:
http://hapijs.com/tutorials/views
Sorry if this isn't what you mean, do feel free to clarify if not :-)
Hope that helps!
The vision plugin is used for templating, which is what I think you're after. If you want to bundle css and js files along with your pages, you can put them in a public directory and serve that with the inert plugin. And then you only need to reference the relative path in whatever html file you're trying to render.
Here's a simple example that uses handlebars. Inert is responsible for serving your css and js files while vision still renders your templates.
./index.js
var hapi = require('hapi');
var server = new hapi.Server();
server.connection({port: 5555});
server.register([require('vision'), require('inert')], (err) => {
if(err){
throw err;
}
server.views({
engines: {
html: require('handlebars')
},
relativeTo: __dirname + '/',
path: 'www'
});
var homeroute = {
method: 'GET',
path: '/',
handler: (request, reply) => {
reply.view('index', {name: 'cuthbert'});
}
};
var publicassetsroute = {
method: 'GET',
path: '/public/{param*}',
handler: {
directory: {
path: './public',
listing: false,
index: false
}
}
};
server.route(homeroute);
server.route(publicassetsroute);
server.start((err) => {
console.log('server started -- ' + server.info.uri)
});
});
www/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hapi Test</title>
<link rel="stylesheet" href="../public/index.css">
</head>
<body>
<h1>A Hapi Happy Test.</h1>
<p>This is a test page. Woo!</p>
<p>My name is {{name}}.</p>
</body>
</html>
public/index.css
p {
color: blue;
}

Reloading browser for every routes ( Express + gulp + Browsersync )

I have build a simple express web server generated with express generator as follow:
express test -ejs
Everything is working fine so far and I have the following folder (with a few changes):
What I want to achieve now is that:
- for every file I'm working on in "/routes/*.js" and "./*.js", on save reload the server and the browser
- for every file in "/views" and "/public", on save only reload the browser
for that I have set up a gulp file.js with browser-sync in proxy mode as follow:
var server = require('gulp-develop-server');
var bs = require('browser-sync').create();
(some tasks for checking js and less ...)
var options = {
server: {
path: './bin/www',
execArgv: ['--harmony']
},
bs: {
proxy: {
target: 'http://localhost:5000',
middleware: function (req, res, next) {
console.log(req.url);
next();
}
},
files: ['./public/**/*', './views/*'], // files to watch with bs instantly (.ejs & .css)
logLevel: 'debug'
}
};
gulp.task('start', ['js','less'], function () {
server.listen(options.server, function (error) {
if (!error)
bs.init(options.bs);
});
gulp.watch('./less/*.less', ['less-nonstop']);
gulp.watch(['./*.js', './routes/*.js'], ['restart:forjs']);
gulp.watch('./views/*').on('change', bs.reload);
});
The proxy is working fine and every pages on http://localhost:3000 give me the same page as http://localhost:5000 (my express server is configured to listen on port 5000).
Now my problem is that browsersync doesn't always refresh my browser on reload (even if browser sync gets the reload event) in fact it refresh only when I'm on the first route path specified in app.js. For example if I have the following code in app.js:
app.use('/bonjour', routes);
app.use('/users', users);
Browser-sync will only reload the browser on http://localhost:3000/bonjour, but not on http://localhost:3000/users or any other paths. Even if browser-sync gets the reload event (as I can check in the console log). It seems that when I'm displaying any other pages than the first route specified in app.js my browser is like "disconnected" from browser-sync.
Why is that ? and How could I fix it ?
it seems that browser-sync need a proper html page render to work that's why it wasn't working on the other routes in this case. In fact my error.ejs file was just:
<h1><%= message %></h1>
<h2><%= error.status %></h2>
<pre><%= error.stack %></pre>
Correcting it to:
<!DOCTYPE html>
<html>
<body>
<h1><%= message %></h1>
<h2><%= error.status %></h2>
<pre><%= error.stack %></pre>
</body>
</html>
solved the problem and now the browser sync works on every html pages.

Express | Routing is messing up css

I ran into a problem I couldn't find an answer for.
I'm using Express for my website's framerwork and I'm using its routing but it seems to mess up links and files attached to a page.
Here is what I use :
app.get('/profile/:name/:age', function(req, res) {
var name = req.params.name;
var age = req.params.age;
someFunction(name, age, function(error, profile) {
res.render('userprofile', profile);
});
});
The page renders but the links are broken, instead of going to example.com/css/main.css it goes to example.com/profile/(whatever name I went to)/css/main.css so this returns html instead of the css file. Same things for my links.
Note that I can show up that, with css enabled, no problem :
app.get('/profile', function(req, res) {
res.render('userprofile');
});
Sounds like you're using relative url's for your CSS:
<link rel="stylesheet" href="css/main.css">
If the current (page) url is /profile/username/, that translates to:
/profile/username/css/main.css
Solution? Use absolute url's for resources and links:
<link rel="stylesheet" href="/css/main.css">

Resources