stakit
v0.1.0
Published
A modular toolkit for building static websites
Downloads
1
Readme
stakit
A modular toolkit for building static websites
Stakit is a framework that helps you compose powerful build pipelines for static-websites without breaking a sweat. It's minimal and modular, uses streams and the Stakit toolkit has a bunch of plugins and transforms that you can use.
Stakit is still early in development, but you can take it and use it to see if you should care about it or not.
Features
- framework agnostic: works with any framework that can output a string
- modular: you never have what you don't need, but you can
npm install
it - small api: it only has 7 core methods, only 3 of them you must use
- no constraints: you are never limited by the features and templates of a static-site generator
- fast, memory efficient: heavily using streams
Installation
npm i stakit
Example
var stakit = require('stakit')
var { render, hydrate } = require('stakit-choo')
var app = require('.')
var kit = stakit()
.routes(function (state) {
return [ '/' ]
})
.render(render(app))
.transform(hydrate)
kit.output(stakit.writeFiles('./public'))
Why?
Generally, you do 2 things when generating a static site:
- fill your app with some content
- copy static files
There are many modular (and lovely) tools for bundling Javascript or transforming CSS, Stakit is something similar, but for the full site, and especially focuses on HTML files.
You'll have to handle the bundling of your app and including the bundle if that's what you need. Following Choo's philosophy, it's small, understandable and easy to use. It was designed to work mainly with Choo, but it should work with other isomorphic frameworks too.
Usage
Stakit is called programmatically, not from the command-line, therefore you'll need a Javascript file (like build.js
), where you require it. Afterwards you can initialize the kit with stakit()
and then chain a couple of methods.
Two methods must appear in the pipeline:
All other methods are optional and called in the following order:
- all the middlewares applied by
kit.use()
- the applied
routesReducer
function - for every route:
- a single call to the applied
renderer
- all
transform
calls
- a single call to the applied
End the pipeline with kit.output()
.
API
This section provides documentation on how each function in Stakit works. It's intended to be a technical reference.
kit = stakit()
Initialize a new kit
instance.
kit.html(template, selector)
Sets the starting HTML template and selector.
kit.use(fn(context))
Pushes a middleware / plugin to the middlewares list, general purpose functions ran before the route generation. You can modify the context any way you want, from altering the state
to installing transform
s.
kit.use(function (ctx) {
ctx._transforms.push(transform)
})
See Middlewares for more information.
kit.routes(routeReducer(state))
The routeReducer
is a function that gets context.state
as a parameter and returns an Array
of strings / routes. These are the routes on which Stakit will call render
.
kit.routes(function (state) {
return Object.keys(state.content)
// or statically
return [ '/', '/about', '/blog' ]
})
kit.render(renderer(route, state))
Sets the renderer of the build. This is where the magic happens. The renderer
will be called for every route returned by routes
.
It has to return an object with the following values:
{
html: string, // the result of the render
state: object // the state after the render (optional)
}
Transforms will receive the updated state returned here.
kit.transform(transformFn, opts)
Pushes a transform to the list of transforms. Stakit uses documentify
and streams to build up the HTML.
They're called after the rendered content has been replaced in the HTML.
See Transforms for more information.
kit.output(writerObject)
Starts the build pipeline and ends it with passing all the routes to writerObject.write({ destination, stream })
. Returns a Promise
that waits until all files (routes and static) has been completely written.
By default it uses a Writer that outputs the site to the ./public
directory.
See Writers for more information.
Middlewares
Built-in middlewares:
stakit.state(extendState)
Utility to help you with adding values to context.state
kit.use(stakit.state({ message: 'good morning!' }))
stakit.copy(files)
Middleware for copying files to the output directory.
// Copy files to the same location
kit.use(stakit.copy([ 'robots.txt' ]))
// Copy files to a different location within the output path
kit.use(stakit.copy({
'robots.txt': 'robots.txt',
'sitemap.xml': 'sitemaps/sitemap.xml'
}))
Transforms
Documentify
is very powerful and can easily be modulized. The general format of a Stakit transform is:
// wrapped in a function
function lang (context) {
// return the documentify transform
return function (lang) {
// return a transform stream
return hstream({ html: { lang: lang } })
}
}
Note: hstream
is a very good friend!
The documentify
transform is wrapped in a function, so we can get the context
when we need it, without messing with documentify
's API. If you want to bypass this, you can simply return the documentify
transform from a function.
See what transforms come with Stakit in transforms/readme.md
.
Writers
Writers output the generated, transformed static files. This can vary from outputting to the file-system, to putting them into a Dat archive.
A writer must implement a method: write
. For every file, including the generated pages + the files added to context._files
, writer.write
will be called with a file object. It should return a Promise
that returns after the pipe was flushed (the file was completely written).
A file object looks like this:
{
source: null | string,
destination: string,
stream: Stream
}
It's recommended to clean up the output directory before every build.
Have a look at the built-in stakit.writeFiles
method as an example.
That's all about writers.
See Also
- choo - sturdy 4kb frontend framework
- documentify - Modular HTML bundler
- jalla - Lightning fast web compiler and server in one (also thanks for a lot of code snippets!)