Search code examples
javascriptnode.jsexpresshandlebars.js

Javascript file isn't loading on local host


I am just learning express and I tried to create a simple webpage on localhost:3000. I created a text box with a submit button, which on click will get the text element inside the text box and print it on the console.

My node.js code is:

const express = require('express')
const path = require('path')
const hbs = require('hbs')

const app=express();

app.set('view engine', 'hbs');
const dir= path.join(__dirname,'../templates/views');
const partials=path.join(__dirname,'../templates/partials')
app.set('views',dir);
hbs.registerPartials(partials);

app.get('', (req, res) => {
    res.render('test')
});

app.listen(3000, () => {
    console.log(`Server started on port`);
});
 

The test.hbs file code is:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
     {{>header}}
    <form class="form">
        <input type="text" placeholder="Write here" class="textbox">
        <input type="submit" class="btn">
    </form>
    <script src="./test.js"></script>
</body>
</html>

And the javascript code is

const values={
    nodeForm:document.querySelector('.form'),
    nodeText:document.querySelector('.textbox'),
    nodeBtn:document.querySelector('.btn')
}

values.nodeForm.addEventListener('submit',e=>{
    e.preventDefault();
    console.log(nodeText.value)
    
})

But when I open up the localhost:3000, the console page gives me an error, saying GET http://localhost:3000/test.js net::ERR_ABORTED 404 (Not Found)

Edit: Javascript works fine if I put scripts inside the script tag present in the test.hbs file


Solution

  • Lets explain futher what is happening when you create a node server such as yours.

    When you start it (with app.listen()) the server will listen for incoming request and return an awnser.

    If you try to access 'localhost:3000/dumb' the navigator request your server asking him for '/dumb' route. As it dosn't exist, the server awnser a 404 error.

    If you now try to access 'localhost:3000/' the server find a route, execute your callback ((req, res) => res.render('test')) and in this callback you use Handlebar to generate an html page which is send to the navigator.

    Then the navigator get the HTML, parse it and find several links (like <script src="./test.js"> but also <img href="./myimage.png"> or <stylesheet href="./style.css">) To be able to fully render the page, the navigator will request each link it found to get the associated ressources.

    So in your case the navigator send one more request to 'localhost:3000/test.js' and as in my first dumb example the server awnser that it doesn't know this route.

    You could create a route for each ressource (app.get('./test.js', /*...*/) with a callback sending back the correct ressource. But as those file are just static (doesn't need any computation), the most common way to solve it is to make them available staticly. That means saying to your app "this folder is full of static file, juste serve them".

    As i said you can just create a 'public' folder and tell your app it contains static files : app.use(express.static('./public')); Of course './public' being a correct path from your root app (where package.json and node_modules is).

    But then, every files and folders in this folder become a reachable route. So if you have a 'js' folder in it, and later you want to create an app.get('/js', /*...*/) route you will have a conflict.

    So the common way is to serve this folder under a route. For example app.use('/static', express.static('./public')); will make everything under './public' folder available under '/static' routes. In your case 'localhost:3000/static/test.js'.

    I hope this is more clear, sorry for the poor english, this is not my native language.