README
Pixbi Build Tool
This repo basically contains the build tool that is used across all frontend projects at Pixbi. The project using this repo must follow a set of conventions outlined below.
This build tool assumes that you're using Pixbi's frontend bootloader.
Installation
If you haven't installed Grunt.js and Component.IO already:
$ npm install -g grunt-cli
$ npm install -g component
Then install the npm module and run the install script:
$ npm install --save-dev pixbi-build
$ node_modules/pixbi-build/install
The install script would ask you whether it should overwrite the .gitignore
in yourself directory. It is highly recommended that you do for the first time.
Usage
grunt dev
starts a local server and re-compiles on file changegrunt build
runs a build. This could be used for checking the code against Closure Compiler. Alias:grunt
grunt release:patch
builds the project and bump the patch versiongrunt release:minor
builds the project and bump the minor versiongrunt release:major
builds the project and bump the major version
Compiling
Compiling the project performs these steps:
- Copy files in
app/assets/
topublic/
- Copy files in
dev/
topublic/
public/index.html
is created if it doesn't already exist- Compile all Stylus files (order specified below) under
app/
and concatenate into one CSS file aspublic/index.css
- Concatenate all JavaScript under
app/
into one JS file aspublic/index.js
- Compile all Jade files under
app/
into one HTML file and inject into the end ofbody
inpublic/index.html
- Write into
public/index.html
tags to includestyle.css
andscript.js
Note that while compiling the builder creates a temporary tmp/
directory.
Building
Building the project performs these steps:
- Stash changes to git to avoid data loss (you should of course make sure there is no uncommitted code as well)
- Checkout the
develop
branch - Compile the project
- Apply Closure Compiler with advanced optimizations on the built JavaScript. Any error would stop the process here and fixes should be applied before retrying.
- Apply any transformation for further uglification
- Scan through the
app/
directory and write all relevant file references tocomponents.json
- Bump the respective version
- Commit to git
- Checkout the
master
branch and mergedevelop
intomaster
- Apply the new version as a new git tag
- Checkout the
develop
branch again
Technologies
File Structure
There are some required directories:
app/ --> Application code
app/index.html --> An optional special HTML file into which the builder
injects the script tag, the style tag, and the markup
when built
app/index.jade --> Entry point for templates. Only this file is compiled.
Use Jade's include system to pull in other templates.
app/params.json --> Optional parameter object to be made available as
`module.params`
app/assets/ --> Asset files are copied as-is to build's top-level
directory
app/styl/ --> Any application top-level style (see below for details)
app/modules/ --> Module within the application that are ordered AFTER
code in the top-level `app/` directory when building
components/ --> Other repos imported via Component.IO
dev/ --> Any code necessary to run the application in dev mode
node_modules/ --> Contains this repo
public/ --> Built files when developing. This is NOT committed to
source
test/ --> Test files go here and should have an extension of
`.spec.js`
Development
During development, everything in the dev/
directory is copied over as-is at
the end of the build process. This means that files in the directory would
replace whatever is built at their respective locations. The index.html
in
dev/
would need to reference the script and the tag manually, e.g.
<html>
<head>
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<script src="script.js"></script>
</body>
</html>
The output file exposes the mode via the module.mode
attribute. When in
development, module.mode === 'dev'
should be true
.
NOTE: because of the builder recursively building dependencies, it does not
watch for changes in components/
directory. If you update a repo's
dependencies, you need to restart Grunt.js.
Application Parameters
Since the bootloader accepts a params
object for module.init()
, you may
specify an optional params.json
, the content of which would be injected as
module.params
. For instance, with a params.json
of:
{
"config": {
"kickass": true
}
}
public/script.js
would look something like:
...
module.mode = "dev";
module.params = {
"config": {
"kickass": true
}
};
And we then may call it in index.html
like this:
<body>
<script>
document.addEventListener('DOMContentLoaded', function () {
module.init(module.params);
});
</script>
</body>
The benefit of this is that we could place a params.json
in dev/
for dev
mode and one in app/
for production and have a complete isolation between code
And configuration.
CSS/Stylus Order
Where you place your CSS files within app/
is significant. Stylus files will
be concatenated in this order:
app/styl/variables.styl --> An optional variable file that gets injected
into every Stylus file
app/styl/keyframes.styl --> Keyframes
app/styl/fonts.styl --> Font declarations
app/styl/reset.styl --> Resetting existing CSS in the target
environment
app/styl/main.styl --> Application CSS that goes before any module
CSS
app/modules/**/index.styl --> CSS relevant to specific modules