Connect 2.0
Connect 2.0 is here with new core middleware, miscellaneous improvements, and some new docs.
var app = connect()
.use(connect.logger('dev'))
.use(connect.static('public'))
.use(function(req, res){
res.end('hello world\n');
})
app.listen(3000);
HTTP and HTTPS
Previously connect.Server inherited from Node’s core net.Server, this made it difficult to provide both HTTP and HTTPS for your application. The result of connect() (formerly connect.createServer()) is now simply a JavaScript Function. This means that you may omit the call to app.listen(), and simply pass app to a Node net.Server as shown here:
var connect = require('connect')
, http = require('http')
, https = require('https');
var app = connect()
.use(connect.logger('dev'))
.use(connect.static('public'))
.use(function(req, res){
res.end('hello world\n');
})
http.createServer(app).listen(80);
https.createServer(tlsOptions, app).listen(443);
Body parsers
The bodyParser() middleware is now nothing but a short-hand for adding the json(), multipart(), and urlencoded() middleware. Each of these populate req.body with an object containing the parsed values, multipart() provides req.body and req.files for uploads.
Core compression
As of Node 0.6.0 fast, native compression capabilities are available, so now we have the compress() middleware supporting deflate and gzip.
Cookie parser
The cookieParser() middleware now supports signed cookies, and accepts a secret. This replaces the need to pass session({ secret: string }) to the session() middleware. Signed cookies are available via req.signedCookies, and unsigned as req.cookies.
Error delegation
Previously a few of the core middleware would respond to error situations directly, these have been changed to simply next(err)-them along. This change allows you to specify customized behaviour by adding an error-handling middleware:
app.use(function(err, req, res, next){
if (4 == err.status / 100) {
// render a client-error page
} else {
// render a server-error page
}
});
Session
As mentioned session() no longer requires a secret. The cookie .maxAge has been defaulted to null, meaning that it will be a browser-session cookie, expiring once the visitor closes their browser.
Third-party middleware
Third-party middleware should remain perfectly functional. This release of Connect is not compatible with Express 2.x, Express 3.0 is coming soon.
Changelog
The following significant changes were made, as well as several others that do not impact public API, such as a full rewrite of the tests using Mocha.
- Added
cookieSession() middleware for cookie-only sessions
- Added
compress() middleware for gzip / deflate support
- Added
session() “proxy” setting to trust X-Forwarded-Proto
- Added
json() middleware to parse “application/json”
- Added
urlencoded() middleware to parse “application/x-www-form-urlencoded”
- Added
multipart() middleware to parse “multipart/form-data”
- Added
cookieParser(secret) support so anything using this middleware may access signed cookies
- Added signed cookie support to
cookieParser()
- Added support for JSON-serialized cookies to
cookieParser()
- Added
err.status support in Connect’s default end-point
- Added X-Cache MISS / HIT to
staticCache()
- Added public
res.headerSent checking nodes res._headerSent until node does
- Changed
basicAuth() req.remoteUser to req.user
- Changed: default
session() to a browser-session cookie. Closes #475
- Changed: no longer lowercase cookie names
- Changed
bodyParser() to use json(), urlencoded(), and multipart()
- Changed:
errorHandler() is now a development-only middleware
- Changed middleware to
next() errors when possible so applications can unify logging / handling
- Removed
http[s].Server inheritance, now just a function, making it easy to have an app providing both http and https
- Removed
.createServer() (use connect())
- Removed
secret option from session(), use cookieParser(secret)
- Removed
connect.session.ignore array support
- Removed
router() middleware. Closes #262
- Fixed: set-cookie only once for browser-session cookies
- Fixed FQDN support. dont add leading “/”
- Fixed 404 XSS attack vector. Closes #473
- Fixed HEAD support for 404s and 500s generated by Connect’s end-point
Mocha test coverage
The latest release of Mocha adds two new reporters, now totaling 13 packaged with the library. The two new ones are “json-cov” and “html-cov”, the latter inherits from the former in order to produce a single-page test coverage report.

If you’re curious what a live example looks like, check out this page.
Setup
With Node’s require.paths array out of the picture there’s a bit of boiler-plate involved in setting up test coverage for your project, but it’s pretty minimal. First you’ll want to install the jscoverage executable, this program parses your source code and spits out an instrumented version, effectively a bunch of lines that look like this:
$_jscoverage[filename][line]++;
This enables libraries like Mocha to execute the code as they normally would, however we can then extract this coverage information and generate fancy reports. jscoverage takes the input directory, and an output directory, I usually calls this “lib-cov”:
$ jscoverage lib lib-cov
Typically when testing your library you’ll use relative require() calls that look like this: var express = require('../'), and the library entry point is ./index.js. Normally this file might look something like below, or you may not have an ./index.js file at all.
module.exports = require('./lib/express');
By using ./index.js we can then alter this statement to conditionally export the instrumented version when the EXPRESS_COV environment variable is present:
module.exports = process.env.EXPRESS_COV
? require('./lib-cov/express')
: require('./lib/express');
Then all you need to do is invoke mocha with --reporter html-cov and redirect the stdout to a file such as coverage.html. Line 25 the test-cov target of the Express Makefile illustrates how I typically handle this but depending on your setup it may vary.
That’s it! remember to add “coverage.html” to your .npmignore and .gitignore files ;)
Stylus gets @extend
@extend is a great little feature which originated in SASS, and now finds a home in Stylus. If you’ve ever written CSS like this, you know it can become quite the pain to maintain large lists of selectors:
.message,
.warning,
.error {
font-size: 14px;
padding: 5px 10px;
border: 1px solid #eee;
border-radius: 5px;
}
.warning {
color: yellow;
}
.error {
color: red;
}
@extend makes this process flow naturally, and even supports inheritance. In Stylus you may use @extend or @extends, I prefer the latter personally but that’s up to you! Using this feature you would define .message on it’s own, and simply __@extend_ it from within the other rulesets:
.message {
font-size: 14px;
padding: 5px 10px;
border: 1px solid #eee;
border-radius: 5px;
}
.warning {
@extends .message;
color: yellow;
}
.error {
@extends .message;
color: red;
}
Taking this even further with inheritance:
.fatal-error {
@extends .error;
font-weight: bold
}
Would yield the following CSS:
.message,
.warning,
.error,
.fatal-error {
font-size: 14px;
padding: 5px 10px;
border: 1px solid #eee;
border-radius: 5px;
}
.warning {
color: #ff0;
}
.error,
.fatal-error {
color: #f00;
}
.fatal-error {
font-weight: bold;
}
Here’s another example:
form
button
padding: 10px
border: 1px solid #eee
border-radius: 5px
ul
li a
@extends form button
Yielding:
form button,
ul li a {
padding: 10px;
border: 1px solid #eee;
border-radius: 5px;
}
And of course you may utilize the alternative Stylus syntax if you prefer:
.message
font-size: 14px
padding: 5px 10px
border: 1px solid #eee
border-radius: 5px
.warning
@extends .message
color: yellow
.error
@extends .message
color: red
.fatal-error
@extends .error
font-weight: bold
Grab Stylus 0.22.4 for these goodies!
This short Vimeo screencast illustrates why Stylus is the most like CSS as a stylesheet “preprocessor”. More on Stylus here.
Connect 1.8.0 - multipart support
Connect 1.8.0 is a tiny but substantial release because it adds multipart/form-data support via Felix Geisendörfer’s fantastic multipart parser formidable, it’s great and chances are you’re already using it!
The bodyParser() middleware now unifies multipart, json, and x-www-form-urlencoded parsing, providing the req.body object containing the parsed data. For security purposes the files are placed in a separate object, req.files, however just as accessible. A constant struggle that I’ve seen in the community is the concept of “missing” request data events so this will
prevent further confusion. The downside to this is that if you wish to report upload progress, or access files and fields as the request is streamed, you will have to use formidable directly.
Before this addition your use of formidable might look something like the following (with Express):
app.post('/someform', function(req, res, next){
var form = new formidable.IncomingForm;
form.parse(req, function(err, fields, files){
if (err) return next(err);
// do something with files.image etc
});
});
With the new bodyParser() all you need is:
app.use(express.bodyParser());
app.post('/some-form', function(req, res){
// do something with req.files.image
})
The middleware takes the same options that are mentioned on formidable’s GitHub repo page, so you can specify things like size limits, retaining extensions, the upload directory etc.
app.use(express.bodyParser({
uploadDir: '/tmp/uploads'
}));
That’s it! but I think this will cover well above the 80% use-case and prevent a lot of headaches that people have with the previous the inconsistencies.
Stylus 0.15.1 - new property reference & @keyframes fabrication features
Stylus 0.15.x adds a bunch of cool new functionality as well as some important bug fixes.
@keyframes fabrication
The new keyframes fabrication support automatically duplicates your @keyframes definitions to support vendor prefixes. Note that this is only a default, as shown below:
@-moz-keyframes foo {
0% {
color: #000;
}
100% {
color: #fff;
}
}
@-webkit-keyframes foo {
0% {
color: #000;
}
100% {
color: #fff;
}
}
@keyframes foo {
0% {
color: #000;
}
100% {
color: #fff;
}
}
one can tweak this functionality using the vendors list as shown in the following snippet which will only expand to the -webkit- vendor prefix.
vendors = moz official
@keyframes foo {
from {
color: black
}
to {
color: white
}
}
The vendors property may be utilized more in the future, and perhaps in frameworks like “nib” to unify configuration.
Property reference
The syntax @<property> has been introduced to reference values of existing properties. For example if you want to re-use values, you may typically do something like below instead of typing the value several times, also allowing you to use functions with w.
.button
width: w = 50px
height: w
The new property reference syntax allows you to treat properties as variables, which can also be accessed within mixins:
.button
width: 50px
height: @width
Comment compilation
When the compress option is true Stylus will not output single-line nor multi-line comments, which are commonly found used for licensing in stylesheet frameworks etc, so it’s useful to strip these out however you can now force output with the ! character /*!.
New built-in functions
The math functions cos() and sin() were added, as well as exposing PI.
Bug fixes