Web framework.

mortie 5b2dfff935 middleware is now executed sequentially 1 year ago
client 6680ba4445 bugfix (and changed file modes) 2 years ago
js af8e148ad9 fix 1 year ago
web 6680ba4445 bugfix (and changed file modes) 2 years ago
README.md 827f3708eb Improved transforms 1 year ago
cli.js 3a020d1825 added CLI util 2 years ago
example.js 827f3708eb Improved transforms 1 year ago
index.js 5b2dfff935 middleware is now executed sequentially 1 year ago
package.json 5b2dfff935 middleware is now executed sequentially 1 year ago

README.md

webframe

Webframe is a small and dependency free web application framework.

Usage

Install:

npm install --save webframe

Use:

var webframe = require("webframe");
var app = new webframe.App();

Or from the command line:

npm install -g webframe
webframe [directory]

The file example.js contains an example of a small web application.

Why a new web framework?

A new installation of express is 2.3 megabytes. You end up with 42 dependencies in your node_modules directory. The Koa framework is 2.5 megabytes, with 36 dependencies. This isn't bad for a big web application, but I write a lot of tiny web applications where megabytes of dependencies just feels wrong. As a result, I have in the past often just used the http module directly. This framework is a nice middle ground; it provides some of the utility of big web frameworks, but without adding a ton of extra dependencies to the application.

Documentation

webframe.App([options])

Creates a new instance, with an optional options argument.

Options:

  • server: Your own HTTP (like the one created by http.createHttpServer).
  • listen: Whether to call the listen method on the server. Defaults to true.
  • port: The port to listen on. Defaults to the PORT environment variable, or 8080.
  • host: The host to listen on. Defaults to the HOSTNAME environment variable, or "127.0.0.1". For the server to be accessible to the outside world, listen on "0.0.0.0".
  • client_utils: Whether to add some utility functions to /webframe.js. Defaults to false.
  • res404: The string to return for a 404 error. "{{pathname}}" will be replaced with the pathname.
  • res403: The string to return for a 403 error. "{{pathname}}" will be replaced with the pathname.
var app = new webframe.App({ client_utils: true });

app.route(method, path [, middleware], func)

Add a route.

  • method: What HTTP method the route should be available at. Valid options: "GET", "POST", "PUT", "DELETE", or "ALL".
  • path: The path. If it starts with a "^", it will be interpreted as a regular expression (with new RegExp(path)), and the route will be ran on all matching paths. Routes without a pattern are prioritized over those with a pattern.
  • middleware: Optional. An array of middleware functions which will be ran before the route's function.
  • func: function(request, response). The function which handles the request.

app.get, app.post, app.put, app.delete, app.all

Utility functions which just call app.route() with a predefined method value.

E.g app.get("/foo", handler) is the same as app.route("GET", "/foo", handler).

app.info(str), app.notice(str), app.warning(str), app.panic(str)

Logging functions. They all print a message. app.panic also exits, and is intended for errors so bad you have to crash.

In the future, it will be possible to control the logging level.

Middleware

webframe.middleware contains middleware for the route functions.

  • webframe.middleware.cookies: Adds request.cookies, parsed COOKIE header.
  • webframe.middleware.params: Adds request.params, parsed URL parameters.
  • webframe.middleware.payload: Adds request.payload, a string (max 50 kilobytes) of the request payload.

In the future, there will be middleware for form data over POST too.

Modifications to the request and response objects

  • req.urlobj: The result of url.parse(req.url).
  • res.json(object): A utility function to respond with JSON.

webframe.static(root[, before])

Serve static files.

  • app.get("^.*", webframe.static("web")) will serve all the files in the web directory, so /index.html will serve web/index.html.
  • app.get("^/static/.*", webframe.static("web", "/static")) will serve all files in the web directory under /static, so /static/script.js will serve web/script.js.

Transformations - app.transform(extension, mime, func)

Webframe has a way to transform files of one file type to an other, for example transforming typescript into javascript, or sass into CSS.

  • extension: The file extension to transform.
  • mime: The result mime type.
  • func: function(path, writeStream). The transform function.
    • writeStream.headersSent: Whether headers have been sent or not.
    • writeStream.status: The status code. Default: 200 (or 500 for errors)
    • writeStream.headers: An object containing the headers to be sent. Default: { "content-type": <mime> }
    • writeStream.write: function(data). Write response data.
    • writeStream.end: function([data]). End the request, optionally with response data.
    • writeStream.error: function(err). Log an error, respond with status code 500 (or the content of writeStream.status if it's not 200).

Example (assumes you have the node-sass module installed):

var sass = require("node-sass");

app.transform(".sass", "text/css", (path, writeStream) => {
	try {
		var str = fs.readFileSync(path, "utf8");
	} catch (err) {
		writeStream.status = 404;
		return writeStream.error(err);
	}

	try {
		var result = sass.renderSync({ data: str });
		writeStream.end(result.css);
	} catch (err) {
		writeStream.error(err);
	}
});

Now, any .sass file served with webframe.static will be compiled into CSS, and sent with the browser with the MIME type "text/css". The result is also cached, so the expensive sass compilation will only happen the first time the file is requested, or when the file changes. The result will not be cached if you call writeStream.error.