spa
v0.3.4
Published
Single-page applications builder with continuous integration, granular updates and loader.
Downloads
143
Maintainers
Readme
S ingle P age A pplications builder with continuous integration, granular updates and loader.
The general idea is to calculate dependencies offline and then eagerly cache/load modules in predefined order. Also we can detect which files are changed and do partial updates.
Preferred module format is CommonJS
.
Advantages:
- no async dependency resolution
- no AMD wrappers
- less moving parts and mutable state
- less data duplication and possible conflicts
- loader code is separate from application code
- loading progress is easy to visualize
Running builder
All options are stored in config file. So the only command line parameter is a config file path.
spa -c spa.yaml
Options
Config file is a dict
in YAML or JSON format with the following keys:
root(required) - path where the file search will start, may be relative to config file itself.
extensions(optional) - files to consider as modules, [".js"]
by default.
excludes(optional) - files to ignore, empty by default.
List may contains wildcards/globs, eg. ./something/**/test/*.js
. Paths are relative to root path.
paths(optional) - path aliases to use during module name resolution.
Example:
root: "/testimonial/"
paths:
vendor: "./lib/contrib"
This allows to use module /testimonial/lib/contrib/b.js
from file /testimonial/src/a.js
as require('vendor/b.js')
grab(optional) - do try grab all dependencies suppressing ExternalDependencyErrors.
Can walk inside node_modules
with commonjs
rules recursively. Default value is false
.
hosting(required for web usage) - similar dict which specifies how to remap paths to URLs.
Keys - rules as in excludes
, where you can select path fragments in brackets,
values - URI format where selected fragments will be substitutes.
If you want files to be included in cache manifest, they need to match at least one pattern in hosting
as well.
Example:
hosting:
"./lib/(**/*.js)": "http://myapp.com/$1"
File ./lib/app/main.js
will be loaded http://myapp.com/app/main.js
.
hosting_map(optional) - relative path to output hosting map file. Can be omitted.
Hosting map format:
{
"version": 1,
"files": {
"relative/hosting/path1.js": "node_modules/source/path1.js",
},
"manifest": {
"url": "relative/hosting/manifest.json",
"path": "node_modules/source/path1.js"
},
"index": {
"url": "http://site.com/hosting/index.html",
"path": "build/index.html"
}
}
loaders(optional) - rules which describe what module formats JS files use.
Keys - rules as in excludes
, values - format types. Available formats:
- cjs -
CommonJS
- amd -
AMD
orUMD
. - junk - module needs to mutate
window
- raw - local variables from module needs to be in
global
context (like<script>
)
default_loader(optional) - loader for files not matched by loaders. Default value is cjs
.
manifest(optional) - relative path to loader manifest. Can be omitted.
bundle(optional) - relative path where bundle will be stored. Bundle used at first run to speed up downloading. Can be omitted.
hash_func(optional) - has function to be used in manifest
and appcache
generation process. Value may be md5
, ripemd160
, sha1
, sha224
, sha256
, sha3
, sha384
, sha512
. Default value is md5
. New hash function could be easily added as assets to builder. Hack into Cakefile
for mere information.
randomize_urls(optional) - this parameter to be transletad into loader thru index_template
. If true
loader will add some random characters to URLs for manifest and application files to suppress caching.
pretty(optional) - pretty-print manifest and other json files. Default is false
.
print_roots(optional) - output list of root modules no one depends on. Default is true
.
print_stats(optional) - output statistics about analyzed modules. Default is true
.
index(optional) - relative path to bootstrap html file. Loader and its dependencies (but not app dependencies) will be baked into this file. Can be omitted.
appcache(optional) - relative path to HTML5 AppCache Manifest.
cached(optional) - paths to other files to include in appcache. URLs are remapped according to hosting dict.
assets(optional) - path to customizable builder templates
- appcache_template - template to generate
appcache
. Can includecached
list. - index_template - template to generate
index
. You can useassets
to include them, except theindex_template
itself :)
coding_func(optional) - dictionary that defines parameters of encoding function. Viable parameters depends on particular function. The only necessary parameter is name
which value may be aes-ccm
, aes-gcm
, aes-ocb2
.
Example:
coding_func:
name: aes-gcm
password: babuka
iter: 1000
ks: 128
ts: 128
copying(required for coding_func
) - same set of rules as in hosting
but used together with coding_func
to store encoded files.
Enabling encryption could possibly overwrite your source files if copying rules was not properly specified. Use this feature with caution. Ensure that you've commited changes into restorable repository before you build.
cache_file(optional) - path to cache-file. This option is also necessary for using some of coding_func
. To preserve incremental updates feature we have to query some data from previous builds. Default value is .spacache
. This path is relative to root
Example:
copying:
"./lib/(**/*.js)": "./build/$1"
Example
root: "./testimonial/"
index: index.html
appcache: main.appcache
manifest: manifest.json
paths:
vendor: "./lib/contrib"
assets:
index_template: /assets/index.tmpl
appcache_template: /assets/appcache.tmpl
hash_func: sha256
cached:
- /a.js
hosting:
"./(**/*.*)": "http://127.0.0.1:8010/$1"
hosting_map: hosting.json
bundle: "./bundle.js"
coding_func:
name: aes-gcm
password: babuka
iter: 1000
ks: 128
ts: 128
copying:
"./lib/(**/*.js)": "./build/$1"
grab: true
Alternatives
Read this book Single page apps in depth!
Other modules you should definitely look at:
Development
Report new issues. I'm open for collaboration.
Installing from GitHub
npm install git://github.com/Evgenus/spa.git#stable
Project structure
spa
├───bin executable builder file
├───bower_components loader dependencies; installs with `bower`
├───lib compiled builder files
│ └───assets builder assets (templates, compiled loader, loader assets)
│ ├───decode prepared decoding functions for using in loader
│ ├───encode prepared encoding functions for using in builder
│ └───hash wrapped and prepared hash-functions code
├───node_modules builder dependencies; installs with `npm`
├───src coffee-script source code
│ ├───assets various assets templates and helpers sources
│ ├───builder source code of builder
│ ├───bootstrap source code of bootstrap code with default callbacks and UI visualization
│ └───loader source code of loader
└───tests tests for builder and loader
Installing dependencies
npm install
bower install
Compiling project
cake build
Testing
Tests require devDependencies to be installed! Tests require Selenium Standalone Server
.
npm test
Events and API methods
To subscribe for event you simply need to assign handler into loader instance.
loader.onEventName = function Handler(param1, param2) { /*....*/ }
load() - starts loading current version of hosted application.
Possible generated events:
NoManifest(error)
- this event fires when there is no current version of application. Either the application is being started for the first time or previous download was unsuccessful. UsuallycheckUpdate
method should be called in the handler.EvaluationStarted(manifest)
- event fires when current version was found and about to be loaded. If handler returnsfalse
then loaded will not perform any further actions and halts. Parameters:manifest
- manifest of current version as an object.ModuleEvaluated(module)
- event fires for each successfully loaded module. Parameters:module
- loaded module descriptor (as inside of manifest).EvaluationError(module, error)
- fires if there was an error during module loading. All further loading could not be performed and loader halts. EventApplicationReady
will not be fired. Parameters:module
- problem module descriptor (some fields may be absent);error
- occurred error(some frequent errors are strictly typed).ApplicationReady(manifest)
- event notifies host application about its successfully loading. Inside handler application could start working and intercept control. Parameters:manifest
- current manifest.
checkUpdate() - checks server for newer version of application.
Returns false
if process of checking or updating already has been started, otherwise true
.
UpToDate(event, manifest)
- event fires if latest version of application was already downloaded. Parameters:manifest
- cuurent manifest.UpdateFound(event, manifest)
- event occurs if a newer version of the application was found. UsuallystartUpdate
should be called inside handler or user asked for confirmation before downloading new version files. Current version is assumed to be working at this time. Parameters:event
- the event object passed by browser as a result of the request;manifest
- the manifest of a new version.UpdateFailed(event, error)
- event occurs if for some of the reason a newer version could not be found or manifest of newer version is incorrect. It also occurs if current loader is outdated and not compatible with the new format of the manifest. Parameters:event
- the event object passed by browser as a result of the query (you can obtain network errors from it);error
- error arose during the analysis of the manifest of the newer version or downloading bundle (may benull
).
startUpdate() - initialize downloading of the newer version of the application accordingly to previously downloaded manifest.
Returns false
if process of updating already has been started, otherwise true
.
ModuleBeginDownload(module)
- event fires when each module is about to be downloaded. Parameters:module
- module descriptor object from newer version manifest.ModuleDownloadProgress(event, module)
- fires when individual module download progress changed. Parameters:event
- browser event (downloaded bytes, etc);module
- descriptor of module being downloaded (contains total length).TotalDownloadProgress(progress)
- total download progress.progress
is a hash with these fields:loaded_count
- number of modules already downloaded,total_count
- total number of modules,loaded_size
- amount of bytes downloaded,total_size
- total size of modules in bytes.ModuleDownloadFailed(event, module, error)
- event fires when module downloading was aborted, interrupted, or data checksum did not match. Parameters:event
- browser event,module
- module which failed to download,error
- contains error occured during module checking.ModuleDownloaded(module)
- occurs when module was successfully downloaded. Parameters:event
- browser event,module
- downloaded module.UpdateCompleted(manifest)
- occurs when all modules of the new version were successfully downloaded. The handler must returntrue
, if loader should accept new version, orfalse
if update should be postponed. You can inform user about update and request application restart at this point. If update is accepted it will be loaded at next application run (nextload
call). Parameters:manifest
- new version manifest.
dropData - remove current version and force data to be downloaded again. Useful in case of critical failures.
Copyright and license
Code and documentation copyright 2014 Eugene Chernyshov. Code released under the MIT license.