Date post: | 15-Jan-2015 |
Category: |
Technology |
Upload: | fabien-doiron |
View: | 2,963 times |
Download: | 1 times |
what makes me “Grunt”?
developer happiness courtesy of automation
/ Fabien Doiron @fabien_doiron
no automationmake me go something something
when I got into development
front-end development was pretty simple
typical tools
HTML / CSS / JS / FTP / browser
then something happened
front-end development became complex
current typical tools
linting / preprocessors / concatenation /
minification / versioning / testing /
coverage / dependency management /
continuous deployment / version control /
frameworks / libraries…
tools mentionedfrom our stack
environment:
back-end:
front-end:
4 reasons
we use build tools & automation
build tools
in 10 seconds or less
what?
automation
why?
automate what you have but don't want to do
how?
configure a task once, run as often as you want~ ▸ build task:target
who?
Grunt, Gulp, Phing, Make, Rake, Jake, Brunch, Ant…
1.
project setup
project setup: goal
coding ready in minutes
project setup: tools
environment:
build tools:
project setup
in 3 easy steps
i.
~ ▸ git clone … # get code from repository
~ ▸ git pull # get latest code from repository
ii.
~ ▸ vagrant up # puts together a complete environment
# provision environment with chef
iii.
~ ▸ phing proj:build # get deps with composer, npm & bower
# database migration with phinx
# front-end build with grunt
~ ▸ grunt build # lint, preprocess, concat, min, version
# my personal favourite: ascii
2.
project output
project output: goal
reproducible results regardless of developer setup/workflow
reduce the risk of
“works on my machine”
by abstracting the output settings from the
user to the build tool
compiling CSS: user settings
~ ▸ sass in.scss:out.css~ ▸ lessc in.scss > out.css
results: can vary
example task (Sass)
module.exports = function ( grunt ) {
var src = '<%= grunt.option( "src" ) %>';
var tmp = '<%= grunt.option( "tmp" ) %>';
grunt.config( 'sass', {
dist: {
files: [ {
expand: true,
cwd: src + '/sass',
src: [ '*.scss' ],
dest: tmp + '/sass',
ext: '.css'
} ]
}
} );
grunt.loadNpmTasks( 'grunt-contrib-sass' );
};
compiling CSS: tool settings
~ ▸ grunt sass~ ▸ grunt less
results: are the same
3.
coding environment
coding environment: goal
easily work in a dev and/or production replica environment
coding environments setup
in 4 easy steps
i. separate targets
~ ▸ grunt build:dev # all source files, commented, unminified
~ ▸ grunt build:prod # concat, minified, versioned files
grunt versioning task
versioning: {
options: {
cwd: 'public',
outputConfigDir: 'public/config'
},
dist: {
files: [{
assets: '<%= uglify.main.files %>',
key: 'global',
dest: 'js',
type: 'js',
ext: '.min.js'
}, { … } ]
}
}
iii. generated configuration file
~ ▸ grunt build:dev <?php
return array( 'static.assets' => array(
'global' => array(
'css' => array( '/static/css/main.css' ),
'js' => array( '/static/js/file1.js', '/static/js/file2.js', … )
),
'home' => array(
'css' => array(),
'js' => array( 'static/js/home1.js', '/static/js/home2.js' )
),
'anotherKey' => array( … )
) );
iii. generated configuration file
~ ▸ grunt build:prod <?php
return array( 'static.assets' => array(
'global' => array(
'css' => array( '/static/css/main.7f41197e.min.css' ),
'js' => array( '/static/js/plugins.7409b19a.min.js',
'/static/js/common.4923a32c.min.js', … )
),
'home' => array(
'css' => array(),
'js' => array( 'static/js/home.47b0990d.min.js' )
),
'anotherKey' => array( … )
) );
ii. generated output
~ ▸ grunt build:dev ~ ▸ grunt build:prod ▾ public ▾ static ▾ css main.css
▾ js plugin1.js
plugin2.js
common1.js
common2.js
home1.js
home2.js
…
▾ public ▾ static ▾ css main.7f41197e.min.css
▾ js plugins.7409b19a.min.js
common.4923a32c.min.js
home.47b0990d.min.js
…
iv. use generated configuration file
// inside our layouts
<?php $this->versionedAsset()->render( 'global' ); ?>
~ ▸ grunt build:dev
~ ▸ grunt build:prod
<link rel="stylesheet" href="/static/css/main.css">
…
<script src="/static/js/file1.js"></script>
<script src="/static/js/file2.js"></script> …
<link rel="stylesheet" href="/static/css/main.7f41197e.min.css">
…
<script src="/static/js/plugins.7409b19a.min.js"></script>
<script src="/static/js/common.4923a32c.min.js"></script>
why did we go down this road?
cloudfront invalidation ~15 minutes
no longer applicable*
*appending a hash creates a “new” file
cleaner includes in our layouts
messy if( APPLICATION_ENV == "production") {
// include concat/min files
} else {
// include all dev files
}
clean <?php $this->versionedAsset()->render( 'global' ); ?>
demo
4.
debugging
debugging: goal
effectively debug errors
debugging [ compiled, ] concatenated,
minified code is hard
our approach
when a bug is found/reported
i. build dev environment
reproduce the errorrule out minification erroruse devtools on source filesupdate/add unit, integration, regression testsgenerally all we need
ii. build prod environment
reproduce the erroruse devtools with source mapsstill have access to source fileseasier to debug than on the live siteupdate/add unit, integration, regression tests
“trying to fix a bug in minified code is like
using a new API with no documentation”
recap
being a front-end developer is hardbuild tools make you awesomeautomate the repetitive tasksfrictionless project setupreproduce output every timeaccess to dev and production environments locallytake the stress out of debugging
resourceschefvagrantphingcomposergruntbowernpmgrunt static versioning
CONFOO2014
40% offcoupon code because you were awesome
*valid until March 30, 2014
thank you
questions
/ Fabien Doiron @fabien_doiron