Grunt & Front-end Workflow

Post on 07-Aug-2015

101 views 1 download

Transcript of Grunt & Front-end Workflow

GRUNTFront-end Workflow

About Pagepro:

• Internet Software House from Poland • Operating since 2010 • Clients from Western Europe and U.S. • 176 projects done in 2014 • 1758 PSDs converted into

HTML5 in 2014

Common Front-end tasks• Compile SASS / LESS

• Minify

• Uglyfi

• Test

• Optimize

• Analyze

• Modules & Dependencies

node.js

• Server-side JavaScript

• V8 (Google Chrome Browser)

• Command Line Tool

• 40% JS 60 % C++

node.js

• EVENT DRIVEN, non-blocking I/O model

• event-loops

• no DOM implementation

• single-thread

mkdir grunt; cd grunt;

git https://github.com/Pagepro/training-grunt.git .

Clone repository

node.js

node -v;// check version if installed

https://nodejs.org/download/

brew install node

node.js

• process (node)

• document (JavaScript)

node.js

Traditional I/O

var result = db.query('select x from table_Y'); doSomethingWith(result); //wait for result! doSomethingWithOutResult(); //execution is blocked

node.js

Non-blocking I/O

db.query('select x from table_Y', function (result) { doSomethingWith(result); //wait for result! }); doSomethingWithOutResult(); //executes without any delay!

node.js

• Access File

• Listen to network traffic

• HTTP requests

• DB Access

node.js• Utilites

• Gulp

• Grunt

• Yeoman

• Live Reload

• Web servers

node.js

console.log('helo world');

node hello

node hello.js (.js is optional)

node.js

var age = 23, person = { name: 'Chris', location: 'Poland' } console.log(age); console.log(person);

node hello-extended

node.js

var requiredModule = require('./example-module'); console.log(requiredModule);

node modules

module.exports.a = 55; module.exports.b = [1, 3, 4, 5];

node.js

node server var http = require('http'); http.createServer(function (req, res) { console.log(req); res.write('hello!'); res.end(); }).listen(5000, "127.0.0.1");

node.js

node watch

var fs = require('fs');fs.watch('./server.js', { persistent: true}, function(event, filename) { console.log(event + " event occurred on " + filename);});

npm

• Node Package Manager

• npm install mongojs

• https://npmjs.org

• npm init

npm

npm init;

package.json{ "name": "libsasserplate", "version": "1.0.1", "description": "Libsass starter", "author": "Pagepro <pagepro@pagepro.pl>", "devDependencies": { "grunt": "^0.4.2", "time-grunt": "latest", "grunt-sass": "latest", "grunt-autoprefixer": "latest", "grunt-spritesmith": "latest", "grunt-contrib-uglify": "~0.2.4", "grunt-contrib-watch": "^0.5.3", "grunt-contrib-copy": "^0.5.0", "grunt-contrib-kraken": "^0.1.3", "grunt-contrib-connect": "^0.8.0", "matchdep": "^0.3.0", "jquery": "1.11.2" }}

package.json

http://browsenpm.org/package.json

http://semver.org

npm

{ "name": "npm", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "" }, "author": "", "license": "ISC", "devDependencies": { "grunt": "^0.4.5" }}

{ "name": "npm", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "" }, "author": "", "license": "ISC"}

npm install grunt —save-dev

npm

rm -rf node_modules/*

ls

npm install

When not to use node.js?• When you are doing heavy and

CPU intensive calculations on server side, because event-loops are CPU hungry

• Node.js API is still in beta, it keeps on changing a lot from one revision to another and there is a very little backward compatibility. Most of the packages are also unstable. Therefore is not yet production ready.

GRUNT• Lint

• Test

• Compile

• Open browser

• Run browser

• Watch assets

• Recompile

• Reload browser

GRUNTpython -m SimpleHttpServer

open index.html

sass —watch sass:css

js hint main.js

./conquer_the_world.sh

etc.

GRUNT

We can setup long flows and run it with just one task.

We can stop the flow if taks fails.

Everyone in the team can follow same workflow.

GRUNT

• JavaScript task runner

• npm install -g grunt-cli

Gruntfile.js

• Grunt configuration file

• Makefile, Rakefile, etc.

GRUNT• cd grunt/linter;

• npm init;

• npm install grunt —save-dev

• npm install grunt-contrib-jshint —save-dev

• grunt jshint

GRUNT

'use strict';module.exports = function (grunt) { // load jshint plugin grunt.loadNpmTasks('grunt-contrib-jshint');};

GRUNT

>> No "jshint" targets found.

Warning: Task "jshint" failed. Use --force to continue.

Aborted due to warnings.

What’s a target?

GRUNTIt’s a core concept of Grunt. When we create a task, we add targets to it.

Every target represents a set of actions and files the task will be run over.

We can run a task’s target by simply appending it to the task name.

grunt mytask:mytarget

GRUNT

'use strict';module.exports = function (grunt) { // load jshint plugin grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.initConfig({ jshint: { all: [ 'Gruntfile.js' ] } });};

GRUNT

'use strict';module.exports = function (grunt) { // load jshint plugin grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.initConfig({ jshint: { all: [ 'Gruntfile.js', 'app/js/**/*.js' ] } });};

GRUNT

'use strict';module.exports = function (grunt) { // load jshint plugin grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.initConfig({ jshint: { all: [ 'Gruntfile.js', 'app/js/**/*.js', '!app/js/vendor/**/*.js' ] } });};

GRUNT'use strict';module.exports = function (grunt) { // load jshint plugin grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.initConfig({ jshint: { options: { jshintrc: '.jshintrc' }, all: [ 'Gruntfile.js', 'app/js/**/*.js', '!app/js/vendor/**/*.js' ] } });};

GRUNT & SASS

cd sass;

npm install;

grunt sass:dev

GRUNT & SASS

Prepare grunt sass:prod for getting minified css.

GRUNT & SERVER

cd server;

npm install;

grunt connect;

GRUNT & SERVER'use strict';module.exports = function (grunt) { // load plugins grunt.loadNpmTasks('grunt-contrib-connect'); grunt.initConfig({ connect: { server: { options: { port: grunt.option('port') || 8080, hostname: 'localhost', base: '', keepalive: true } } } });};

GRUNT & WATCH

Listen for something.

Do something.

GRUNT & SERVER

cd watch;

npm install;

GRUNT & SERVER

watch: {sass: {

files: ['app/sass/*.scss'], tasks: ['sass:dev'] }}

GRUNT & SERVER

grunt connect:server watch

GRUNT & SERVER

grunt.registerTask('mytask', 'Desc', [ 'connect:server', 'watch',]);

GRUNT & SERVER

grunt.registerTask('default', ['copy:dev', 'compass:dev', 'connect:server', 'watch']);

What is matchdep?

Matchdep

// Load pluginsrequire('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);// Default task(s).grunt.registerTask('default', ['sass', 'connect:server', 'copy:dev', 'watch']);// SASSS compilation onlygrunt.registerTask('compile', ['sass']);// sprite generationgrunt.registerTask('sprites', ['sprite']);grunt.registerTask('krak', ['kraken']);

Other examples

Uglifyuglify: {

lp: { files: { 'dist_lp/js/app.min.js': [ 'node_modules/jquery/dist/jquery.js', 'src/js/plugins.js', 'src/js/main.js' ] } }, thx: { files: { 'dist_thx/js/app.min.js': [ 'node_modules/jquery/dist/jquery.js', 'src/js/plugins.js', 'src/js/main.js' ] } } },

Shell

shell: { lpPackage: { command: 'cd dist_lp && zip -r ../package_lp.zip *' }, thxPackage: { command: 'cd dist_thx && zip -r ../package_thx.zip *' }}

Process

process: function (content, srcpath) { content = content.replace('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>', '<script src="./js/app.min.js"></script>'); content = content.replace('<script src="static/js/main.js"></script>', ''); content = content.replace('<script src="static/js/plugins.js"></script>', ''); return content.replace(/static\//g, "./");}

Useful links1. https://www.youtube.com/watch?v=pU9Q6oiQNd0

2. http://howtonode.org/introduction-to-npm

3. https://speakerdeck.com/dmosher/frontend-workflows-and-tooling

4. http://gruntjs.com/

5. http://browsenpm.org/package.json

Thank you!Developing the web in the heart of Europe.