Together with few friends we started building pace - a web application for organizing and managing running events & competitions. We are a colorful bunch of people with different backgrounds, therefore we wanted to choose an approachable tech stack, as some of us wants also to learn one or two things about JavaScript, web applications or programming in general.
And then, somebody suggested to write one thing or two, about our technology decisions and accompany it with some HowTo information. So here we are.
This is the first post out of the pace series. We will take a look at how to quickly bootstrap a new express.js application and what is acctually happening during that process.
First things first: node.js & express.js
Node.js® is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices. - Nodejs.org https://nodejs.org
Probably also due to the popularity of JavaScript node quickly spread all around the web and is nowadays widely used and has an impressive ecosystem of additional libraries/modules (just take a look at npm package manager).
express.js is one of many web frameworks based on node, but seems also to be one of the most popular ones. What is a web framework you ask:
A web application framework is a software framework that is designed to support the development of dynamic websites, web applications, web services and web resources. The framework aims to alleviate the overhead associated with common activities performed in web development. For example, many frameworks provide libraries for database access, templating frameworks and session management, and they often promote code reuse - http://localhost:1313/post/2016/02/22/bff/
How to bootstrap a web app & what happens
Assuming you have node already installed on your machine (if not look at here)
npm install express-generator -g
express myWebApp
cd myWebApp
npm install
npm start
What happened you ask? So first we globally installed express-generator (it will be now available to you via express cmd). Then we made it bootstrap for us an app called myWebApp. This resulted in the following:
/tmp|⇒ express myWebApp
create : myWebApp
create : myWebApp/package.json
create : myWebApp/app.js
create : myWebApp/public
create : myWebApp/public/javascripts
create : myWebApp/public/images
create : myWebApp/routes
create : myWebApp/routes/index.js
create : myWebApp/routes/users.js
create : myWebApp/public/stylesheets
create : myWebApp/public/stylesheets/style.css
create : myWebApp/views
create : myWebApp/views/index.jade
create : myWebApp/views/layout.jade
create : myWebApp/views/error.jade
create : myWebApp/bin
create : myWebApp/bin/www
install dependencies:
$ cd myWebApp && npm install
run the app:
$ DEBUG=myWebApp ./bin/www
The generator created for us a new directory which contains all the needed files the web application consists of:
- package.json -> definition of our node dependencies and some node configuration
- app.js -> the main entry point into the application
- public -> contains all public assets whic will be exposed to the public
- routes -> contains the definitions of our routes (as ourDomain/index or ourDomain/somethingDifferent)
- views -> contains our templates (more about this in future posts)
- bin/www -> executable application (if you run
npm start
this will be started)
The execution of npm install
in app’s directory, installs all the dependencies defined in the package.json
file. Those dependencies will be installed only locally in the node_modules
directory. After this step we are ready to go and able to run npm start
which should result in this:
myWebApp|⇒ npm start
> myWebApp@0.0.1 start /private/tmp/myWebApp
> node ./bin/www
GET / 200 305ms - 170b
GET / 200 34ms - 170b
GET /stylesheets/style.css 200 4ms - 110b
GET / 304 25ms
GET /stylesheets/style.css 304 1ms
You can see, that I opened http://localhost:3000 in the browser and express served me the index page with the 200 code (you can also see that I refreshed the page and got 304 NOT MODIFIED). Everything works also as expected {%gemoji +1%}
Why? How? Let’s take a quick look at the following:
app.js
var routes = require('./routes/index');
app.use('/', routes)
This is only a part of the app.js
file but shows the wiring of our default root to the index.js file shown below. BTW: you can also see how to load dependencies/modules for our code via the require
function (if you want to read more about that, here is a nice write-up)
routes/index.js:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
title = "bootstraping a node dot js webapp"
});
module.exports = router;
The index.js
uses express’ router
and wires request for / to the function responding with a rendered index.jade
template, to which it passes a variable called title
. If you never used jade, don’t worry, is a pretty simple HTML template engine. Look at the following:
index.jade:
extends layout
block content
h1= title
p Welcome to #{title}
Jade enables template composition. In here we extend layout.jade
which defines the general page structure. If other template defines a block called content
it will be then injected at the corresponding place.
layout.jade:
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
block content
Jade is indentation aware, meaning that the above example results in the following:
<!DOCTYPE html>
<html>
<head>
<title>Express</title>
<link rel="stylesheet" href="/stylesheets/style.css">
</head>
<body>
<h1>Express</h1>
<p>Welcome to Express</p>
</body>
</html>
Now you have seen all the parts making the browser render the most basic page of all time :sunglasses:
Next post out of the pace series, will actually explain how to start working on the functionality we need. Right now you can start to play around with the data which is passed by the index.js
to the index.jade
template and how the template uses it. Have fun!