building assets on the fly with node.js
TRANSCRIPT
Building assets on the fly using node (no watcher)
JS-Montreal
Martin Drapeau2012-08-14
About Acquisio• Automate web advertising
• The leading platform to buy, track, manage, optimize and report on media across all major Search, Social and Display networks.
• Benefits• Increase Efficiency• Uncover New Business Opportunities• Serve Clients Better• Serve More Clients• Mitigate Risk
Visit www.acquisio.com for more info.
SEARCH SOCIAL DISPLAY
Buy
Track
ManageOptimize
Report
• Flex (ActionScript)• EOL by Adobe
• Front-End Heavy• Client is +10MB (to be downloaded
every time by customers)• Client contains a lot of business
logic – heavy processing. A lot should be moved to the Back-End.
Need to change architecture!
Current Front-End Technology Stack
Next Gen Front-End Technology Stack
JavaAPI & Business logic & Interface to Back-End
JBoss, JAX-RS (Jersey), JAXB (JSON)
Apache/PHP- Serve JS/CSS assets- Dynamic generation of HTML- Harness for different
environments (i.e. dev vs. prod)
Node JS- Build and deployment- JS dependency management- Compilation of JS and CSS- Test harness (unit, functional
and integration)
Javascript
Service Layer “Middleware”
Serving Technologies
Front-End- Backbone JS & Underscore JS- Twitter Bootstrap + Foundation- Stylus for CSS (preprocessor)- Kendo UI for data-grid and other
widgets
- MVC architecture- Presentation logic
Priv
ate
API
Efficient Development- Zero compilation- Dev in the browser- Re-use what’s out
there
No communication between PHP and Java
• Objective• Make it easy to develop in the browser• F5 must be the ONLY way to build
• How to do it• Harness PHP to manage assets on the fly
• Technology tools• Node.js – Driver our build scripts with JS!• Snockets – Manage JS dependencies, concat and minify• Stylus – CSS preprocessor
Development in the browser
Snockets• A JavaScript/CoffeeScript concatenation tool for Node.js
inspired from Sprockets . • We use it to manage dependencies and compile (concat and
minify) production JS assets.
How to use (script-side)• Declare dependencies directly in your JS files
//= require jquery.jsor
//= require_tree common
Managing JavaScript Assets
How to use (Node-side)
• Construct dependency chain var file = ‘my_file.js’; var dependencies = []; snockets.scan(file, {sync:1}, function(err, depGraph) { dependencies = depGraph.getChain(file); });
• Concatenate and minify (compilation) var file = ‘my_file.js’; snockets.getConcatenation(file, {minify:1, sync:1}, function (err, js) { fs.writeFileSync(‘my_file.min.js’, js, 'utf8');}); });
Managing JavaScript Assets
Stylus• CSS preprocessor Expressive, dynamic, robust CSS
How to compile• Use the Node.js stylus module.
var file = ‘my_file.styl’; styl = fs.readFileSync(file, 'utf8').replace(/\r/g, ''); style = stylus(styl) .set('compress', true) .set('include css', true); style.render(function (err, css) { fs.writeFileSync('.css', css, 'utf8'); });
Managing CSS Assets
• Either load single minified JS file, or multiple JS files running Node.js to retrieve dependency chain
function js($module) { if (USE_COMPILED_JS) { $this->view('script_include', array( 'url' => WEB_ROOT."/javascripts/$module.min.js", 'content_type' => 'text/javascript', 'version' => VERSION )); } else { $assets = $this->getAssetsForJsModule($module); foreach ($assets as $asset) $this->view('script_include', $asset); } }
PHP – Load JS assets
• Run Node.js
$chain_script = realpath(FCPATH.'../bin/js_chain.js'); $cmd = 'node "'.$chain_script.'" '.$module; exec($cmd, $result); $chains = json_decode($result[0], TRUE);
• Create SCRIPT tags
<script type="<?=$type?>" src="<?=$url?>"></script>
PHP – Load JS assets
• If CSS files do not exist, or are stale – run Node.js to create them from Stylus files
$stylus_script = realpath(FCPATH.'../bin/css_compile.js'); $cmd = 'node "'.$stylus_script.'" --compress=true '.$module; exec($cmd, $result);
PHP – Load CSS assets
• JS Assets• 0.5 seconds to chain 70 dependencies (608KB raw JS)*
• CSS Assets• 1.7 seconds to compile 133 Stylus files (2.8MB) into 2 CSS files
• Time to Load page in Chrome
With CSS Compilation92 requests 5.24MB transferred 5.75s (onload: 4.46s, DOMContentLoaded: 4.44s)❘ ❘
With no CSS Compilation92 requests 5.24MB transferred 3.93s (onload: 2.57s, DOMContentLoaded: 2.55s)❘ ❘
Performance in Development Environment
*Exculding 3rd party libraries jQuery and KendoUI
• Automate builds with JavaScript thanks to Node.js!
• Deployment to different environments• QA, Staging, Pre-production and Production
• Automate running QA tests suites• Run QA unit, functional and integration tests• Use Zombie browser
Other work in progress
Questions?