I'm following a NodeJS tutorial on how to render an HTML page, but I can't seem to make it work. I installed all of the requirements and use the --save
option so it's inside my node_modules
folder. After I do npm start
and visit my localhost
, this is the error message I get:
Error: No default engine was specified and no extension was provided.
at new View (C:\Users\Billy\NodeJSProjects\HelloWorld\node_modules\express\lib\view.js:62:11)
at EventEmitter.render (C:\Users\Billy\NodeJSProjects\HelloWorld\node_modules\express\lib\application.js:570:12)
at ServerResponse.render (C:\Users\Billy\NodeJSProjects\HelloWorld\node_modules\express\lib\response.js:966:7)
at app.get (C:\Users\Billy\NodeJSProjects\HelloWorld\app\index.js:25:12)
at Layer.handle [as handle_request] (C:\Users\Billy\NodeJSProjects\HelloWorld\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Billy\NodeJSProjects\HelloWorld\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\Billy\NodeJSProjects\HelloWorld\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\Billy\NodeJSProjects\HelloWorld\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\Billy\NodeJSProjects\HelloWorld\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\Billy\NodeJSProjects\HelloWorld\node_modules\express\lib\router\index.js:335:12)
./index.js
require('./app/index')
const path = require('path')
const express = require('express')
const exphbs = require('express-handlebars')
const app = express()
app.engine('.hbs', exphbs({
defaultLayout: 'main',
extname: '.hbs',
layoutsDir: path.join(__dirname, 'views/layouts')
}))
app.set('view engine', '.hbs')
app.set('views', path.join(__dirname, 'views'))
./app/index.js
const express = require('express')
const app = express()
app.use((request, response, next) => {
console.log(request.headers)
next()
})
app.get('/', (request, response) => {
response.render('home', {
name: 'John'
})
})
app.get('/', (request, response) => {
throw new Error('oops')
})
app.use((err, request, response, next) => {
// log the error, for now just console.log
console.log(err)
response.status(500).send('Something broke!')
})
app.listen(3000)
(auto-generated) package.json
{
"name": "name-first-nodejs-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "mocha test",
"your-custom-script": "echo npm"
},
"author": "",
"license": "ISC",
"dependencies": {
"async": "^2.3.0",
"express": "^4.15.2",
"express-handlebars": "^3.0.0",
"handlebars": "^4.0.6",
"lodash": "^4.17.4",
"promise-async": "^0.2.0"
},
"devDependencies": {
"mocha": "^3.3.0"
}
}
./views/layouts/main.hbs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Express handlebars</title>
</head>
<body>
{{{body}}}
</body>
</html>
./views/home.hbs
<h2>Hello {{name}}</h2>
You are making two separate app
objects and configuring handlebars on one of them and configuring your routes on the other one. Thus, the one with your routes is not configured for handlebars. You need to have only one app
object that you share between your two modules. You can export it from one and import that module into the other or pass the app
object to the other with a module constructor or a method after you've loaded the module to get access to the single shared app
object from the other module.
For example:
./index.js
const path = require('path');
const express = require('express');
const exphbs = require('express-handlebars');
const app = express();
app.engine('.hbs', exphbs({
defaultLayout: 'main',
extname: '.hbs',
layoutsDir: path.join(__dirname, 'views/layouts')
}));
app.set('view engine', '.hbs');
app.set('views', path.join(__dirname, 'views'));
// now that handlebars is configured,
// configure all our routes on this app object
require('./app/index')(app);
./app/index.js
module.exports = function(app) {
app.use((request, response, next) => {
console.log(request.headers);
next();
});
app.get('/', (request, response) => {
response.render('home', {
name: 'John'
});
});
app.use((err, request, response, next) => {
// log the error, for now just console.log
console.log(err)
response.status(500).send('Something broke!')
});
app.listen(3000);
};