CLI - Express.js Guide: The Comprehensive Book on Express.js (2014)

Express.js Guide: The Comprehensive Book on Express.js (2014)

CLI

Comparable to Ruby on Rails and many other web frameworks, Express.js comes with a command-line interface for jump-starting your development process. The CLI generates a basic foundation for the most common cases.

If you followed the global installation instructions in the Installation chapter, you should be able to see the version number if you run the $ express -V form anywhere on your machine. If we type $ express -h or $ express --help, we’ll get the list of available options and their usage:

To generate a skeleton Express.js app, we need to run a terminal command: express [options] [dir|appname] where options are:

· -s or --sessions adds session support

· -e or --ejs adds EJS engine support, by default Jade is used

· -J or --jshtml adds JSHTML engine support, by default Jade is used

· -H or --hogan adds hogan.js engine support

· -c <engine> or --css <engine> adds stylesheet <engine> support (e.g., LESS or Stylus), by default plain CSS is used

· -f or --force forces app generation on non-empty directory

If the dir/appname option is omitted, Express.js will create files using the current folder as the base for the project. Otherwise, the application will be under the specified directory.

For the sake of experimenting, let’s run this command: $ express -s -e -c less -f cli-app. Here is what will be generated:

The result of running `$ express -s -e -c less -f cli-app`.

The result of running $ express -s -e -c less -f cli-app.

As you can see, Express.js provides a robust command-line tool for spawning boilerplates rapidly. The downside is that this approach is not immensely configurable, e.g., it’s possible to use a Handlebars template engine (and many others) creating apps manually, not just Hogan, Jade, JSHTML or EJS provided by CLI.

Let’s briefly examine the application structure. We have three folders:

1. public for static assets

2. views for templates

3. routes for request handlers

The public folder has three folders on its own:

1. images for storing images

2. javascripts for front-end JavaScript files

3. stylesheets for CSS or in our example LESS files (the -c less options)

Open the main web server file app.js in your favorite text editor. We’ll briefly go through the auto-generated code and what it does before diving deeper into each one of those configurations later in the book.

We include module dependencies:

1 var express = require('express');

2 var routes = require('./routes');

3 var user = require('./routes/user');

4 var http = require('http');

5 var path = require('path');

Create the Express.js app object:

1 var app = express();

Define configurations. You can probably guess their meaning based on their names, i.e., instruct app about a web server port number, and where to get template files along with what template engine to use. More on these parameters in the Configuration chapter of The Interface part.

1 app.set('port', process.env.PORT || 3000);

2 app.set('views', __dirname + '/views');

3 app.set('view engine', 'ejs');

Define middlewares (more on them later in the book) to serve favicon, log events, parse request body, support old browsers’ HTTP methods, parse cookies and utilize routes:

1 app.use(express.favicon());

2 app.use(express.logger('dev'));

3 app.use(express.bodyParser());

4 app.use(express.methodOverride());

5 app.use(express.cookieParser('your secret here'));

6 app.use(express.session());

7 app.use(app.router);

These take care of serving static assets from public folder:

1 app.use(require('less-middleware')({ src: __dirname + '/public' }));

2 app.use(express.static(path.join(__dirname, 'public')));

Express.js gets its env variable from process.env.NODE_ENV which is passed as NODE_ENV=production, for example either when the server is started or in the machine’s configs. With this condition, we enable more explicit error handler for the development environment:

1 if ('development' == app.get('env')) {

2 app.use(express.errorHandler());

3 }

The routes are defined as a module in a separate file, so we just pass the functions’ expressions instead of defining them right here as anonymous request handlers:

1 app.get('/', routes.index);

2 app.get('/users', user.list);

There is another way to start up the server:

1 http.createServer(app).listen(app.get('port'), function(){

2 console.log('Express server listening on port ' + app.get('port'));

3 });

For your reference, the full code for app.js :

1 /**

2 * Module dependencies.

3 */

4

5 var express = require('express');

6 var routes = require('./routes');

7 var user = require('./routes/user');

8 var http = require('http');

9 var path = require('path');

10

11 var app = express();

12

13 // all environments

14 app.set('port', process.env.PORT || 3000);

15 app.set('views', path.join(__dirname, 'views'));

16 app.set('view engine', 'ejs');

17 app.use(express.favicon());

18 app.use(express.logger('dev'));

19 app.use(express.bodyParser());

20 app.use(express.methodOverride());

21 app.use(express.cookieParser('your secret here'));

22 app.use(express.session());

23 app.use(app.router);

24 app.use(require('less-middleware')({ src: path.join(__dirname, 'public' })));

25 app.use(express.static(path.join(__dirname, 'public')));

26

27 // development only

28 if ('development' == app.get('env')) {

29 app.use(express.errorHandler());

30 }

31

32 app.get('/', routes.index);

33 app.get('/users', user.list);

34

35 app.get('/admin', function(req, res, next) {

36 if (!req.query._token) return next(new Error('no token provided'));

37 }, function(req, res, next) {

38 res.render('admin');

39 });

40

41

42 http.createServer(app).listen(app.get('port'), function(){

43 console.log('Express server listening on port ' + app.get('port'));

44 });

If you $ cd cli-app into the project folder and run $ npm start or $ node app, you should see the common response at http://localhost:3000:

Boilerplate Express.js app.

Boilerplate Express.js app.