A static website. In memory. You can save your website to a file, serve it, or upload it to S3.
What's a "static" website? "Static" means this:
- Only GET and HEAD requests are valid.
- The response for a given endpoint never changes.
- There are no errors. (A server may return 404 errors, and a server may receive erroneous HTTP requests; but those aren't website errors.)
Why "in memory"? Because it's crazy-fast for small websites. And it's better than storing the website as a bunch of files:
- A website doesn't have "folders": it has "paths".
/foo
can be an HTML file, and/foo/bar
can also be an HTML file. See?/foo
is not a folder. - A website doesn't just return file contents: it also returns HTTP headers. Those headers aren't derived from the file contents.
- A website can have redirects.
How do you take advantage? Use a framework that outputs a "static website" in this format. This package provides the tools to develop and deploy within milliseconds.
Usage
First, npm install --save in-memory-website
Now, build your in-memory website. It can be as simple as this, my-website.js
:
'use strict' const StaticWebsite = StaticWebsiteconst website = path: '/hello-world' headers: 'Content-Type': 'text/plain; charset=utf-8' body: Buffer // ... now let's see what we can do with this website.
Local website
Now you can serve the website locally. The 404 error page is a directory
listing, and any response with a Location
header becomes a
301 Moved Permanently
.
// ... continuing above programconst DevServer = HttpServerconst server = websiteserver // and browse to http://localhost:3000
Saving a website as a file
You can dump the website to a file, and then reload it later:
// ... continuing above programconst fs = fs // ... and in a later programconst website2 = StaticWebsite
Lightning-fast development server
Want to code a website? Good. Here's the pattern for you. It involves three scripts:
1. build.js: builds a website; outputs to stdout
#!/usr/bin/env node'use strict' const StaticWebsite = StaticWebsiteconst validate = validate // Normally our website generator would be more complex. Potentially it will// be asynchronous. It may throw an error. Make this script exit with a// non-zero error code if there's a problem.const website = path: '/hello-world' headers: 'Content-Type': 'text/plain; charset=utf-8' body: Buffer // We have utilities to avoid common mistakes. Choose the mistakes you want// to avoid; make this script exit with a non-zero error code if there's a// problem.const validationError = validateif validationError throw validationError // No problem? Write the website to stdout and exit with a zero error code// (the default).processstdout
This is your framework: the program that builds your entire website. It outputs
the website to process.stdout
and exits with status code 0
. If it fails
(for instance, your framework has a syntax error), the error is output to
process.stderr
.
2. dev.js: serves a website; rebuilds automatically
#!/usr/bin/env node'use strict' const DevServer = DevServer const server = `/build.js` // In this dev environment, let's rebuild the website every time a file changesconst chokidar = // https://github.com/paulmillr/chokidarchokidar // queueBuild() is "debounced": if 10 files change very quickly, we only // rebuild once. server server // and use http://livereload.com/extensions/
This is your development environment: the program you run in the background while you work. It's a web server, at http://localhost:3000. It has some nifty features:
- Its "404 Not Found" page links to all the valid endpoints
- When
build.js
returns a status code that isn't0
, every endpoint is a500 Internal Server Error
with debugging information. - It queues HTTP requests while rebuilding; those HTTP requests will complete when the build finishes.
- If you use a LiveReload browser extension the page will refresh whenever you change a file. That means you'll see the results of your code changes immediately -- be they error messages or bugfixes.
3. deploy.js: sends a website to a production server
#!/usr/bin/env node'use strict' const child_process = const StaticWebsite = StaticWebsiteconst S3Uploader = S3Uploader // Throws error if build.js failsconst websiteData = child_processconst website = StaticWebsite S3Uploader
Lightning-fast production server
Hosting on S3 is cheap and fast. TODO add tutorial.
Backup production server
We supply Express middleware to help you build your own web server. For instance:
#!/usr/bin/env node'use strict' const express = const StaticWebsite = StaticWebsiteconst ExpressApp = ExpressApp const websiteData = const website = StaticWebsite const app = app app
License
Copyright (c) 2017 The Huffington Post, released under the MIT license. See LICENSE.