Skip to content

Commit

Permalink
feat: add bankai start command
Browse files Browse the repository at this point in the history
  • Loading branch information
marionebl committed Aug 9, 2016
1 parent a61e0c1 commit 7701ee7
Show file tree
Hide file tree
Showing 13 changed files with 461 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
node_js:
- "0.12"
- "4"
- "6"
sudo: false
language: node_js
script: "npm run test:cov"
Expand Down
66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,72 @@ Return a `css` stream using [sheetify](https://github.com/stackcss/sheetify).
Return a `js` stream. `src` is the bundle entry file. `opts` are passed
directly to `browserify`

## CLI

```
$ node ./bin/ --help
DIY asset server
Usage
$ bankai <command> [options]
Commands
start Start a bankai server
Options
-e, --entry=<id> Resolve <id> from cwd and use as entry module [default: .]
Entry module is expected to export `() -> app`
-p, --port=<n> Bind bankai to <n> [default: 1337]
-o, --optimize Optimize the page and all assets served by bankai [default: false]
-b, --browse=<app> Browse the page served by bankai with <app> [default: false]
--html.entry=<uri> Serve client js at <uri> [default: bundle.js]
--html.css=<uri> Serve client css at <uri> [default: bundle.css]
--html.favicon Disable favicon [default: true]
--html.title Title to use for page
--html.lang Lang attribute to use [default: en]
--css.use sheetify plugins to use
--js.<opt>=<value> Pass key <opt> with <value> to browserify
Examples
$ bankai start
Started bankai for index.js on http://localhost:1337
$ bankai start --entry=basic
Started bankai fro basic/index.js on http://localhost:1337
$ bankai start --port=3000
Started bankai for index.js on http://localhost:3000
$ bankai start --open
Started bankai for index.js on http://localhost:1337
Opening http://localhost:1337 with default browser
$ bankai start --open Safari
Started bankai for index.js on http://localhost:1337
Opening http://localhost:1337 with system browser
$ bankai start --html.title bankai
Started bankai for index.js on http://localhost:1337
$ bankai start --css.use sheetify-cssnext
Started bankai for index.js on http://localhost:1337
$ bankai start --js.fullPaths=false
```

## Examples
Projects showing exemplary usage are provided. Install root project dependencies,
example project dependencies and execute `npm start` to start an example.

- [Basic](./example/basic) - Showing default settings, Hot Module Replacement
```
npm install
cd example/basic
npm install
npm start
```

## See Also
- [budo](https://www.npmjs.com/package/budo)
- [tiny-lr](https://github.com/mklabs/tiny-lr)
Expand Down
146 changes: 146 additions & 0 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/env node
'use strict'

const meow = require('meow')

const commands = {
start: require('./start')
}

const commandNames = Object.keys(commands)
const commandList = commandNames.join(', ')
const unknowns = []
const alias = {
entry: ['e'],
optimize: ['o'],
browse: ['b'],
port: ['p']
}

const cli = meow(`
Usage
$ bankai <command> [options]
Commands
start Start a bankai server
Options
-e, --entry=<id> Resolve <id> from cwd and use as entry module [default: .]
Entry module is expected to export () -> app
-p, --port=<n> Bind bankai to <n> [default: 1337]
-o, --optimize Optimize the page and all assets served by bankai [default: false]
-b, --browse=<app> Browse the page served by bankai with <app> [default: false]
--html.entry=<uri> Serve client js at <uri> [default: bundle.js]
--html.css=<uri> Serve client css at <uri> [default: bundle.css]
--html.favicon Disable favicon [default: true]
--html.title Title to use for page
--html.lang Lang attribute to use [default: en]
--css.use sheetify plugins to use
--js.<opt>=<value> Pass key <opt> with <value> to browserify
Examples
$ bankai start
Started bankai for index.js on http://localhost:1337
$ bankai start --entry=basic
Started bankai fro basic/index.js on http://localhost:1337
$ bankai start --port=3000
Started bankai for index.js on http://localhost:3000
$ bankai start --open
Started bankai for index.js on http://localhost:1337
Opening http://localhost:1337 with default browser
$ bankai start --open Safari
Started bankai for index.js on http://localhost:1337
Opening http://localhost:1337 with system browser
$ bankai start --html.title bankai
Started bankai for index.js on http://localhost:1337
$ bankai start --css.use sheetify-cssnext
Started bankai for index.js on http://localhost:1337
$ bankai start --js.fullPaths=false
`,
{
alias: alias,
string: [
'entry',
'html.entry',
'html.css',
'html.title',
'css.use',
'js.noParse',
'js.transform',
'js.ignoreTransform',
'js.plugin',
'js.extensions',
'js.basedir',
'js.paths',
'js.commondir',
'js.builtins',
'js.bundleExternal',
'js.browserField',
'js.insertGlobals',
'js.standalone',
'js.externalRequireName'
],
boolean: [
'optimize',
'js.fullPaths',
'js.debug'
],
unknown: function (flag) {
if (flag in commands) {
return
}
unknowns.push(flag)
}
})

const aliasNames = Object.keys(alias)
.reduce(function (r, i) {
return r.concat(alias[i])
}, [])

function main (commandName, options, cb) {
let error

if (typeof commandName !== 'string') {
error = new Error(`Missing command parameter. Available commands: ${commandList}`)
error.cli = true
return cb(error)
}

if ((commandName in commands) === false) {
error = new Error(`Unknown command ${commandName}. Available commands: ${commandList}`)
error.cli = true
return cb(error)
}

if (unknowns.length > 0) {
error = new Error(`Unkown flags detected: ${unknowns.join(', ')}`)
error.cli = true
return cb(error)
}

// Remove short hand pointers
aliasNames.forEach(function (aliasName) {
delete options[aliasName]
})

const command = commands[commandName]
command(options, cb)
}

main(cli.input[0], cli.flags, error => {
if (error) {
if (error.cli) {
console.error(`${cli.help}\n${error.message}`)
return process.exit(1)
}
throw error
}
})
91 changes: 91 additions & 0 deletions bin/start.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
const http = require('http')
const path = require('path')
const browserify = require('browserify')
const getServerPort = require('get-server-port')
const opn = require('opn')
const resolve = require('resolve')
const serverRouter = require('server-router')
const stringToStream = require('string-to-stream')
const xtend = require('xtend')

const defaults = {
port: 1337,
browse: false,
optimize: false,
entry: '.',
html: {},
css: {},
js: {}
}

const cwd = process.cwd()

// resolve a path according to require.resolve algorithm
// string -> string
function resolveEntryFile (relativePath) {
const first = relativePath.charAt(0)
const entry = ['.', '/'].includes(first) ? relativePath : './' + relativePath
return resolve.sync(entry, {basedir: cwd})
}

// Start a development server
function start (options, cb) {
const bankai = require('../')({
optimize: options.optimize
})

const settings = xtend({}, defaults, options)
const callback = cb || function () {}

const entryFile = resolveEntryFile(settings.entry)
const relativeEntry = path.relative(cwd, entryFile)
const router = serverRouter('/404')

router.on('/404', (req, res) => {
res.statusCode = 404
return stringToStream('Not found')
})

if (settings.html) {
const html = bankai.html(settings.html)
router.on('/:path', html)
router.on('/', html)
}

if (settings.css) {
const css = bankai.css(settings.css)
router.on(settings.html.css || '/bundle.css', css)
}

const js = bankai.js(browserify, entryFile, settings.js)
router.on(settings.html.entry || '/bundle.js', js)

const server = http.createServer((req, res) => {
router(req, res).pipe(res)
})

server.listen(settings.port, () => {
const port = getServerPort(server)

const address = ['http://localhost', port].join(':')
console.log('Started bankai for', relativeEntry, 'on', address)

if (settings.browse) {
const app = typeof settings.open === 'string' ? settings.open : null

const appName = typeof settings.open === 'string'
? settings.open
: 'system browser'
console.log('Opening', address, 'with', appName)

opn(address, {app: app})
.catch(error => {
console.error(error)
})
}

callback()
})
}

module.exports = start
3 changes: 3 additions & 0 deletions example/basic/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
h1 {
color: red;
}
53 changes: 53 additions & 0 deletions example/basic/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const choo = require('choo')
const html = require('choo/html')
const sheetify = require('sheetify')

sheetify('normalize.css')
const sheet = sheetify('./index.css')

const application = choo()

application.model({
state: {title: 'Not quite set yet!'},
reducers: {
update: (data, state) => ({ title: data })
}
})

const mainView = (state, prev, send) => html`
<main class="${sheet}">
<h1>Title: ${state.title}</h1>
<input
type="text"
value=${state.title}
oninput=${(e) => send('update', e.target.value)}/>
<button>Hello!</button>
</main>
`

const testView = (state, prev, send) => html`
<main class="${sheet}">
<h1>Test: ${state.title}</h1>
<input
type="text"
value="${state.title}"
oninput=${(e) => send('update', e.target.value)}/>
</main>
`

application.router((route) => [
route('/', mainView),
route('/test', testView)
])

if (module.parent) {
// Server-side
module.exports = application
} else {
// Client-side
const tree = application.start()

if (tree) {
document.body.appendChild(tree)
}
}
19 changes: 19 additions & 0 deletions example/basic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "bankai-examples-basic",
"version": "1.0.0",
"description": "Basic example of using bankai",
"main": "index.js",
"scripts": {
"start": "node ../../bin start"
},
"license": "MIT",
"dependencies": {
"choo": "^3.2.0",
"nanoajax": "^0.4.3",
"normalize.css": "^4.2.0",
"resolve": "^1.1.7",
"sheetify": "^5.0.5",
"sheetify-cssnext": "^1.0.7",
"yo": "^1.8.4"
}
}
Loading

0 comments on commit 7701ee7

Please sign in to comment.