What makes me "Grunt"?

Preview:

DESCRIPTION

Slides from my talk at Confoo 2014. Notes to come... As a front end developer, I want to write code. Dealing with the mundane tasks that come with static assets such as concatenation, minification and versioning, I don't care much for. In this session, I'll explain how to setup Grunt tasks to handle CSS and JavaScript assets in both development and production environments. This automated workflow allows you to easily reproduce both environments locally for testing and debugging. ## Resources * http://www.getchef.com/ * http://www.vagrantup.com/ * http://www.phing.info/ * https://getcomposer.org/ * http://www.gruntjs.com/ * http://www.bower.io/ * http://www.npmjs.com/ * http://github.com/canvaspop/grunt-static-versioning ## Links * http://fabien-d.github.io/ * http://twitter.com/fabien_doiron * http://canvaspop.com * http://dna11.com * http://crated.com * http://developers.canvaspop.com * http://remade.canvaspop.com/

Citation preview

what makes me “Grunt”?

developer happiness courtesy of automation

/ Fabien Doiron @fabien_doiron

no automationmake me go something something

I work on Cratedsoftware developer, front-end

@fabien_doiron

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

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

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

project output: tools

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 environment: tools

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

CONFOO2014

40% offcoupon code because you were awesome

*valid until March 30, 2014

thank you

questions

/ Fabien Doiron @fabien_doiron