Verified Commit 8e64b07d authored by Aral Balkan's avatar Aral Balkan
Browse files

Fork, document, and license new contributions under AGPLv3

parent aecae2e6
Pipeline #786 canceled with stages
This diff is collapsed.
# bankai
[![npm version][2]][3] [![build status][4]][5]
[![downloads][8]][9] [![js-standard-style][10]][11]
# @hypha/web-compiler
The easiest way to compile JavaScript, HTML and CSS.
@hypha/web-compiler v1.0.0 was forked from Bankai v9.15.0.
We want people to have fun building things for the web. There should be no
hurdles between a great idea, and your first prototype. And once you're ready,
it should be easy to package it up and share it online. That's Bankai: a tool
that helps you build for the web. No configuration, and no hassle - that's our
[Bankai]( is an excellent “friendly web compiler” by [Yoshua Wuyts](, [Renée Kooi](, and [other contributors](
If this is your first time building something for the web, take a look at
[choojs/create-choo-app]( to help get
a project setup from scratch :sparkles:.
If you want a general purpose web compiler, please use Bankai and [back their project](
@hypha/web-compiler is a simplified version of Bankai, tuned for the needs of the Hypha project that uses [https-server]( for seamless installation and use of locally-trusted certificates during development (and, soon, seamless Let’s Encrypt certificate provisioning and use in production).
## Installation
npm i @hypha/web-compiler
## Usage
$ bankai <command> [entry] [options]
The primary use case of web-compiler is programmatically with Hypha.
In Hypha, web-compiler is used:
1. As a live build and reload tool on development.
2. As a build and optimisation tool on production.
There is a command-line binary but it is not used in Hypha except for its useful _ispect_ command:
web-compiler inspect
## Example
@hypha/web-compiler is used by hooking it up to an HTTPS server.
The following example demonstrates how you can use @hypha/web-compiler in both
development and production and alongside regular HTTPS and WebSocket routes (the
latter demonstrated using the [Express]( framework):
build compile all files to dist/
inspect inspect the bundle dependencies
start start a development server
const httpsServer = require('')
const express = require('express')
const expressWebSocket = require('express-ws')
const path = require('path')
// Catch any uncaught errors.
process.on('uncaughtException', function (error) {
console.log('Uncaught exception:', error)
// Create the Express app, the HTTPS server, and add WebSocket support.
const app = express()
const server = httpsServer.createServer({}, app)
expressWebSocket(app, server, { perMessageDeflate: false })
-d, --debug output lots of logs
-h, --help print usage
-q, --quiet don't output any logs
-v, --version print version
// Websocket routes go here.
Examples:'/echo', (webSocket, request) => {
webSocket.on('message', message => {
console.log('Got web socket request to echo ', message)
Start a development server
$ bankai start index.js
// Regular HTTPS routes go here.
Visualize all dependencies in your project
$ bankai inspect index.js
app.get('/hello', (request, response) => {
response.writeHeader(200, {'Content-Type': 'text/html'})
response.end('<!doctype html><html lang=\'en\'><head><meta charset=\'utf-8\'/><title>Hello</title><style>body{background-color: "white";}</head><body>Hello, I am an HTTPS GET route!</body></html>')
Compile all files in the project to disk
$ bankai build index.js
// Set up @hypha/web-compiler.
// In development, we use it as middleware to enable live compilation and live reload.
// In production, use build a static distribution and serve it with express.static.
// client/index.js is the entry-point of your client-side JavaScript (e.g., Choo app).
const entryPoint = path.join(__dirname, 'client/index.js')
if (process.env.NODE_ENV === 'production') {
// Build the static distribution and serve it in production.
const build = require('@hypha/web-compiler/lib/cmd-build')
build(entryPoint, null, {base: 'https://localhost'})
} else {
// Set up development mode with live compilation and reload.
const webCompilerMiddleware = require('@hypha/web-compiler/http')(entryPoint)
Running into trouble? Feel free to file an issue:
// Handle server errors.
app.use(function(error, request, response, next) {
console.log('Error', error)
Do you enjoy using this software? Become a backer:
// Start the server.
server.listen(443, () => {
console.log('Server running on port 443.\n')
## ⚠️ HTTPS Instructions
When you first open up your application in a browser, you'll probably see a
warning page about HTTPS connections being untrusted. No worries, this is
entirely expected behavior. Follow the instructions below to solve this for
your browser.
<b>How does this work?</b>
For HTTPS to run on <code>localhost</code>, we must sign a TLS certificate
locally. This is better known as a "self-signed certificate". Browsers
actively check for certificates from uknown providers, and warn you (for good
reason!) In our case, however, it's safe to ignore.
HTTPS is needed for an increasing amount of APIs to work in the browser. For
example if you want to test HTTP/2 connections or use parts of the storage
API, you have no choice but to use an HTTPS connection on localhost. That's
why we try and make this work as efficiently, and securely as possible.
We generate a unique certificate for each Bankai installation. This means
that you'll only need to trust an HTTPS certificate for Bankai once. This
should be secure from remote attackers, because unless they have successfully
acquired access to your machine's filesystem, they won't be able to replicate
the certificate.
<b>Firefox Instructions</b>
<h3>Step 1</h3>
A wild security screen appears!. Click on "advanced".
<img src="/assets/firefox01.png" alt="firefox01">
<h3>Step 2</h3>
More details emerge! Click on "Add Exception".
<img src="/assets/firefox02.png" alt="firefox02">
<h3>Step 3</h3>
In the dropdown click "Confirm Security Exception".
<img src="/assets/firefox03.png" alt="firefox03">
<h3>Step 4</h3>
<img src="/assets/firefox04.png" alt="firefox04">
<b>Chrome Instructions</b>
Click the "more details" dropdown, then click "proceed". Pull Request for
screenshots welcome!
<b>Safari Instructions</b>
<h3>Step 1</h3>
A wild security screen appears! Click "Show Certificate".
<img src="/assets/safari01.png" alt="safari01">
<h3>Step 2</h3>
More details emerge! Check "Always trust 'localhost'…".
<img src="/assets/safari02.png" alt="safari02">
<h3>Step 3</h3>
The box is checked! Click "Continue".
<img src="/assets/safari03.png" alt="safari03">
<h3>Step 4</h3>
A box is asking you for your crendentials. Fill them in, and hit "Enter".
<h3>Step 5</h3>
<img src="/assets/safari04.png" alt="safari04">
## Optimizations
Bankai applies lots of optimizations to projects. Generally you won't need to
care how we do this: it's lots of glue code, and not necessarily pretty. But it
can be useful to know which optimizations we apply. This is a list:
## Optimisations
The following optimisations are applied during a build:
### JavaScript
- __[nanohtml][]:__ Optimize `choo` HTML code so it runs significantly faster in the
......@@ -148,7 +126,7 @@ can be useful to know which optimizations we apply. This is a list:
- __[babelify][]:__ Bring the latest browser features to _all_ browsers. See
[our babel section](#babel) for more details.
And bankai uses [tinyify][], which adds the following optimizations:
It also uses [tinyify][], which adds the following optimisations:
- __[browser-pack-flat][]:__ Remove function wrappers from the bundle, making
the result faster to run and easier to minify.
......@@ -168,7 +146,7 @@ And bankai uses [tinyify][], which adds the following optimizations:
- __[cleanCSS][clean-css]:__ minify the bundle.
### HTML
- __[inline-critical-css][]:__ extract all crititical CSS for a page into the
- __[inline-critical-css][]:__ extract all critical CSS for a page into the
`<head>` of the document. This means that every page will be able to render
after the first roundtrip, which makes for super snappy pages.
- __async load scripts:__ loads scripts in the background using the
......@@ -190,43 +168,13 @@ And bankai uses [tinyify][], which adds the following optimizations:
- __live reload:__ during development, we inject a live reload script.
## Configuration
The Bankai CLI doesn't take any flags, other than to manipulate how we log to
the console. Configuring Bankai is done by modifying `package.json`.
Bankai is built on three technologies: [`browserify`][browserify],
[`sheetify`][sheetify], and [`documentify`][documentify]. Because these can be
configured inside `package.json` it means that Bankai itself can be configured
from there too. Also if people ever decide to switch from the command line to
JavaScript, no extra configuration is needed.
"name": "my-app",
"browserify": {
"transform": [
"sheetify": {
"transform": [
"documentify": {
"transform": [
### Custom HTML
By default, Bankai starts with an empty HTML document, injecting the tags
By default, @hypha/web-compiler starts with an empty HTML document, injecting the tags
mentioned [above](#html). You can also create a custom template as `index.html`,
and Bankai will inject tags into it instead.
and @hypha/web-compiler will inject tags into it instead.
If you export your Choo app instance after doing `.mount()`, Bankai respects the
If you export your Choo app instance after doing `.mount()`, @hypha/web-compiler respects the
mount location during server side rendering:
......@@ -246,8 +194,9 @@ module.exports = app.mount('#app')
### Service Workers
Bankai comes with support for service workers. You can place a service worker
entry point in a file called `sw.js` or `service-worker.js`. Bankai will output
@hypha/web-compiler comes with support for service workers. You can place a service worker
entry point in a file called `sw.js` or `service-worker.js`. @hypha/web-compiler will output
a browserify bundle by the same name.
You can easily register service workers using
......@@ -272,38 +221,14 @@ Service workers have access to some environment variables:
* __process.env.FILE_LIST:__ An array of URLs to assets and routes. This can
be used to add all your app's files to a service worker cache.
Bankai can be hooked up directly to an HTTP server, which is useful when
working on full stack code.
var bankai = require('bankai/http')
var http = require('http')
var path = require('path')
var compiler = bankai(path.join(__dirname, 'client.js'))
var server = http.createServer(function (req, res) {
compiler(req, res, function () {
res.statusCode = 404
res.end('not found')
server.listen(8080, function () {
console.log('listening on port 8080')
## Babel
Not all browsers support all of the Web Platform's features. So in order to use
newer features on older browsers, we have to find a solution. The best solution
out there at the moment is Babel.
[Babel]( is a plugin-based JavaScript compiler. It takes
JavaScript in, and outputs JavaScript based for the platforms you've decided to
target. In Bankai we target the last 2 versions of FireFox, Chrome and Edge,
target. In @hypha/web-compiler we target the last 2 versions of FireFox, Chrome and Edge,
and every other browser that's used by more than 1% of people on earth. This
includes IE11. And if you have different opinions on which browsers to use,
Bankai respects `.babelrc` and [`.browserslistrc`]( files.
@hypha/web-compiler respects `.babelrc` and [`.browserslistrc`]( files.
Some newer JavaScript features require loading an extra library; `async/await`
being the clearest example. To enable such features, the `babel-polyfill`
......@@ -313,21 +238,25 @@ library needs to be included in your application's root (e.g. `index.js`).
We don't include this file by default in Bankai, because it has a significant
We don't include this file by default because it has a significant
size overhead. Once Babel includes only the language features you're using,
we'll work to include `babel-polyfill` by default.
## Events
### `compiler.on('error', callback(nodeName, edgeName, error))`
Whenever an internal error occurs.
### `compiler.on('change', callback(nodeName, edgeName, state))`
Whenever a change in the internal graph occurs.
## API
### `compiler = bankai(entry, [opts])`
Create a new bankai instance. Takes a path to a JavaScript file as the first
argument. The following options are available:
### `compiler = webCompiler(entry, [opts])`
Create a new @hypha/web-compiler instance. Takes a path to a JavaScript file as the first argument. The following options are available:
- __opts.quiet:__ Defaults to `false`. Don't output any data to `stdout`. Useful
if you have your own logging system.
......@@ -336,6 +265,7 @@ argument. The following options are available:
- __babelifyDeps:__ Defaults to true. Transform dependencies with babelify.
### `compiler.documents(routename, [opts], done(err, { buffer, hash }))`
Output an HTML bundle for a route. Routes are determined based on the project's
router. Pass `'/'` to get the default route.
......@@ -343,25 +273,33 @@ router. Pass `'/'` to get the default route.
in the `<head>` of the body as `window.initialState`.
### `compiler.scripts(filename, done(err, { buffer, hash }))`
Pass in a filename and output a JS bundle.
### `compiler.assets(assetName, done(err, { buffer, hash }))`
Output any other file besides JS, CSS or HTML.
### `compiler.styles(name, done(err, { buffer, hash }))`
Output a CSS bundle.
### `compiler.manifest(done(err, { buffer, hash }))`
Output a `manifest.json`.
### `compiler.serviceWorker(done(err, { buffer, hash }))`
Output a service worker.
### `compiler.close()`
Close all file watchers.
## License
Apache License 2.0
* Any code added starting from and including commit 7ae96cf36c3d335ef482a5e08c59d3b956d7a7b4 is released under [AGPLv3 or later](./LICENSE).
* All code up to and including commit 41a32b3361d5ad926a74bf63fb5345606091a4fd is licensed under [Apache License 2.0](./LICENSE).
......@@ -382,15 +320,3 @@ Apache License 2.0
"name": "bankai",
"version": "9.15.0",
"description": "The easiest way to compile JavaScript, HTML and CSS",
"license": "Apache-2.0",
"repository": "choojs/bankai",
"name": "@hypha/web-compiler",
"version": "1.0.0",
"description": "A web compiler forked from Bankai and tuned for Hypha.",
"license": "AGPL-3.0-or-later",
"repository": "",
"main": "index.js",
"bin": {
"bankai": "bin.js"
"web-compiler": "bin.js"
"scripts": {
"build": "./bin.js build example dist",
......@@ -14,7 +14,7 @@
"start": "NODE_NO_WARNINGS=1 ./bin.js start example",
"debug": "DEBUG='*' ./bin.js start -q example"
"keywords": [],
"keywords": ['hypha', 'web compiler', 'Bankai'],
"dependencies": {
"@choojs/findup": "^0.2.0",
"": "^2.0.0",
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment