Bundling Client Side Assets

Post on 27-Jan-2015

120 views 1 download

Tags:

description

 

Transcript of Bundling Client Side Assets

Client Side Assets

Thursday, 13 December 12

Thursday, 13 December 12

npm for the front-end

Thursday, 13 December 12

> bower install jquery

Thursday, 13 December 12

> bower install jquery bower cloning git://github.com/components/jquery.gitbower caching git://github.com/components/jquery.gitbower fetching jquerybower checking out jquery#1.8.1bower copying /Users/timoxley/.bower/jquery

Thursday, 13 December 12

{  "name": "myProject",  "version": "1.0.0",  "main": "./path/to/main.css",  "dependencies": {    "jquery": "~1.7.1"  }}

component.json

Thursday, 13 December 12

> bower install bower cloning git://github.com/components/jquery.gitbower cached git://github.com/components/jquery.gitbower fetching jquerybower checking out jquery#1.7.1bower copying /Users/timoxley/.bower/jquery

component.json

Thursday, 13 December 12

> bower update bower cloning git://github.com/components/jquery.gitbower cached git://github.com/components/jquery.gitbower fetching jquerybower checking out jquery#1.7.2bower copying /Users/timoxley/.bower/jquery

Thursday, 13 December 12

componentsby TJ Holowaychuk

Thursday, 13 December 12

modular… components.

Thursday, 13 December 12

> component install component/jquery

Thursday, 13 December 12

single responsibility principle

Thursday, 13 December 12

“Have you ever seen a great jQuery plugin and thought to yourself “damn! I’m using MooTools!” or perhaps the other way around?”

Thursday, 13 December 12

“That highlights the problem right there, we should have no “jQuery plugins”, no “Dojo modules”, just simply “components” that we can all consume.”

Thursday, 13 December 12

“Components could then utilize these smaller, more modular dependencies to perform tasks.”

Thursday, 13 December 12

“Instead of requiring jQuery as a dependency to convert a string of HTML into elements, one could simply add domify as a dependency and invoke domify(html).”

Thursday, 13 December 12

“…ubiquitous libraries like jQuery will eventually be a thing of the past and fragmentation will hopefully decrease.” – TJ Holowaychuk

Thursday, 13 December 12

microjs meets npm

Thursday, 13 December 12

Thursday, 13 December 12

Thursday, 13 December 12

Thursday, 13 December 12

Thursday, 13 December 12

Thursday, 13 December 12

Thursday, 13 December 12

•visionmedia/superagent•visionmedia/page.js•jprichardson/string.js•guille/ms.js•component/domify•component/emitter•component/tip•component/dialog•component/notification•visionmedia/bytes.js•component/bus•component/overlay•component/autoscale-canvas•component/popover•component/event•component/confirmation•component/confirmation-popover•component/popup•component/menu•component/clipboard•jamesarosen/ember-progressbars•component/suggest-email•component/clipboard-dom•component/cookie•component/path•component/path-to-regexp•component/color-picker•component/within-document•component/classes•component/upload•component/file•component/touchit•component/color•component/thumb•component/calendar•component/url•component/query-string•component/progress-notification•component/progress•forbeslindesay/ajax•component/dropload

•component/history•component/moment•forbeslindesay/booting-sub-nav•juliangruber/stream•component/t•component/grow•component/dom•component/matches-selector•component/color-parser•component/inherit•component/select•component/map•component/escape-html•component/pager•component/bind•component/more•component/trim•component/object•component/removed•component/pie•component/inserted•component/mime•component/sketch•component/indexof•component/convolve•component/preloader•component/piecon•component/json•component/pad•component/confirmation-

notification•component/dropdown•component/relative-date•component/type•component/favicon•component/counter•component/assert•component/states•component/countries•component/regexps•component/style

•component/noticon•component/zepto•component/escape-regexp•component/jquery•component/batch•solutionio/countdown•componitable/editable•juliangruber/span•component/underscore•solutionio/backbone•solutionio/async•component/buttonset•colinf/datecalc•retrofox/to-object•componitable/format-number•retrofox/toolkit•component/aurora-calendar

Thursday, 13 December 12

GRUNTThursday, 13 December 12

Grunt is a task-based command line build tool for JavaScript projects.

Thursday, 13 December 12

• GNU Make

• Apache Ant

• Jake

• Cake

• Rake

• Buildr

• Sprockets

• + many more

Similar Tools

Thursday, 13 December 12

What does a grunt file look like?

Thursday, 13 December 12

module.exports = function(grunt) {

// Project configuration. grunt.initConfig({ lint: { all: ['grunt.js', 'lib/**/*.js', 'test/**/*.js'] }, jshint: { options: { browser: true } } });

// Load tasks from "grunt-sample" grunt plugin installed via Npm. grunt.loadNpmTasks('grunt-sample');

// Default task. grunt.registerTask('default', 'lint sample');

};

Thursday, 13 December 12

module.exports = function(grunt) {  grunt.initConfig({    handlebars: {      all: {        src: "src/templates/",        dest: "public/js/templates.js"      }    },    less: {      all: {        src: 'src/less/application.less',        dest: 'public/css/application.css'      }    },    concat: {      app: {        src: ['src/app/*.coffee'],        dest: 'public/js/main.coffee'      }    },    watch: {      all: {        files: ["src/*", "src/**"],        tasks: "default"      }    },    coffee: {      all: {        src: ["public/js/main.coffee"],        dest: "public/js",        options: {          bare: false        }      }    }  });

  grunt.loadNpmTasks("grunt-handlebars");  grunt.loadNpmTasks("grunt-coffee");  grunt.loadNpmTasks("grunt-less");  return grunt.registerTask("default", "handlebars concat coffee less");};

Thursday, 13 December 12

module.exports = function(grunt) {

  // Project configuration.  grunt.initConfig({    meta: {      version: '0.1.0',      banner: '/*! App Name - v<%= meta.version %> - ' +        '<%= grunt.template.today("yyyy-mm-dd") %>\n' +        '* THIS FILE IS GENERATED BY GRUNT. DO NOT MODIFY MANUALLY\n' +        '* http://app/\n' +        '* Copyright (c) <%= grunt.template.today("yyyy") %> ' +        'Company Inc.; */'    },    lint: {      files: ['grunt.js', 'frontend/src/app.js', 'frontend/src/models/*.js', 'frontend/src/collections/*.js', 'frontend/src/views/*.js', 'frontend/src/router.js', 'frontend/spec/**/*.js', 'frontend/src/statechart.js']    },    concat: {      libs: {        src: ['<banner:meta.banner>',              'frontend/src/vendor/jquery-1.7.2.min.js',              'frontend/src/vendor/underscore-min.js',              'frontend/src/vendor/backbone.js',              'frontend/src/vendor/stativus.js',              'frontend/src/vendor/handlebars.runtime.js',              'frontend/src/vendor/moment-1.6.2.js'        ],        dest: 'public/js/libs.js'      },      tribe: {        src: ['<banner:meta.banner>', 'frontend/src/app.js', 'frontend/src/models/*.js', 'frontend/src/collections/*.js', 'frontend/src/views/*.js', 'frontend/src/router.js', 'frontend/src/statechart.js'],        dest: 'public/js/tribe.js'      },      css: {        src: ['<banner:meta.banner>', 'frontend/css/reset.css', 'frontend/css/base.css', 'frontend/css/tribe.css'],        dest: 'public/css/screen.css'      }    },    min: {      libs: {        src: ['<banner:meta.banner>', 'public/js/libs.js'],        dest: 'public/js/libs.min.js'      },      tribe: {        src: ['<banner:meta.banner>', 'public/js/tribe.js'],        dest: 'public/js/tribe.min.js'      },      templates: {        src: ['<banner:meta.banner>', 'public/js/templates.js'],        dest: 'public/js/templates.min.js'      }    },    recess: {      css: {        src: ['public/css/screen.css'],        dest: 'public/css/screen.min.css',        options: {          compress: true,          noIDs: false        }      }    },    handlebars: {      all: {        src: 'frontend/src/templates',        dest: 'public/js/templates.js'      }    },    watch: {      files: ['<config:lint.files>', 'frontend/css/*.css', 'frontend/src/templates/*.handlebars'],      tasks: 'handlebars concat:tribe concat:css min:tribe min:templates recess'    },    jshint: {      options: {        curly: true,        eqeqeq: true,        immed: true,        latedef: true,        newcap: true,        noarg: true,        sub: true,        undef: true,        boss: true,        eqnull: true,        browser: true      },      globals: {}    },    uglify: {}  });

  grunt.loadNpmTasks('grunt-handlebars');  grunt.loadNpmTasks('grunt-recess');

  // Default task.  grunt.registerTask('default', 'lint handlebars concat min recess');

};

Thursday, 13 December 12

Running grunt

Thursday, 13 December 12

> grunt

Thursday, 13 December 12

Concatenate

grunt.initConfig({ concat: { dist: { src: ['src/intro.js', 'src/project.js', 'src/outro.js'], dest: 'dist/built.js' } }});

Thursday, 13 December 12

Lint

grunt.initConfig({ lint: { files: ['grunt.js', 'lib/*.js', 'test/*.js'] }});

Thursday, 13 December 12

Lintgrunt.initConfig({ lint: { files: ['grunt.js', 'src/**/*.js', 'test/**/*.js'] }, jshint: { options: { curly: true, sub: true, undef: true }, globals: { jQuery: true } },});

Thursday, 13 December 12

Minify

grunt.initConfig({ min: { dist: { src: ['vendor/*'], dest: 'public/libs.min.js' } }});

Thursday, 13 December 12

Watch

grunt.initConfig({ watch: { files: ['src/*.jade'], tasks: 'jade' }, jade: { html: { src: ['src/*.jade'], dest: 'public' } }});

Thursday, 13 December 12

CoffeeScript makes for tidy Gruntfiles

Thursday, 13 December 12

module.exports = (grunt) ->  grunt.initConfig    handlebars:      all:        src: "src/templates/"        dest: "public/js/templates.js"    less:      all:        src: 'src/less/application.less'        dest: 'public/css/application.css'    concat:      app:        src: [          'src/app/*.coffee'        ]        dest: 'public/js/main.coffee'    watch:      all:        files: [          "src/*",          "src/**"        ]        tasks: "default"

  grunt.loadNpmTasks "grunt-handlebars"  grunt.loadNpmTasks "grunt-less"

  grunt.registerTask "default", "handlebars concat less"

Thursday, 13 December 12

> grunt --config ./grunt.coffee

Thursday, 13 December 12

150+ 3rd Party Tasks

Thursday, 13 December 12

• contrib-clean - Clear files and folders.

• cp - A Grunt plugin for copying directories (recursively)

• md5 - generate md5 filename

• shell - Run shell commands

• s3 - automate moving files to/from Amazon S3.

Thursday, 13 December 12

• image-embed - Embed images as base64 data URIs inside your stylesheets.

• smushit - Remove unnecessary bytes of PNG and JPG using Yahoo Smushit

• willitmerge - Check if open Github pull requests are merge-able.

• rigger - Rigging tasks for elegant includes

Thursday, 13 December 12

min: { app: { src: ['app/*'], dest: 'public/app.min.js' }, libs: { src: ['vendor/*'], dest: 'public/libs.min.js' } }

> grunt min:app> grunt min:libs

Thursday, 13 December 12

Creating Custom Plugins is Easy

Thursday, 13 December 12

> grunt init:gruntplugin

Thursday, 13 December 12

Running "init:gruntplugin" (init) taskThis task will create one or more files in the current directory, based on theenvironment and the answers to a few questions. Note that answering "?" to anyquestion will show question-specific help and answering "none" to most questionswill leave its value blank.

"gruntplugin" template notes:The grunt plugin system is still under development. For more information, seethe docs at https://github.com/cowboy/grunt/blob/master/docs/plugins.md

Please answer the following:[?] Project name (grunt-plugin) [?] Description (The best sample grunt tasks ever.) [?] Version (0.1.0) [?] Project git repository (git://github.com/timoxley/grunt-plugin.git) [?] Project homepage (https://github.com/timoxley/grunt-plugin) [?] Project issues tracker (https://github.com/timoxley/grunt-plugin/issues) [?] Licenses (MIT) [?] Author name (Tim Oxley) [?] Author email (secoif@gmail.com) [?] Author url (none) [?] What versions of grunt does it require? (~0.3.9) [?] What versions of node does it run on? (*) [?] Do you need to make any changes to the above before continuing? (y/N) N

Writing .npmignore...OKWriting bin/grunt-plugin...OKWriting grunt.js...OKWriting README.md...OKWriting tasks/plugin.js...OKWriting test/plugin_test.js...OKWriting LICENSE-MIT...OK

Initialized from template "gruntplugin".

Done, without errors

Thursday, 13 December 12

// Load tasks and helpers from the "tasks" directory, relative to grunt.js.grunt.loadTasks('tasks');

// Load tasks and helpers from the "grunt-sample" Npm-installed grunt plugin.grunt.loadNpmTasks('grunt-sample');

Thursday, 13 December 12

html5 boilerplate +grunt +opinions =

Thursday, 13 December 12

node-build-script

Thursday, 13 December 12

bootstrap for grunt

Thursday, 13 December 12

•Concats / Compresses JS

•Concats / Compresses CSS

•Inline CSS imports via RequireJS

•Basic to aggressive html minification (via [html-minfier][])

•Optimizes JPGs and PNGs (with jpegtran & optipng)

Thursday, 13 December 12

•Renames JS/CSS to prepend a hash of their contents for easier versioning

•Revises the file names of your assets so that you can use heavy caching

•Updates your HTML to reference these new hyper-optimized CSS + JS files

Thursday, 13 December 12

•May rerun the build script on file changes (grunt's watch task ❤)

•May automatically reload the page in your browsers whenever watched files change, through some socket.io magic.

Thursday, 13 December 12

node-build-script +bower +more opinions=

Thursday, 13 December 12

Thursday, 13 December 12

•HTML5 Boilerplate

•Twitter Bootstrap

•Twitter Bootstrap plugins

•RequireJS

•Support for ES6 Modules

•Wraps bower

Thursday, 13 December 12

• Lightning-fast scaffolding — Easily scaffold new projects with customizable templates (e.g HTML5 Boilerplate, Twitter Bootstrap), AMD (via RequireJS) and more.

• Automatically compile CoffeeScript & Compass — Our LiveReload watch process automatically compiles source files and refreshes your browser whenever a change is made so you don't have to.

Thursday, 13 December 12

• Automatically lint your scripts — All your scripts are automatically run against jshint to ensure they're following language best-practices.

• Built-in preview server — No more having to fire up your own HTTP Server. My built-in one can be fired with just one command.

• Awesome Image Optimization — I optimize all your images using OptiPNG and JPEGTran so your users can spend less time

Thursday, 13 December 12

• Integrated package management — Need a dependency? It's just a keystroke away. I allow you to easily search for new packages via the command-line (e.g., yeoman search jquery), install them and keep them updated without needing to open your browser.

• Support for ES6 module syntax — Experiment with writing modules using the latest ECMAScript 6 module syntax. This is an experimental feature that transpiles back to ES5 so you can use the code in all

Thursday, 13 December 12

• PhantomJS Unit Testing — Easily run your unit tests in headless WebKit via PhantomJS. When you create a new application, I also include some test scaffolding for your app.

Thursday, 13 December 12