- can be used in any environment (Ruby, Python, HTML).
- has automatic dependency resolution, both global and relative
- can be accessed from any page or server, even a vanilla HTML page
- scripts are included simply by using <script> tag
- javascripts are provided either as
- a single concatenated script (e.g. for production)
- multiple separate scripts (e.g. for debugging in development)
- Entirely cross browser and works well with tools such as Firebug
Interacting with Bean Server
A Sinatra server (perhaps it should be a Node server
acts as a system wide provider for the javascript.
I tend to run the server under Passenger, and have it associated with http://beans/
http://beans/
- Returns HTML page listing each file in the repos
http://beans/?.js
- Returns HTML page showing each file who’s path matches “.js”
http://beans/path/to/my_file.ext
- Finds a file with path /path/to/my_file.ext and returns it inline
- This can be js, css, jpg or any file
- No dependency resolution will occur
- If there’s more than one repo that matches, it will return the first it finds
http://beans/=lib_a.js,lib_b.js
- Searches the repo for two files, who’s paths matches lib_a.js and lib_b.js
- If the files are javascripts, it will resolve dependencies (see below).
- In this instance, let’s say that
- lib_a depends on dep1, dep2
- lib_b depends on dep1, dep3
- Therefore the final scripts to load in order will be
- dep1, dep2, lib_a, dep3, lib_b
- There are multiple scripts to return, it will return a single script that writes out inclusion via document.write:
- <script src=’http://beans/path/to/dep1.js’ ></script>
- <script src=’http://beans/path/to/dep2.js’ ></script>
- <script src=’http://beans/path/to/lib_a.js’ ></script>
- <script src=’http://beans/path/to/dep3.js’ ></script>
- <script src=’http://beans/path/to/lib_b.js’ ></script>
http://beans/=lib_a.js,lib_b.js?concat=true
- If the option concat=true is passed, the bean-server will return the scripts as a single concatenated script.
http://beans/=lib_a.js,lib_b.js?paths=/abs/path,/abs/another/path
- The paths option allows multiple temporary (absolute) load path
Dependencies
The syntax for declaring dependencies is the similar as Sprockets, ie they are entered within inline comments.
A slight difference is that the comments must be placed at the top of the file, before any code. This is because of the way Beans can provide each script separately and also speeds up the script parsing as the server can break as soon as a non-code line is reached.
//= require <my_lib>
This will do a global search in all load paths for a file matching my_lib.js and include it before this script
//= require “relative/path/to/my_file”
This will look for a file relatively to the current script.
Installation
git clone git://github.com/weepy/bean-server.git
cd bean-server
ruby app.rb
point browser at http://localhost:4567/test-beanz.html
Config
Currently there’s a simple settings.rb file that only contains the location of various repos
Javascript, CSS and HTML
The beans server is designed for serving particular javascript, however it can also search for and server css and HTML. E.g. http://beans/qunit/lib/test-suite.css will server up the Qunit test suite css. This is useful, among other things for writing and running tests in HTML to be bundled along with the source.
Comparison with other systems
Sprockets tries to achieve similar but not identical goals:
- Beans uses a similar dependancy syntax as Sprockets
- Beans is not tied to any language or framework, whereas Sprockets is invoked from Ruby
- Sprockets includes the Javascript by concatenating into one single file. Beans can do this or optionally include each script as a separate file for ease of debugging.
- Beans doesn’t (yet?) support providing assets from javascripts, although the server can search and return any other type of file
- CommonJS provides a framework using require and exports
- It is functionally different from Beans as it inserts the files into a closure, where as Beans evaluates everything in the global scope
- CommonJS is suited more to server side development, whereas Beans is aimed at client side development (tho it can be used server side e.g. I’m using it on ChessTwit)
Project
Github: http://github.com/weepy/bean-server
Todo
Potential features that are not yet addressed:
- Versioning, ownership
- Canonical external resource (e.g. rubyforge, gemcutter)
- minification



