In the previous section we saw the Express CLI tool used to create Express projects
express --view=pug myapp
This way of creating Express projects is best practice. It gives us a uniform project structure across projects making each project easy to navigate and maintain, thus resulting in fewer errors. Things out customers and users appreciate.
For personal as developers there are a couple of more steps involved in the creation of a good development environment fort each new project. Let us call it the Recipe. It goes like this:
express --view=pug <projectname>
cd <projectname>
npm install
git init
echo 'node_modules/' > .gitignore
git add .
git commit -m 'initial commit, Express installed, ready for own code'
These commands may be put into a script in your command line shell, if you wish.
When this has been done you have a work setup with skeleton project files, git initialized and initially committed. Thsi may be pushed into an empty repository created on Gitlab, Bitbucket, or Github, or similar services. You are close to being ready to code. One or two improvements for practical reasons.
The Express CLI wrote to you:
run the app:
$ DEBUG=demoproject:* npm start
Let us improve your package.json
slightly, so that it contains:
{
"name": "demoproject",
"version": "0.0.0",
"private": true,
"scripts": {
"pretest": "npm install",
"test": "DEBUG=demoproject:* NODE_ENV=development node ./bin/www",
"start": "DEBUG=demoproject:* NODE_ENV=production node ./bin/www"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"debug": "~2.6.9",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"morgan": "~1.9.1",
"pug": "2.0.0-beta11"
}
}
The lines 6, 7, and 8 have replaces what was in the
scripts object before.
Henceforth we may test the project with:
npm test
or we may run production with:
npm start
from the CLI.
Let us try
npm test > demoproject@0.0.0 pretest /home/nml/nodeProjects/nodejsexps/demoproject > npm install audited 54 packages in 0.663s found 0 vulnerabilities > demoproject@0.0.0 test /home/nml/nodeProjects/nodejsexps/demoproject > DEBUG=demoproject:* NODE_ENV=development node ./bin/www demoproject:server Listening on port 3000 +0ms
Notice the running of npm install. It runs because
of the pretest clause in scripts. If
we decide to run test, the pretest
kicks in just prior to that. Now we may
point our browser at the designated port.
Again, every Express application has an app.js
module configuring the application with various external
modules for use in the application. This external software
is attached to the app object which is the
shared.
The user of the app is the bin/www,
a JavaScript file that we don't edit directly.
With respect to the native Node.js we have worked with
so far, app.js, and bin/www are
two JavaScript files corresponding what we have called
main.js, and bin/server.js before.
We have seen the file structure from the early project above.
app.js Filevar createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
The bin/www is a JavaScript file in spite of the
lacking.js filename suffix. It is not
particularly interesting in that we do not edit it.
Now let us peep at the routing. There are two files, but for the time being, we are only interested in one of them
routes/index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;