#nBob
Ex Machina's second generation frontend build tool, based on Node and V8, focussing on:
- Ease of use
- Includes local build server
- Shows build errors directly in browser
- Performance
- Incremental builds
- Multi-core processing
- Predictability
- Single mode (no development vs production)
- Build on browser reload
- Conciseness
- Minimal project configuration
- Efficient processor plugin API
See the releases page for a changelog.
Licensed under MIT License and Copyright Ex Machina.
Start by installing Node if you don't have that yet.
Then install nBob through NPM; open a terminal or command prompt and type the following on your command line:
On OS X and Linux:
$ sudo npm install -g nbob
On Windows:
> npm install -g nbob
If an update is available then nBob will notify you and you can update similarly:
$ sudo npm update -g nbob
Running nbob in your terminal with invalid or incomplete arguments will result in it's help being displayed:
nBob v<version>
Usage: nbob [options] <commands>
Commands:
init
nbob Create nbob-config.json
skeleton Copy skeleton files
browsers Create browserslist file
aws Create ~/.aws/credentials
update
api Update EM api directory
doc *Update doc directory
l10n Update l10n directory
lib *Update lib directory
endings Convert text file line endings
clean Remove build and dist directories
make
images
png Compress PNG images
html
l10n Localize texts
minify Minify HTML
templates Concatenate templates
hbs Compile Handlebars templates
css
less Compile LESS to CSS
post Post process CSS
js
style Analyze and Fix JS with JSCS
hint Analyze JS with JSHint
esnext Transpile ES6+ to ES5 with Babel
minify Minify JS
concat Concatenate JS files
amd Optimize EM AMD modules
test *Run tests
include Include files
substitute Substitute in file paths and text
dist Write files to dist directory
server Make and host files
deploy Make and copy to S3
Options:
-d, --dir Use specified working directory (default: <current working directory>)
-e, --env Use specified environment config overrides
-l, --level Use specified log level (spam/debug/info/ok/warn/error/silent) (default: info)
-o, --option Override specified option in config (e.g: -o server.port=8081)
-r, --reload *Run live-reload server on dist directory
-s, --sync *Run browser-sync server on dist directory
*) Not yet implemented
Note: Like options, commands can be abbreviated, per example:
Full length: nbob --env=staging update:api deploy
Abbreviated: nbob -e staging u:a d
Configuration consists of nBob package defaults (nbob-config.json) which can be extended and overridden by user defaults (~/.nbob/nbob-config.json
) and finally project configuration (<project>/nbob-config.json
).
These configuration files are JSON files with section keys, aside from a few special ones (nbob, project and envConfigMap), referring to the command that they define.
The active configuration can be further influenced by specifying options (--env and --option) on your command line.
Most configuration sections include a files
key that specifies an array of glob patterns for files to be included and excluded (by starting glob string with an exclamation mark !
).
For glob syntax details, please see the documentation of the used matcher: minimatch.
Most, if not all, files
configurations will be pre-configured to match the appropriate files by convention, but in some cases you will have to manually opt-in to using a command processor by adding files globs in your project configuration.
When one config object is extended by another then any new properties are added and any existing properties are overridden.
When one config array is extended by another then all items from the other array are added to the first.
However, when the extending array starts with the special item !!
then the original array is first emptied, effectively replacing the array.
Configuration values can contain substitution syntax, inspired by Mustache templating.
Example:
{
"make:js:concat": {
"files": [ "{lib,src}/**/*.min.js{,.map}" ],
"output": "{{project.name}}-{{project.version}}.min.js"
},
"make:js:amd": {
"files": [ "{{make:js:concat.output}}{,.map}" ],
"exports": []
}
}
Results in project name and version being filled in to generate the JS concat output filename and the AMD using that output filename as input.
Note: Substitution by non-string config object values is currently also supported using Mustache partial sytax, p.e: "files": "{{> update:l10n.files}}"
.
It is however a deprecated feature since it does not combine well with config extension and will be removed in the future.
The special configuration section with key nbob
has the following options:
multiCore = true
- Toggles multi-core processing on or off
Example:
{
"nbob": {
"multiCore": false
}
}
Adding this section to your user config file (~/.nbob/nbob-config.json
) would result in all of your builds defaulting to not using multi-core processing. This can be useful if you have found that the overhead does not outweigh the improved processing speed on your system.
The special configuration section with key project
has the following options:
name = "Unnamed"
- Used to name build artifacts, you should define this in your project config fileversion = "0"
- Used to name build artifacts, you should define this in your project config filefiles
- Can be used to exclude (or un-exclude) certain files or directoriesbuildDir = "build"
- Name of project subdirectory where to write build artifactsdistDir = "dist"
- Name of project subdirectory where to write distribution artifacts
Example:
{
"project": {
"name": "awesomo",
"version": "1.2.3",
"files": [ "!!nbob-config.json", "!res/unused-theme/**/*" ]
}
}
Results in nbob-config.json being un-excluded and the unused-theme files being excluded from all processing.
The special configuration section with key envConfigMap
can be used to specify a number of named environment configs.
When you specify the name of such an environment using the --env
option your config will be extended with that environment config.
Example:
{
"make:substitute:path": {
"substitutes": {
"SERVER": "dev-backend.playtotv.com"
}
},
"deploy": {
"bucketName": "dev.playtotv.com"
},
"envConfigMap": {
"staging": {
"make:substitute:path": {
"substitutes": {
"SERVER": "staging-backend.playtotv.com"
}
},
"deploy": {
"bucketName": "staging.playtotv.com"
}
}
}
}
Will result with $ nbob d
deploying to dev.playtotv.com and $ nbob -e staging d
deploying to staging.playtotv.com.
It will simultaneously substitute __SERVER__
by dev-backend.playtotv.com
or staging-backend.playtotv.com
in their respective environment artifacts.
If you want to quickly override a single configuration value you can use the --option
command line option.
Examples:
$ nbob -o server.port=8081 s
- In case you want to run multiple nbob servers$ nbob -o deploy.force=true d
- In case you want to force a deploy of all files (not just the changed ones)
Commands combine a processor with configuration to provide a specific type of functionality.
Their names are hierarchical, separated by colon characters :
.
When you execute a command you will also execute all of it's subcommands.
If a Command specifies any dependencies, those commands will also be executed.
Commands and subcommands are executed in the order that they were defined (though still processed parallelly where possible).
When referenced from the command line, command names can be abbreviated.
Example:
{
"make:js:concat": {
"description": "Concatenate JS files",
"processor": "concat",
"files": [ "{lib,src}/**/*.min.js{,.map}" ],
"output": "{{project.name}}-{{project.version}}.min.js"
}
}
Uses the generic concat
processor to concatenate JavaScript files and their source maps.
Note: Through config extension not only command configs, but also their processor references can be customized. You can even add extra commands this way! Support for using your own custom processors will also be added in the near future.
TODO: Add support for showing processor help (e.g: nbob -h make:js:minify) and copy output here
For now, please see processor source files for more information on how they work and package.json for links to used third party dependencies.
Here are some links to third party tools that might be used for pending processor implementations:
- Image resizing
- Image spriting
- Image optimizing
- Documentation
- CSS linting
- ES6 Module loading and packaging
- JS Formatting/Fixing
- JS Linting
- JS Testing
- Live Reload
- Browser Sync
nBob uses the following filename and directory conventions:
inc/**/*
- HTML include filesl10n/*.json
- Localization dictionary fileslib/**/*.js
(and optionally*.map
) - External JavaScript files from other projects etc. to be included into this projectsrc/**/*.js
- This project's JavaScript filestemplates/**/*.html
- HTML template files to be compiled into directory JSON filestemplates/**/*.hbs
- Handlebars template files to be compiled to JS files and later**/*.{html,css,js,json,less,png}
- Respectively HTML/CSS/JS/JSON/LESS/PNG files (e.g: use extensions)**/*.min.*
- Minified files (e.g:foo.min.js
fromfoo.js
)**/*.map
- Source map files (e.g:foo.min.js.map
forfoo.min.js
)**/*-l10n{,-*}.{html,hbs}
and**/*-l10n/**/*.{html,hbs}
- Files to be localized__BUILD__/**/*
- Files to be prefixed with build digest (e.g, becomes:build-1a2B3c4D/**/*
) and cached longer
The following files are generated by the following init processors.
nbob-config.json
- The nBob configuration file
.hgignore
- Mercurial configuration file.jscsrc
- JavaScript Code Style configuration file.jshintrc
and.jshintignore
- JSHint configuration files__PROJECT__.sublime-project
- Sublime Text configuration filexhr-proxy.html
- EM XHR Proxy (load in iframe to enable cross origin XHR)
browserslist
- Browserslist config file for Post CSS Autoprefixer etc.
~/.aws/credentials
- Amazon Web Services credentials configuration file