1 | # bankai
|
2 | [![npm version][2]][3] [![build status][4]][5]
|
3 | [![downloads][8]][9] [![js-standard-style][10]][11]
|
4 |
|
5 | The easiest way to compile JavaScript, HTML and CSS.
|
6 |
|
7 | We want people to have fun building things for the web. There should be no
|
8 | hurdles between a great idea, and your first prototype. And once you're ready,
|
9 | it should be easy to package it up and share it online. That's Bankai: a tool
|
10 | that helps you build for the web. No configuration, and no hassle - that's our
|
11 | promise.
|
12 |
|
13 | If this is your first time building something for the web, take a look at
|
14 | [choojs/create-choo-app](https://github.com/choojs/create-choo-app) to help get
|
15 | a project setup from scratch :sparkles:.
|
16 |
|
17 | ## Usage
|
18 | ```txt
|
19 | $ bankai <command> [entry] [options]
|
20 |
|
21 | Commands:
|
22 |
|
23 | build compile all files to dist/
|
24 | inspect inspect the bundle dependencies
|
25 | start start a development server
|
26 |
|
27 | Options:
|
28 |
|
29 | -d, --debug output lots of logs
|
30 | -h, --help print usage
|
31 | -q, --quiet don't output any logs
|
32 | -v, --version print version
|
33 |
|
34 | Examples:
|
35 |
|
36 | Start a development server
|
37 | $ bankai start index.js
|
38 |
|
39 | Visualize all dependencies in your project
|
40 | $ bankai inspect index.js
|
41 |
|
42 | Compile all files in the project to disk
|
43 | $ bankai build index.js
|
44 |
|
45 | Running into trouble? Feel free to file an issue:
|
46 | https://github.com/choojs/bankai/issues/new
|
47 |
|
48 | Do you enjoy using this software? Become a backer:
|
49 | https://opencollective.com/choo
|
50 | ```
|
51 |
|
52 | ## ⚠️ HTTPS Instructions
|
53 | When you first open up your application in a browser, you'll probably see a
|
54 | warning page about HTTPS connections being untrusted. No worries, this is
|
55 | entirely expected behavior. Follow the instructions below to solve this for
|
56 | your browser.
|
57 |
|
58 | <details>
|
59 | <summary>
|
60 | <b>How does this work?</b>
|
61 | </summary>
|
62 | For HTTPS to run on <code>localhost</code>, we must sign a TLS certificate
|
63 | locally. This is better known as a "self-signed certificate". Browsers
|
64 | actively check for certificates from uknown providers, and warn you (for good
|
65 | reason!) In our case, however, it's safe to ignore.
|
66 |
|
67 | HTTPS is needed for an increasing amount of APIs to work in the browser. For
|
68 | example if you want to test HTTP/2 connections or use parts of the storage
|
69 | API, you have no choice but to use an HTTPS connection on localhost. That's
|
70 | why we try and make this work as efficiently, and securely as possible.
|
71 |
|
72 | We generate a unique certificate for each Bankai installation. This means
|
73 | that you'll only need to trust an HTTPS certificate for Bankai once. This
|
74 | should be secure from remote attackers, because unless they have successfully
|
75 | acquired access to your machine's filesystem, they won't be able to replicate
|
76 | the certificate.
|
77 | </details>
|
78 |
|
79 | <details>
|
80 | <summary>
|
81 | <b>Firefox Instructions</b>
|
82 | </summary>
|
83 | <h3>Step 1</h3>
|
84 |
|
85 | A wild security screen appears!. Click on "advanced".
|
86 | <img src="/assets/firefox01.png" alt="firefox01">
|
87 |
|
88 | <h3>Step 2</h3>
|
89 | More details emerge! Click on "Add Exception".
|
90 | <img src="/assets/firefox02.png" alt="firefox02">
|
91 |
|
92 | <h3>Step 3</h3>
|
93 | In the dropdown click "Confirm Security Exception".
|
94 | <img src="/assets/firefox03.png" alt="firefox03">
|
95 |
|
96 | <h3>Step 4</h3>
|
97 | Success!
|
98 | <img src="/assets/firefox04.png" alt="firefox04">
|
99 | </details>
|
100 |
|
101 | <details>
|
102 | <summary>
|
103 | <b>Chrome Instructions</b>
|
104 | </summary>
|
105 | Click the "more details" dropdown, then click "proceed". Pull Request for
|
106 | screenshots welcome!
|
107 | </details>
|
108 |
|
109 | <details>
|
110 | <summary>
|
111 | <b>Safari Instructions</b>
|
112 | </summary>
|
113 | <h3>Step 1</h3>
|
114 | A wild security screen appears! Click "Show Certificate".
|
115 | <img src="/assets/safari01.png" alt="safari01">
|
116 |
|
117 | <h3>Step 2</h3>
|
118 | More details emerge! Check "Always trust 'localhost'…".
|
119 | <img src="/assets/safari02.png" alt="safari02">
|
120 |
|
121 | <h3>Step 3</h3>
|
122 | The box is checked! Click "Continue".
|
123 | <img src="/assets/safari03.png" alt="safari03">
|
124 |
|
125 | <h3>Step 4</h3>
|
126 | A box is asking you for your crendentials. Fill them in, and hit "Enter".
|
127 |
|
128 | <h3>Step 5</h3>
|
129 | Success!
|
130 | <img src="/assets/safari04.png" alt="safari04">
|
131 | </details>
|
132 |
|
133 | ## Optimizations
|
134 | Bankai applies lots of optimizations to projects. Generally you won't need to
|
135 | care how we do this: it's lots of glue code, and not necessarily pretty. But it
|
136 | can be useful to know which optimizations we apply. This is a list:
|
137 |
|
138 | ### JavaScript
|
139 | - __[nanohtml][]:__ Optimize `choo` HTML code so it runs significantly faster in the
|
140 | browser.
|
141 | - __[glslify][]:__ Adds a module system to GLSL shaders.
|
142 | - __[brfs][]:__ Statically inline calls to `fs.readFile()`. Useful to ship assets
|
143 | in the browser.
|
144 | - __[envify][]:__ Allow environment variables to be used in the bundle. Especially
|
145 | useful in combination with minification, which removes unused code paths.
|
146 | - __[split-require][]:__ Lazy load parts of your application using the
|
147 | [`require('split-require')`][split-require] function.
|
148 | - __[babelify][]:__ Bring the latest browser features to _all_ browsers. See
|
149 | [our babel section](#babel) for more details.
|
150 |
|
151 | And bankai uses [tinyify][], which adds the following optimizations:
|
152 |
|
153 | - __[browser-pack-flat][]:__ Remove function wrappers from the bundle, making
|
154 | the result faster to run and easier to minify.
|
155 | - __[bundle-collapser][]:__ Remove all pathnames from inside the bundle, and
|
156 | replace them with IDs. This not only makes bundles smaller, it prevents
|
157 | details from your local dev setup leaking.
|
158 | - __[common-shakeify][]:__ Remove unused JavaScript code from the bundle. Best
|
159 | known as _dead code elimination_ or _tree shaking_.
|
160 | - __[unassertify][]:__ Remove all `require('assert')` statements from the code.
|
161 | Only applied for production builds.
|
162 | - __[uglifyify][]:__ Minify the bundle.
|
163 |
|
164 | ### CSS
|
165 | - __[sheetify][]:__ extract all inline CSS from JavaScript, and include it in
|
166 | `bundle.js`.
|
167 | - __[purifyCSS][purify-css]:__ removes unused CSS from the project.
|
168 | - __[cleanCSS][clean-css]:__ minify the bundle.
|
169 |
|
170 | ### HTML
|
171 | - __[inline-critical-css][]:__ extract all crititical CSS for a page into the
|
172 | `<head>` of the document. This means that every page will be able to render
|
173 | after the first roundtrip, which makes for super snappy pages.
|
174 | - __async load scripts:__ loads scripts in the background using the
|
175 | [`defer`](https://devdocs.io/html/attributes#defer-attribute) attribute.
|
176 | - __async load styles:__ loads styles in the background using the
|
177 | [`preload`](https://devdocs.io/html/attributes#preload-attribute) attribute.
|
178 | - __async load styles:__ preloads fonts in the background using the
|
179 | [`preload`](https://devdocs.io/html/attributes#preload-attribute) attribute.
|
180 | - __server render:__ server renders Choo applications. We're welcome to
|
181 | supporting other frameworks too. PRs welcome!
|
182 | - __manifest:__ includes a link to `manifest.json` so the application can be
|
183 | installed on mobile.
|
184 | - __viewport:__ defines the right viewport dimensions to make applications
|
185 | accessible for everyone.
|
186 | - __theme color:__ sets the theme color defined in `manifest.json` so the
|
187 | navigator bar on mobile is styled on brand.
|
188 | - __title:__ sets the right title on a page. Either extracts it from the
|
189 | application (choo only, for now) or uses whatever the title is in
|
190 | `manifest.json`.
|
191 | - __live reload:__ during development, we inject a live reload script.
|
192 |
|
193 | ## Configuration
|
194 | The Bankai CLI doesn't take any flags, other than to manipulate how we log to
|
195 | the console. Configuring Bankai is done by modifying `package.json`.
|
196 |
|
197 | Bankai is built on three technologies: [`browserify`][browserify],
|
198 | [`sheetify`][sheetify], and [`documentify`][documentify]. Because these can be
|
199 | configured inside `package.json` it means that Bankai itself can be configured
|
200 | from there too. Also if people ever decide to switch from the command line to
|
201 | JavaScript, no extra configuration is needed.
|
202 |
|
203 | ```json
|
204 | {
|
205 | "name": "my-app",
|
206 | "browserify": {
|
207 | "transform": [
|
208 | "some-browserify-transform"
|
209 | ]
|
210 | },
|
211 | "sheetify": {
|
212 | "transform": [
|
213 | "some-sheetify-transform"
|
214 | ]
|
215 | },
|
216 | "documentify": {
|
217 | "transform": [
|
218 | "some-documentify-transform"
|
219 | ]
|
220 | }
|
221 | }
|
222 | ```
|
223 |
|
224 | ### Custom HTML
|
225 | By default, Bankai starts with an empty HTML document, injecting the tags
|
226 | mentioned [above](#html). You can also create a custom template as `index.html`,
|
227 | and Bankai will inject tags into it instead.
|
228 |
|
229 | If you export your Choo app instance after doing `.mount()`, Bankai respects the
|
230 | mount location during server side rendering:
|
231 |
|
232 | ```js
|
233 | // app.js
|
234 | ...
|
235 | module.exports = app.mount('#app')
|
236 | ```
|
237 |
|
238 | ```html
|
239 | <!-- index.html -->
|
240 | ...
|
241 | <body>
|
242 | <div id="app"></div>
|
243 | <div id="footer">© 2018</div>
|
244 | </body>
|
245 | ...
|
246 | ```
|
247 |
|
248 | ### Service Workers
|
249 | Bankai comes with support for service workers. You can place a service worker
|
250 | entry point in a file called `sw.js` or `service-worker.js`. Bankai will output
|
251 | a browserify bundle by the same name.
|
252 |
|
253 | You can easily register service workers using
|
254 | [choo-service-worker](https://github.com/choojs/choo-service-worker):
|
255 | ```js
|
256 | app.use(require('choo-service-worker')())
|
257 | ```
|
258 |
|
259 | choo-service-worker defaults to `/sw.js` for the service worker file name. If
|
260 | you named your service worker `service-worker.js` instead, do:
|
261 | ```js
|
262 | app.use(require('choo-service-worker')('/service-worker.js'))
|
263 | ```
|
264 |
|
265 | Service workers have access to some environment variables:
|
266 | * __process.env.STYLE_LIST:__ An array of URLs to stylesheet files.
|
267 | * __process.env.SCRIPT_LIST:__ An array of URLs to script files.
|
268 | * __process.env.ASSET_LIST:__ An array of URLs to assets.
|
269 | * __process.env.DOCUMENT_LIST:__ An array of URLs to server-rendered routes.
|
270 | * __process.env.MANIFEST_LIST:__ An array containing the URL to the manifest
|
271 | file.
|
272 | * __process.env.FILE_LIST:__ An array of URLs to assets and routes. This can
|
273 | be used to add all your app's files to a service worker cache.
|
274 |
|
275 | ## HTTP
|
276 | Bankai can be hooked up directly to an HTTP server, which is useful when
|
277 | working on full stack code.
|
278 | ```js
|
279 | var bankai = require('bankai/http')
|
280 | var http = require('http')
|
281 | var path = require('path')
|
282 |
|
283 | var compiler = bankai(path.join(__dirname, 'client.js'))
|
284 | var server = http.createServer(function (req, res) {
|
285 | compiler(req, res, function () {
|
286 | res.statusCode = 404
|
287 | res.end('not found')
|
288 | })
|
289 | })
|
290 |
|
291 | server.listen(8080, function () {
|
292 | console.log('listening on port 8080')
|
293 | })
|
294 | ```
|
295 |
|
296 | ## Babel
|
297 | Not all browsers support all of the Web Platform's features. So in order to use
|
298 | newer features on older browsers, we have to find a solution. The best solution
|
299 | out there at the moment is Babel.
|
300 |
|
301 | [Babel](https://babeljs.io/) is a plugin-based JavaScript compiler. It takes
|
302 | JavaScript in, and outputs JavaScript based for the platforms you've decided to
|
303 | target. In Bankai we target the last 2 versions of FireFox, Chrome and Edge,
|
304 | and every other browser that's used by more than 1% of people on earth. This
|
305 | includes IE11. And if you have different opinions on which browsers to use,
|
306 | Bankai respects `.babelrc` and [`.browserslistrc`](https://github.com/ai/browserslist) files.
|
307 |
|
308 | Some newer JavaScript features require loading an extra library; `async/await`
|
309 | being the clearest example. To enable such features, the `babel-polyfill`
|
310 | library needs to be included in your application's root (e.g. `index.js`).
|
311 |
|
312 | ```js
|
313 | require('babel-polyfill')
|
314 | ```
|
315 |
|
316 | We don't include this file by default in Bankai, because it has a significant
|
317 | size overhead. Once Babel includes only the language features you're using,
|
318 | we'll work to include `babel-polyfill` by default.
|
319 |
|
320 | ## Events
|
321 | ### `compiler.on('error', callback(nodeName, edgeName, error))`
|
322 | Whenever an internal error occurs.
|
323 |
|
324 | ### `compiler.on('change', callback(nodeName, edgeName, state))`
|
325 | Whenever a change in the internal graph occurs.
|
326 |
|
327 | ## API
|
328 | ### `compiler = bankai(entry, [opts])`
|
329 | Create a new bankai instance. Takes a path to a JavaScript file as the first
|
330 | argument. The following options are available:
|
331 |
|
332 | - __opts.quiet:__ Defaults to `false`. Don't output any data to `stdout`. Useful
|
333 | if you have your own logging system.
|
334 | - __opts.watch:__ Defaults to `true`. Watch for changes in the source files and
|
335 | rebuild. Set to `false` to get optimized bundles.
|
336 | - __babelifyDeps:__ Defaults to true. Transform dependencies with babelify.
|
337 |
|
338 | ### `compiler.documents(routename, [opts], done(err, { buffer, hash }))`
|
339 | Output an HTML bundle for a route. Routes are determined based on the project's
|
340 | router. Pass `'/'` to get the default route.
|
341 |
|
342 | - __opts.state:__ Will be passed the render function for the route, and inlined
|
343 | in the `<head>` of the body as `window.initialState`.
|
344 |
|
345 | ### `compiler.scripts(filename, done(err, { buffer, hash }))`
|
346 | Pass in a filename and output a JS bundle.
|
347 |
|
348 | ### `compiler.assets(assetName, done(err, { buffer, hash }))`
|
349 | Output any other file besides JS, CSS or HTML.
|
350 |
|
351 | ### `compiler.styles(name, done(err, { buffer, hash }))`
|
352 | Output a CSS bundle.
|
353 |
|
354 | ### `compiler.manifest(done(err, { buffer, hash }))`
|
355 | Output a `manifest.json`.
|
356 |
|
357 | ### `compiler.serviceWorker(done(err, { buffer, hash }))`
|
358 | Output a service worker.
|
359 |
|
360 | ### `compiler.close()`
|
361 | Close all file watchers.
|
362 |
|
363 | ## License
|
364 | Apache License 2.0
|
365 |
|
366 | [babelify]: https://github.com/babel/babelify
|
367 | [brfs]: https://github.com/browserify/brfs
|
368 | [browser-pack-flat]: https://github.com/goto-bus-stop/browser-pack-flat
|
369 | [browserify]: https://github.com/browserify/browserify
|
370 | [bundle-collapser]: https://github.com/substack/bundle-collapser
|
371 | [clean-css]: https://github.com/jakubpawlowicz/clean-css
|
372 | [common-shakeify]: https://github.com/browserify/common-shakeify
|
373 | [documentify]: https://github.com/stackhtml/documentify
|
374 | [envify]: https://github.com/hughsk/envify
|
375 | [glslify]: https://github.com/glslify/glslify
|
376 | [inline-critical-css]: https://github.com/stackcss/inline-critical-css
|
377 | [nanohtml]: https://github.com/choojs/nanohtml
|
378 | [purify-css]: https://github.com/purifycss/purifycss
|
379 | [sheetify]: https://github.com/stackcss/sheetify
|
380 | [split-require]: https://github.com/goto-bus-stop/split-require
|
381 | [tinyify]: https://github.com/browserify/tinyify
|
382 | [uglifyify]: https://github.com/hughsk/uglifyify
|
383 | [unassertify]: https://github.com/unassert-js/unassertify
|
384 |
|
385 | [0]: https://img.shields.io/badge/stability-experimental-orange.svg?style=flat-square
|
386 | [1]: https://nodejs.org/api/documentation.html#documentation_stability_index
|
387 | [2]: https://img.shields.io/npm/v/bankai.svg?style=flat-square
|
388 | [3]: https://npmjs.org/package/bankai
|
389 | [4]: https://img.shields.io/travis/choojs/bankai/master.svg?style=flat-square
|
390 | [5]: https://travis-ci.org/choojs/bankai
|
391 | [6]: https://img.shields.io/codecov/c/github/choojs/bankai/master.svg?style=flat-square
|
392 | [7]: https://codecov.io/github/choojs/bankai
|
393 | [8]: http://img.shields.io/npm/dm/bankai.svg?style=flat-square
|
394 | [9]: https://npmjs.org/package/bankai
|
395 | [10]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square
|
396 | [11]: https://github.com/feross/standard
|