The alpha-strike web framework.
A framework with sane defaults, aiming to handle everything for you as automatically as possible.
new Lance( config )
What just happened:
- An HTTP server was started
- Compiled, minified, bundled and watched Stylus, CoffeeScript, CJSX, CSS, JS
- Saved to the static directory
- Populated the static asset directory at
- Assets like
robots.txtare copied over with their preserved directory structure.
- Assets like
- Set up request routing
- Began serving static assets from
- Began utlizing a templating engine in
- Began parsing http requests; forms, file transfers
All parts of Lance can be utilized outside of the config. Lance always utilizes promises for async operations.
See the ./config - effectively an API reference.
The minimal example:
Lance = require 'lance'lance =routes:"GET"'/:api(a|b|c|d)'consolelog 'ayyy' if orouteapi is 'a'oserve body: 'woo!'lanceinitializethen -> # Server is up!
The full example:
###The directory structure:/project//static//views/index.jadestyle.stylapp.coffee/images/image.pngserver.coffee (this)###Lance = require 'lance'lance =server:host: '0.0.0.0'port: 1337static: './static' # Automatically intercepts and serves static contenttemplater:findIn: './views'saveTo: './static'###Bundle up all Stylus/Css or Coffee/Js dependencies into a single fileby utilizing Stylus and browserify.###bundle:# destination : source"my/css/here.css": "style.styl""app.js": "app.coffee"templater:ext: '.jade'engine: require 'jade'# Routes can be defined after instantiation, outside of the config, toolancerouterget '/:api(a|b|c|d)'###`o` is a special options object containing request information in a pre-parsed manner. `o` is passed to all route requests in place of `req` and `res`.More info on this later.###if orouteapi is 'a'consolelog 'ayyy'# This will resolve to our ./project/views/index.jade fileo.template.view = 'index'###o.serve() serves a response based on either arguements passed to it or depending on properties in `o`.if `o.template.view` is set, the template will be renderedif `o.redirect` is set, a redirection will occurif neither are set, Lance serves JSON by default.You may also instead call `o.serveTemplate()`, `o.serveHttpCode()`, `o.serveJson()`, `o.serveRedirect()` or a basic `o.respond()`###oserve###This will build the templates then start the server, all depending on the config.###lanceinitializethen -># we're ready###Alternitavely...There is a choice between `lance.initialize()`, which initializes everything in order, and manually initializing aspects of lance for more control.###lancetemplaterinitializethen -># The bundles have been compiled to:# ./projectDirectory/static/style.css# ./projectDirectory/static/app.js# from the ./projectDirectory/views directory.# and will be watched for changes (and any of their dependencies)# then recompiled automaticallylancestartthen -># we're ready###The new directory structure:/project//static//my//css/here.cssapp.js/images/image.png/views/index.jadestyle.stylapp.coffee/images/image.pngserver.coffee (this)###
Requests from a http server normally use
request parameters. Lance supplies an object as outlined below:
###Assuming you visited:GET###lancerouterget '/:api(a|b|c|d)''aRouteName'# HTTP request objectoreq# HTTP response objectores# Response HTTP codeocode is 200# Response headersoheaders is 'content-type': 'text/html; charset=utf-8'# Fallback body to respond with if not template is usedobody is ''# Sent as JSON for JSON responsesojson is# Relative or absolute path to a templateotemplateview is ''# Local variable for the templateotemplatedata is# Optional lance.Templater instanceotemplatetemplater is olancetemplater# Redirects to this as a path if setoredirect is ''# Used as a GET response query if redirectingoredirectQuery is# Parsed query, whether it be GET, POST etc.oquery istest:a: '1'# Any filesofiles is# Example file'exampleFile':field : 'exampleFile'filename : 'file.txt'encoding : 'utf8'mimetype : 'text/plain'ext : 'txt'# Temporary file path, saved to the OS's temp directory# Will be auto deleted after a timerfile : tempFilePath# Call this to delete the temporary filedelete : Functiontruncated : falseomethod is 'GET'oroute ispath : api: 'b'splats :name : 'aRouteName'callback : ThisFunctionpattern : '/:api(a|b|c|d)'regex : /./ # Final regex from patternopath is oroutepathosplats is oroutesplatsocookies is 'cookies' oreqores# These properties above are also passed into a template, accessable under the "o" propertytemplate = view: './someTemplate'data: woo: 1template is otemplateoserve templateoserve###When `o.serve` is called without parameters it will execute this logic:if o.redirecto.serveRedirect( o.redirect, o.redirectQuery )elseif o.template.viewo.serveTemplate()elseo.serveJson()###
You can specify your own templater middleware. If none are specified, then Lance will default to checking whether
ect is installed and will use that.
# Uses Jadetemplater:templater:ext: '.jade'engine: require 'jade'options: # Supplied to the engine on instantiation# Uses ECT.js if `ect` is installedtemplater:templater:
For these features to become avaliable, simply make sure they're installed.
browserifyfor bundling coffee/js
coffee-reactifyfor embedding JSX into Coffee
coffeeifyonly normal coffeescript
uglify-jsfor js compression
lactatefor static file serving
Stylus is compulsary if you're going to bundle css assets; because Stylus can exist as pure css with the benefit of the
@import bundling syntax. Any plain CSS file is concatenated, it is not resolved to an
Lance handles these mostly automatically:
- CSS and Stylus
- Static assets such as images, json, robots.txt etc.
- Bundles are rendered to the static directory
- Bundles are watched for changes, then rerendered
- Assets files are copied over to the static directory
- Assets files are watched for changes, then resaved
- Directories are watched for new directories and files
By default all static assets that match the regexp (found in the config's
templater.assets.match) will be copied over to the static directory.
- For some filetypes, such as images, this means they can also be optimized.
- TODO: Impliment asset stream hooking
templater:findIn: './views'saveTo: './static'###true by default, this causes `assets` to keep their directory structure inside the saveTo folder.###preserveDirectory: truebundle:# destination : source"style.css" : "style.styl""app.js" : "app.coffee"
The result is that the static directory will always have only what you want to make public, in one place, with a directory structure that will mirror your views.
Cloned via the github repo, tests are manual in nature at the moment. Due to the complexity of a web server, they consist of scenarios for which must be manually tested and interacted with in the browser, currently.
All dependencies have unit tests.
Upgrading from 1.x.x
__ / /___ _____ ________ / / __ `/ __ \/ ___/ _ \ / / /_/ / / / / /__/ __/ /_/\__/_/_/ /_/\___/\___/