Scaffolding
CSCI-UA.0480-008
Scaffolding Topics
We'll discuss:
- what it takes to bootstrap an Express app
- a peek at scaffolding
- revisit modules
- revisit middleware
- revisit handlebars / yet another handlebars module
- revisit installing with npm
- scaffolding
- installation
- our modifications
- running an app
- stacktraces
- layout
Bootstrapping an Express App
Hey. So good news. We know to create an express app. Walk me through all of the boilerplate stuff that we have to do to… →
- create a simple express app
- that contains a form (that POSTs data)
- …and has handlebars templates
- …and serves static files (for CSS and images)
- …that has adequate logging
(kind of the bare minimum for a reasonable app, right?)
Bootstrapping an Express App Continued
Not sooooo much work, but there's still enough to make it a bit cumbersome: →
- require and setup an actual Express app (create an app object, listen)
- require handlebars and configure your Express app to use it
- create your
view
directories so you have a place to put your templates
- configure your Express app to use static files
- create your
public
directory so you have a place to store your static resources, like images, css, etc.
- require and configure body-parser to make sure you can read form data
- create middleware to log requests and responses to the console
WHEW! I AM TIRED
We're lazy, so even though that's not so much, it's still definitely too much work.
- that's a lot of tasks for such a tiny web app
- they're all pretty boilerplate too
- you know who's really good at finishing up tons of tiny and tedious tasks?
- your computer!
Instead of doing all of this stuff on our own, we can just let a computer do it for us.
Express Generator
Express Generator is a commandline tool that creates a skeleton Express project with a single, simple command. The project will come with a bunch of stuff baked in:
All of the stuff we asked for…
- creating a simple express app with…
- templating
- serving static files
- parsing the request body
- logging
And even more!
- bootstrapping package.json
- laying out the directory structure of your project
- setting up 404 and 500 pages
A Peek at Scaffolding
Let's take a quick peek at what this thing does! →
- install it:
npm install -g express-generator
- generate a skeleton app:
express --hbs myapp
- install dependencies
cd myapp
, then npm install
- run your app at localhost:3000:
./bin/www
Let's Check Out What it Made
You can find a more detailed list in the Express docs, but here are some highlights:
- a few directories
- the actual app's directory
views
(but no layout
)
public
(but the folders in are named differently)
- something called
routes
and bin
- a bunch of files
- of course,
app.js
- a package.json
- and others
- for the most part, things are slightly different, but familiar
Revisiting a Few Topics Before Moving On
The are a few things that need a bit of explanation before diving in to what the scaffolding generated….
- installing with npm (finally using package.json)
- modules (creating our own)
- middleware (mounting at a specific location)
- handlebars again (a different module)
package.json?
What does package.json contain again? →
- meta data about your app (mainly for packaging and distribution purposes)
- but most importantly, a list of module dependencies
- we've been
--save
'ing dependencies to it, but we haven't done anything with it yet… so what can we actually do with it? →
Notice that right after we generated our scaffolding, we ran npm install
in our application's root directory! →
- this installs everything that's in
package.json
!
- … without having to install each module individually
- (that means that everything that's required in the generated
app.js
gets installed)
npm install
Straight from the docs:
npm install (in package directory, no arguments):
- install the dependencies in the local
node_modules
folder.
- by default, npm install will install all modules listed as dependencies
- (with the –production flag, npm will not install modules listed in devDependencies … we don't have any yet, so this can be safely ignored)
Modules
Does anyone remember what a module is? →
- it's just a JavaScript file
- its contents can be brought in to another file by using the
require
statement (like const express = require('express')
- you can name a specific path in
require
(require('./somemodule')
)
- you can also drop the .js extension
- for variables to be usable by (exposed to) the file that's including the module… →
- you have to use the built-in
exports
variable (in module: exports.publicname = myVar;
to make things public
- after requiring module,
module.publicname
)
Let's try making a module that has a function in it… and using that function in another file. →
Modules in the Scaffolding
Note that there's a directory called routes… →
- it has two files in it
index.js
and users.js
- with (surprise) routes in them!
- …it looks like the files are just modules
- (notice the use of
module.exports
- the built in exports
variable is just a shorter name/alias for it)
- also it uses an Express router… →
Routers
A router is an object that has the ability to define routes and use middleware. Sound familiar? →
(Because it should a little bit…) →
Straight from the docs: →
- a router is an isolated instance of middleware and routes
- routers can be thought of as "mini" applications…
- capable only of performing middleware and routing functions
- we've seen this before because it acts just like our app object
- the router can have middleware
- … and http VERB routes added just like an application
- but no listen…
- routers behave like middleware themselves and can be
.use()'d
by the app or in other routers
Route Modules as Middleware
To use the route modules, the generated app.js
does the following:
- the route modules are brought in using
require
- which are used like middleware by using
app.use
- let's take a look at the generated code… →
- speaking of middleware, there are two version of calling the
use
method… what were they?
- with a single argument… middleware is enabled for all paths -
app.use(someFunction)
- with a two arguments… middleware is enabled for the path specified -
app.use('/path', someFunction)
External Routes / Middleware at Specific Paths
Notice that the route modules are used just like middleware.
- they're mounted at specific paths
- why might we have a separate folder for each set of routes, and why do we want them external to app.js? →
- as code base grows, a single file with all routes may end up unwieldy!
- helps organize functionality by top level paths
- (for example, all blog related stuff goes in /blog, all account related stuff goes in /account)
- for our simple projects, separating this stuff out may seem a bit like over-engineering, but it's handy to know for larger projects…
Back to Scaffolding
Recap so far…
- How do we install it? →
npm install express-generator
- How do we generate a project? →
express --hbs myapp
(the –hbs specifies that handlebars should be the template engine)
- How do we run an app? →
./bin/www
or node bin/www
→
- that's weird… let's take a closer look →
- (note that app is just a module required by www)
The Project Layout
├── app.js (main app and app configuration)
├── bin
│ └── www (file that we run to start app)
├── package.json (dependencies, project meta data)
├── public (static assets)
│ ├── images
│ ├── javascripts
│ └── stylesheets
│ └── style.css
├── routes - (we'll do a lot of work here)
│ ├── index.js
│ └── users.js (get rid of this, yeah?)
└── views (layouts and templates)
├── error.hbs
├── index.hbs
└── layout.hbs
Odds and Ends
- stack trace
NODE_ENV='development' node bin/www
- check out the logging!
- what should we remove?
Some Annoyances
- delete a bunch of stuff - users, any unwanted modules
- forces specific handlebars module
- some folder names are odd (javascripts?)
- two space indents may not match your indentation
- ups complexity somewhat (more files and requires)
Yeah, Scaffolding!
For convenience, we'll be using scaffolding in class demonstrations from time to time.
- you know, because live demos are prone to typos, misspellings and a bunch of on-the-spot debugging (fun sometimes, but maybe too time consuming)
- now that you (hopefully) are comfortable with some of the basic concepts behind express, feel free to use the generator
- so, for your projects / homework, you can decide whether or not you'd like to use it (why wouldn't you? →)
- maybe it's just not to your liking (too much extraneous stuff!)
- fortunately, express is unopinionated, you can use whatever project structure you like
- check out some other options in the faq
- … this layout will continue to evolve