Skip to content

Commit 8d8b6d8

Browse files
committed
Initial commit
0 parents  commit 8d8b6d8

37 files changed

Lines changed: 252842 additions & 0 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

.jshintignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/**
2+
test/fixtures/**

.travis.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
language: node_js
2+
node_js:
3+
- "stable"
4+
- "4"
5+
- "0.12"
6+
7+
env:
8+
- CXX=g++-4.8 WORKER_COUNT=2
9+
addons:
10+
apt:
11+
sources:
12+
- ubuntu-toolchain-r-test
13+
packages:
14+
- g++-4.8

README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# FastBoot Express Middleware
2+
3+
This middleware is a small wrapper around the
4+
[`fastboot`](https://github.com/ember-fastboot/fastboot) package, which
5+
renders Ember.js apps in Node.js.
6+
7+
By adding this middleware to your Express app, you can serve HTML from a
8+
rendered Ember.js app to clients that don't support JavaScript, such as
9+
`curl`, search crawlers, or users with JavaScript disabled.
10+
11+
Note that this is _just an Express middleware_ and there is more needed
12+
to serve apps in a production environment. If you want to server-side
13+
rendered Ember applications without doing a lot of work, you are
14+
recommended to consider the [FastBoot App
15+
Server](https://github.com/ember-fastboot/fastboot-app-server), which
16+
manages many of the hard parts for you.
17+
18+
That said, this middleware is designed to be easy to integrate for those
19+
who already have existing Express stacks, or who want maximum
20+
flexibility in how requests are handled.
21+
22+
## Usage
23+
24+
```js
25+
const express = require('express');
26+
const fastbootMiddleware = require('fastboot-express-middleware');
27+
28+
let app = express();
29+
30+
app.get('/*', fastbootMiddleware('/path/to/dist'));
31+
32+
app.listen(3000, function () {
33+
console.log('FastBoot app listening on port 3000!');
34+
});
35+
```
36+
37+
## Building Your Ember App
38+
39+
Before you can use your app with FastBoot, you must first install the
40+
[ember-cli-fastboot][ember-cli-fastboot] addon and build your app by
41+
running `ember build`. The build process will compile your app into a
42+
version that is compatible with both Node.js and the browser and put it
43+
in the `dist` directory. This `dist` directory is the path you should
44+
provide to the middleware to specify which Ember app to load and render.
45+
46+
## Resilient Mode
47+
48+
By default, errors during render will cause the middleware to send an
49+
HTTP 500 status code as the response. In order to swallow errors and
50+
return a `200 OK` with an empty HTML page, set the `resilient` flag to
51+
true:
52+
53+
```js
54+
app.get('/*', fastbootMiddleware('/path/to/dist', {
55+
resilient: true
56+
}));
57+
```
58+
59+
## Custom FastBoot Instance
60+
61+
For more control over the FastBoot instance that is created to render
62+
the Ember app, you can pass a custom instance that the middleware will
63+
use instead of creating its own:
64+
65+
```js
66+
let fastboot = new FastBoot({
67+
distPath: 'path/to/dist'
68+
});
69+
70+
let middleware = fastbootMiddleware({
71+
fastboot: fastboot
72+
});
73+
74+
app.get('/*', middleware);
75+
76+
// ...later
77+
fastboot.reload();
78+
```
79+
80+
[ember-cli-fastboot]: https://github.com/ember-fastboot/ember-cli-fastboot

index.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'use strict';
2+
3+
const FastBoot = require('fastboot');
4+
const chalk = require('chalk');
5+
6+
function fastbootExpressMiddleware(distPath, options) {
7+
let opts = options;
8+
9+
if (arguments.length === 1) {
10+
if (typeof distPath === 'string') {
11+
opts = { distPath: distPath };
12+
} else {
13+
opts = distPath;
14+
}
15+
}
16+
17+
opts = opts || {};
18+
19+
let log = opts.log !== false ? _log : function() {};
20+
21+
let fastboot = opts.fastboot;
22+
23+
if (!fastboot) {
24+
fastboot = new FastBoot({
25+
distPath: opts.distPath,
26+
resilient: opts.resilient
27+
});
28+
}
29+
30+
return function(req, res, next) {
31+
let path = req.url;
32+
fastboot.visit(path, { request: req, response: res })
33+
.then(success, failure);
34+
35+
function success(result) {
36+
result.html()
37+
.then(html => {
38+
let headers = result.headers;
39+
40+
for (var pair of headers.entries()) {
41+
res.set(pair[0], pair[1]);
42+
}
43+
44+
log(result.statusCode, 'OK ' + path);
45+
res.status(result.statusCode);
46+
res.send(html);
47+
})
48+
.catch(error => {
49+
console.log(error.stack);
50+
res.sendStatus(500);
51+
});
52+
}
53+
54+
function failure(error) {
55+
if (error.name === "UnrecognizedURLError") {
56+
next();
57+
} else {
58+
log(500, "Unknown Error: " + error.stack);
59+
res.status(500).send(error.stack);
60+
}
61+
}
62+
};
63+
}
64+
65+
function _log(statusCode, message, startTime) {
66+
let color = statusCode === 200 ? 'green' : 'red';
67+
let now = new Date();
68+
69+
if (startTime) {
70+
let diff = Date.now() - startTime;
71+
message = message + chalk.blue(" " + diff + "ms");
72+
}
73+
74+
console.log(chalk.blue(now.toISOString()) + " " + chalk[color](statusCode) + " " + message);
75+
}
76+
77+
module.exports = fastbootExpressMiddleware;

package.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "fastboot-express-middleware",
3+
"version": "0.1.0",
4+
"description": "An Express middleware for rendering Ember apps with FastBoot",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "mocha"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/ember-fastboot/fastboot-express-middleware.git"
12+
},
13+
"keywords": [
14+
"fastboot",
15+
"ember",
16+
"express",
17+
"middleware"
18+
],
19+
"author": "Tom Dale <[email protected]>",
20+
"license": "MIT",
21+
"bugs": {
22+
"url": "https://github.com/ember-fastboot/fastboot-express-middleware/issues"
23+
},
24+
"homepage": "https://github.com/ember-fastboot/fastboot-express-middleware#readme",
25+
"devDependencies": {
26+
"chai": "^3.5.0",
27+
"chai-as-promised": "^5.3.0",
28+
"express": "^4.13.4",
29+
"mocha": "^2.4.5",
30+
"mocha-jshint": "^2.3.1",
31+
"request-promise": "^3.0.0"
32+
},
33+
"dependencies": {
34+
"chalk": "^1.1.3"
35+
}
36+
}

test/.jshintrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"mocha": true,
3+
"esnext": true,
4+
"node": true
5+
}

0 commit comments

Comments
 (0)