SlideShare a Scribd company logo
1 of 68
Download to read offline
Automating Your
Workflow with Gulp.js
php[world] 2016
@colinodell - joind.in/talk/17992
Colin O’Dell
• Lead Web Developer at Unleashed Technologies
• PHP League Member
 league/commonmark
 league/html-to-markdown
• PHP 7 Upgrade Guide e-book
@colinodell - joind.in/talk/17992
Agenda
• What Are Task Runners?
• Getting Started with Gulp.js
• Gulp API
• Task Examples
• Q&A
@colinodell - joind.in/talk/17992
What Are Task Runners?
Software that automates, coordinates, and controls the
process of running build tasks.
• Define tasks & dependencies
• Execute those tasks
@colinodell - joind.in/talk/17992
What Are Task Runners?
Three types of tasks:
1. Tranformations
2. Tests
3. Commands
@colinodell - joind.in/talk/17992
Transformations
• Compiling SASS/LESS, CoffeeScript, etc.
• Combining/minifying files
• Compressing images
• Copying files to a different location
@colinodell - joind.in/talk/17992
0110011
1001111
0010011
1010010
0110011
1001111
0010011
1010010
Running Tests
• Linting for syntax errors
• Checking code styles
• Running automated tests (unit, functional, etc)
@colinodell - joind.in/talk/17992
0110011
1001111
0010011
1010010
✓✗
Running Misc. Commands
• Deleting previous builds
• Installing dependencies with Composer, npm, bower, yarn, etc.
• Any shell command
@colinodell - joind.in/talk/17992
✓✗
@colinodell - joind.in/talk/17992
0110011
1001111
0010011
1010010
0110011
1001111
0010011
1010010
0110011
1001111
0010011
1010010
✓✗
✓✗
When/Where To Run Build Tasks
• Locally during development
• Continuous integration
• Deployments
@colinodell - joind.in/talk/17992
Different Task Runners
Comparison between Apache Ant, Phing, Grunt, and Gulp
@colinodell - joind.in/talk/17992
Apache Ant
• Like Make, but built in Java
• Typically installed via package manager (apt-get)
• XML configuration files
@colinodell - joind.in/talk/17992
<?xml version="1.0"?>
<project name="Hello World Project" default="info">
<target name="info">
<echo>Hello World - Welcome to Apache Ant!</echo>
</target>
</project>
Apache Ant
@colinodell - joind.in/talk/17992
<?xml version="1.0"?>
<project name="Compress CSS and run PHPUnit" default="build">
<target name="build" depends="compress_css,phpunit"/>
<target name="compress_css">
<apply executable="java" parallel="false">
<fileset dir="." includes="foo.css, bar.css"/>
<arg line="-jar"/>
<arg path="yuicompressor.jar"/>
<srcfile/>
<arg line="-o"/>
<mapper type="glob" from="*.css" to="*-min.css"/>
<targetfile/>
</apply>
</target>
<target name="phpunit">
<exec executable="./vendor/bin/phpunit" failonerror="true">
<arg value="--configuration"/>
<arg path="phpunit.xml"/>
</exec>
</target>
</project>
Phing
• Based on Apache Ant, but built in PHP
• Typically installed via PEAR or Composer
• XML configuration files
@colinodell - joind.in/talk/17992
<?xml version="1.0"?>
<project name="Hello World Project" default="info">
<target name="info">
<echo>Hello World - Welcome to Apache Ant!</echo>
</target>
</project>
Apache Ant
@colinodell - joind.in/talk/17992
<?xml version="1.0"?>
<project name="Compress CSS and run PHPUnit" default="build">
<target name="build" depends="compress_css,phpunit"/>
<target name="compress_css">
<apply executable="java" parallel="false">
<fileset dir="." includes="foo.css, bar.css"/>
<arg line="-jar"/>
<arg path="yuicompressor.jar"/>
<srcfile/>
<arg line="-o"/>
<mapper type="glob" from="*.css" to="*-min.css"/>
<targetfile/>
</apply>
</target>
<target name="phpunit">
<exec executable="./vendor/bin/phpunit" failonerror="true">
<arg value="--configuration"/>
<arg path="phpunit.xml"/>
</exec>
</target>
</project>
@colinodell - joind.in/talk/17992
<?xml version="1.0"?>
<project name="Compress CSS and run PHPUnit" default="build">
<target name="build" depends="compress_css,phpunit"/>
<target name="compress_css">
<apply executable="java" parallel="false">
<fileset dir="." includes="foo.css, bar.css"/>
<arg line="-jar"/>
<arg path="yuicompressor.jar"/>
<srcfile/>
<arg line="-o"/>
<mapper type="glob" from="*.css" to="*-min.css"/>
<targetfile/>
</apply>
</target>
<target name="phpunit">
<phpunit pharlocation="./vendor/bin/phpunit" configuration="phpunit.xml"/>
</target>
</project>
Grunt
• Built in JavaScript
• Many third-party plugins; easy to install
• JS-based configuration with heavy JSON usage
@colinodell - joind.in/talk/17992
var grunt = require('grunt');
grunt.registerTask('default', 'The default build task', function(){
console.log('Hello World!');
});
@colinodell - joind.in/talk/17992
var grunt = require('grunt');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-phpunit');
grunt.initConfig({
cssmin: {
target: {
files: [{
src: ['foo.css', 'bar.css'],
dest: 'build/css',
ext: '.min.css'
}]
}
},
phpunit: {
options: {
bin: 'vendor/bin/phpunit',
configuration: 'phpunit.xml',
coverage: false
}
}
});
grunt.registerTask('default', 'The default build task', ['cssmin', 'phpunit']);
Gulp.js
• Built in JavaScript
• Many third-party plugins; easy to install
• Uses JS code instead of configuration
• Built around file streams
@colinodell - joind.in/talk/17992
var gulp = require('gulp');
gulp.task('default', function() {
console.log('Hello world.');
});
@colinodell - joind.in/talk/17992
var gulp = require('gulp');
var cssmin = require('gulp-minify-css');
var phpunit = require('gulp-phpunit');
var rename = require('gulp-rename');
gulp.task('cssmin', function() {
return gulp.src(['foo.css', 'bar.css'])
.pipe(minifycss())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest('build/css'));
});
gulp.task('phpunit', function() {
var options = { noCoverage: true };
return gulp.src('phpunit.xml')
.pipe(phpunit('./vendor/bin/phpunit', options));
});
gulp.task('default', ['cssmin', 'phpunit']);
@colinodell - joind.in/talk/17992
0110011
1001111
0010011
1010010
0110011
1001111
0010011
1010010
0110011
1001111
0010011
1010010
0110011
1001111
0010011
1010010
{ … }
0110011
1001111
0010011
1010010
Getting Started with
Gulp.js
@colinodell - joind.in/talk/17992
Installing gulp-cli
@colinodell - joind.in/talk/17992
Initializing npm
@colinodell - joind.in/talk/17992
Adding gulp to a project
@colinodell - joind.in/talk/17992
Adding gulp to a project
@colinodell - joind.in/talk/17992
gulpfile.js
@colinodell - joind.in/talk/17992
var gulp = require('gulp');
gulp.task('default', function() {
// place code for your default task here
});
gulpfile.js
@colinodell - joind.in/talk/17992
Gulp API
@colinodell - joind.in/talk/17992
gulp.task(name [, deps] [, fn])
• Defines tasks and their dependencies
• Three parameters:
 Name (required)
 Array of task dependencies
 Function to run
@colinodell - joind.in/talk/17992
gulp.task('sometask', function() {
// Do stuff
});
gulp.task('sometask', ['dep1', 'dep2'], function() {
// Do stuff
});
gulp.task('js', ['jshint', 'jsmin']);
gulp.src(globs [, options])
• Two parameters:
 Globs of files (required)
 String or array
 Options
• Returns a stream of Vinyl files that can be piped to plugins
@colinodell - joind.in/talk/17992
gulp.src('styles/foo.css')
gulp.src('styles/*.css')
gulp.src('styles/**/*.css')
gulp.src(['styles/**/*.css', '!*.min.css'])
var themeBase = 'src/theme';
var distThemeBase = 'web/theme';
var paths = {
img: [themeBase + '/img/**/*.{gif,png,jpg,svg,svgz}'],
js: [themeBase + '/js/**/*.js'],
font: [themeBase + '/fonts/**/*.{otf,eot,svg,ttf,woff,woff2}'],
css: [themeBase + '/styles/**/*.css'],
favicons: [themeBase + '/favicons/**/*.{png,xml,ico,json,svg}'],
php: ['src/**/*.php'],
xml: ['src/**/*.xml'],
distContrib: distThemeBase + '/contrib/',
distCSS: distThemeBase + '/css/',
distJS: distThemeBase + '/js/',
distImg: distThemeBase + '/img/',
distFont: distThemeBase + '/fonts/',
distFavicons: distThemeBase + '/favicons/'
};
gulp.src(paths.css);
@colinodell - joind.in/talk/17992
.pipe(destination)
• Called on gulp.src() result stream
• destination is a stream (typically an input stream created by a plugin)
@colinodell - joind.in/talk/17992
return gulp.src(['foo.css', 'bar.css'])
.pipe(minifycss())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest('build/css'));
gulp.dest(path [,options])
• Writes the streamed files to the given path
@colinodell - joind.in/talk/17992
return gulp.src(['foo.css', 'bar.css'])
.pipe(minifycss())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest('build/css'));
Examples
Code Linting
@colinodell - joind.in/talk/17992
jshint
@colinodell - joind.in/talk/17992
var jshint = require('gulp-jshint');
gulp.task('jshint', function() {
return gulp.src(paths.js)
.pipe(jshint())
.pipe(jshint.reporter())
.pipe(jshint.reporter('fail'));
});
jshint
@colinodell - joind.in/talk/17992
csslint
@colinodell - joind.in/talk/17992
var csslint = require('gulp-csslint');
gulp.task('csslint', function() {
return gulp.src([paths.css, '!**/*.min.css'])
.pipe(csslint('.csslintrc'))
.pipe(csslint.reporter())
.pipe(csslint.failReporter());
});
phplint
@colinodell - joind.in/talk/17992
var phplint = require('gulp-phplint');
gulp.task('phplint', function() {
return gulp.src(paths.phpLint)
.pipe(phplint())
.pipe(phplint.reporter('fail'));
});
phpcs
@colinodell - joind.in/talk/17992
var phpcs = require('gulp-phpcs');
gulp.task('phpcs', ['phplint'], function() {
var options = {
bin: 'vendor/bin/phpcs',
standard: 'PSR2
};
return gulp.src(paths.php)
.pipe(phpcs(options))
.pipe(phpcs.reporter('log'))
.pipe(phpcs.reporter('fail'));
});
eol
@colinodell - joind.in/talk/17992
var eol = require('gulp-eol-enforce');
gulp.task('eol', function(){
var paths = [].concat(paths.php, paths.less, paths.js, paths.xml);
return gulp.src(paths)
.pipe(eol('n'));
});
'lint' task group
@colinodell - joind.in/talk/17992
gulp.task('lint', ['eol', 'phpcs', 'csslint', 'jshint']);
gulp.task('lint', function() {
gulp.start('eol', 'phpcs', 'csslint', 'jshint');
});
Examples
Transformations
@colinodell - joind.in/talk/17992
Compile, autoprefix, and minify LESS
@colinodell - joind.in/talk/17992
var autoprefixer = require('gulp-autoprefixer'),
less = require('gulp-less'),
minifycss = require('gulp-minify-css'),
rename = require('gulp-rename')
;
gulp.task('less', function() {
return gulp.src(paths.less)
.pipe(less())
.pipe(autoprefixer({
browsers: ['last 3 versions', 'ie >= 8']
}))
.pipe(minifycss())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest(paths.distCSS));
});
Compile, autoprefix, and minify SASS
@colinodell - joind.in/talk/17992
var autoprefixer = require('gulp-autoprefixer'),
sass = require('gulp-sass'),
minifycss = require('gulp-minify-css'),
rename = require('gulp-rename')
;
gulp.task('sass', function() {
return gulp.src(paths.sass)
.pipe(sass())
.pipe(autoprefixer({
browsers: ['last 3 versions', 'ie >= 8']
}))
.pipe(minifycss())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest(paths.distCSS));
});
Compressing Images
@colinodell - joind.in/talk/17992
var imagemin = require('gulp-imagemin');
gulp.task('images', function () {
var options = {
svgoPlugins: [{removeViewBox: false}]
};
return gulp.src(paths.img)
.pipe(imagemin(options))
.pipe(gulp.dest(paths.distImg));
});
Examples
Unit Tests
@colinodell - joind.in/talk/17992
PHPUnit Tests
@colinodell - joind.in/talk/17992
var phpunit = require('gulp-phpunit');
gulp.task('phpunit', function () {
return gulp.src('phpunit.xml')
.pipe(phpunit('./vendor/bin/phpunit', {notify: true}));
});
Examples
Command Line Scripts
@colinodell - joind.in/talk/17992
Run Shell Commands
@colinodell - joind.in/talk/17992
var shell = require('gulp-shell');
gulp.task('deps', shell.task([
'composer install',
'npm install',
'bower install'
]));
Examples
Task Groups
@colinodell - joind.in/talk/17992
Task Groups
@colinodell - joind.in/talk/17992
gulp.task('lint', function() {
gulp.start('eol', 'phpcs', 'csslint', 'jshint');
});
gulp.task('build', function() {
gulp.start('css', 'images', 'js', 'fonts', 'favicons');
});
gulp.task('test', function() {
gulp.start('lint', 'phpcs');
});
gulp.task('default', function() {
gulp.start('test', 'build');
});
@colinodell - joind.in/talk/17992
@colinodell - joind.in/talk/17992
Useful Utilities
@colinodell - joind.in/talk/17992
gulp-changed
@colinodell - joind.in/talk/17992
var imagemin = require('gulp-imagemin');
gulp.task('images', function () {
var options = {
svgoPlugins: [{removeViewBox: false}]
};
return gulp.src(paths.img)
.pipe(imagemin(options))
.pipe(gulp.dest(paths.distImg));
});
gulp-changed
@colinodell - joind.in/talk/17992
var changed = require('gulp-changed');
var imagemin = require('gulp-imagemin');
gulp.task('images', function () {
var options = {
svgoPlugins: [{removeViewBox: false}]
};
return gulp.src(paths.img)
.pipe(changed(paths.distImg))
.pipe(imagemin(options))
.pipe(gulp.dest(paths.distImg));
});
gulp-newer
@colinodell - joind.in/talk/17992
var gulp = require('gulp');
var newer = require('gulp-newer');
var concat = require('gulp-concat');
gulp.task('concat', function() {
return gulp.src('lib/*.js')
.pipe(newer('dist/all.js'))
.pipe(concat('all.js'))
.pipe(gulp.dest('dist'));
});
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
gulp.task('build-js', function() {
return gulp.src(paths.js)
.pipe(concat('app.js'))
.pipe(uglify())
.pipe(gulp.dest(paths.distJs));
});
gulp-sourcemaps
@colinodell - joind.in/talk/17992
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
gulp.task('build-js', function() {
return gulp.src(paths.js)
.pipe(sourcemaps.init())
.pipe(concat('app.js'))
.pipe(uglify())
.pipe(sourcemaps.write())
.pipe(gulp.dest(paths.distJs));
});
gulp-sourcemaps
@colinodell - joind.in/talk/17992
gulp-load-plugins
@colinodell - joind.in/talk/17992
{
"devDependencies": {
"gulp": "~3.9",
"gulp-autoprefixer": "~2.3.1",
"gulp-bower": "~0.0.10",
"gulp-changed": "~1.2.1",
"gulp-csslint": "~0.1.5",
"gulp-eol-enforce": "*",
"gulp-imagemin": "~2.3.0",
"gulp-jshint": "~1.11.2",
"gulp-less": "~3.0.3",
"gulp-minify-css": "~1.2.0",
"gulp-phpcs": "~0.6.0",
"gulp-rename": "~1.2.2",
"gulp-uglify": "~1.2.0"
}
}
var gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
bower = require('gulp-bower'),
changed = require('gulp-changed'),
csslint = require('gulp-csslint'),
eol = require('gulp-eol-enforce'),
imagemin = require('gulp-imagemin'),
jshint = require('gulp-jshint'),
less = require('gulp-less'),
minifycss = require('gulp-minify-css'),
phpcs = require('gulp-phpcs'),
rename = require('gulp-rename'),
uglify = require('gulp-uglify');
gulp-load-plugins
@colinodell - joind.in/talk/17992
{
"devDependencies": {
"gulp": "~3.9",
"gulp-autoprefixer": "~2.3.1",
"gulp-bower": "~0.0.10",
"gulp-changed": "~1.2.1",
"gulp-csslint": "~0.1.5",
"gulp-eol-enforce": "*",
"gulp-imagemin": "~2.3.0",
"gulp-jshint": "~1.11.2",
"gulp-less": "~3.0.3",
"gulp-minify-css": "~1.2.0",
"gulp-phpcs": "~0.6.0",
"gulp-rename": "~1.2.2",
"gulp-uglify": "~1.2.0"
}
}
var gulp = require('gulp'),
plugins = require('gulp-load-plugins')();
// ...
.pipe(plugins.changed('app.css'))
.pipe(plugins.less())
// ...
gulp.watch(paths, tasks)
@colinodell - joind.in/talk/17992
gulp.task('watch', function() {
gulp.watch(paths.less, ['css']);
gulp.watch(paths.img, ['images']);
gulp.watch(paths.js, ['js']);
gulp.watch(paths.font, ['fonts']);
gulp.watch(paths.favicons, ['favicons']);
gulp.watch(paths.php, ['phpcs']);
});
gulp.watch(paths, tasks)
@colinodell - joind.in/talk/17992
• Example: https://youtu.be/9d9756j2pq8?t=100
Other Plugins & Integrations
• Browsersync – Live browser reloads
• gulp-notify – Sends notifications to OS notification center or Growl
• gulp-autopolyfiller – Like autoprefixer, but for JS polyfills
• gulp-git – Run Git commands within Gulp
• gulp-ssh – Connect to servers via SSH and SFTP
@colinodell - joind.in/talk/17992
Summary
@colinodell - joind.in/talk/17992
• Task runners help automate build processes
• Automate during development, CI, and deployment
• Gulp is fast, easy-to-use, and has tons of great plugins
Questions?
@colinodell - joind.in/talk/17992
Thanks!
Slides/Feedback:
https://joind.in/talk/17992
@colinodell - joind.in/talk/17992

More Related Content

What's hot

But we're already open source! Why would I want to bring my code to Apache?
But we're already open source! Why would I want to bring my code to Apache?But we're already open source! Why would I want to bring my code to Apache?
But we're already open source! Why would I want to bring my code to Apache?gagravarr
 
Matt's PSGI Archive
Matt's PSGI ArchiveMatt's PSGI Archive
Matt's PSGI ArchiveDave Cross
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainKen Collins
 
Perl in the Internet of Things
Perl in the Internet of ThingsPerl in the Internet of Things
Perl in the Internet of ThingsDave Cross
 
Getting Git Right
Getting Git RightGetting Git Right
Getting Git RightSven Peters
 
Modern Perl for the Unfrozen Paleolithic Perl Programmer
Modern Perl for the Unfrozen Paleolithic Perl ProgrammerModern Perl for the Unfrozen Paleolithic Perl Programmer
Modern Perl for the Unfrozen Paleolithic Perl ProgrammerJohn Anderson
 
VCS for Teamwork - GIT Workshop
VCS for Teamwork - GIT WorkshopVCS for Teamwork - GIT Workshop
VCS for Teamwork - GIT WorkshopAnis Ahmad
 
An introduction to git
An introduction to gitAn introduction to git
An introduction to gitolberger
 
Server Side Swift
Server Side SwiftServer Side Swift
Server Side SwiftChad Moone
 
Building real time applications with Symfony2
Building real time applications with Symfony2Building real time applications with Symfony2
Building real time applications with Symfony2Antonio Peric-Mazar
 
Ruby in office time reboot
Ruby in office time rebootRuby in office time reboot
Ruby in office time rebootKentaro Goto
 
Kamailio - Surfing Big Waves Of SIP With Style
Kamailio - Surfing Big Waves Of SIP With StyleKamailio - Surfing Big Waves Of SIP With Style
Kamailio - Surfing Big Waves Of SIP With StyleDaniel-Constantin Mierla
 

What's hot (20)

But we're already open source! Why would I want to bring my code to Apache?
But we're already open source! Why would I want to bring my code to Apache?But we're already open source! Why would I want to bring my code to Apache?
But we're already open source! Why would I want to bring my code to Apache?
 
Matt's PSGI Archive
Matt's PSGI ArchiveMatt's PSGI Archive
Matt's PSGI Archive
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own Domain
 
Perl in the Internet of Things
Perl in the Internet of ThingsPerl in the Internet of Things
Perl in the Internet of Things
 
Getting Git Right
Getting Git RightGetting Git Right
Getting Git Right
 
Modern Perl for the Unfrozen Paleolithic Perl Programmer
Modern Perl for the Unfrozen Paleolithic Perl ProgrammerModern Perl for the Unfrozen Paleolithic Perl Programmer
Modern Perl for the Unfrozen Paleolithic Perl Programmer
 
Git training v10
Git training v10Git training v10
Git training v10
 
Logstash and friends
Logstash and friendsLogstash and friends
Logstash and friends
 
Kamailio Updates - VUC 588
Kamailio Updates - VUC 588Kamailio Updates - VUC 588
Kamailio Updates - VUC 588
 
Perl in Teh Cloud
Perl in Teh CloudPerl in Teh Cloud
Perl in Teh Cloud
 
effective_r27
effective_r27effective_r27
effective_r27
 
VCS for Teamwork - GIT Workshop
VCS for Teamwork - GIT WorkshopVCS for Teamwork - GIT Workshop
VCS for Teamwork - GIT Workshop
 
An introduction to git
An introduction to gitAn introduction to git
An introduction to git
 
Plack at YAPC::NA 2010
Plack at YAPC::NA 2010Plack at YAPC::NA 2010
Plack at YAPC::NA 2010
 
Node.js cluster
Node.js clusterNode.js cluster
Node.js cluster
 
Kamailio - Load Balancing Load Balancers
Kamailio - Load Balancing Load BalancersKamailio - Load Balancing Load Balancers
Kamailio - Load Balancing Load Balancers
 
Server Side Swift
Server Side SwiftServer Side Swift
Server Side Swift
 
Building real time applications with Symfony2
Building real time applications with Symfony2Building real time applications with Symfony2
Building real time applications with Symfony2
 
Ruby in office time reboot
Ruby in office time rebootRuby in office time reboot
Ruby in office time reboot
 
Kamailio - Surfing Big Waves Of SIP With Style
Kamailio - Surfing Big Waves Of SIP With StyleKamailio - Surfing Big Waves Of SIP With Style
Kamailio - Surfing Big Waves Of SIP With Style
 

Viewers also liked

Debugging Effectively - SunshinePHP 2017
Debugging Effectively - SunshinePHP 2017Debugging Effectively - SunshinePHP 2017
Debugging Effectively - SunshinePHP 2017Colin O'Dell
 
From Docker to Production - SunshinePHP 2017
From Docker to Production - SunshinePHP 2017From Docker to Production - SunshinePHP 2017
From Docker to Production - SunshinePHP 2017Chris Tankersley
 
Debugging Effectively - PHP UK 2017
Debugging Effectively - PHP UK 2017Debugging Effectively - PHP UK 2017
Debugging Effectively - PHP UK 2017Colin O'Dell
 
Docker for Developers - Sunshine PHP
Docker for Developers - Sunshine PHPDocker for Developers - Sunshine PHP
Docker for Developers - Sunshine PHPChris Tankersley
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...James Titcumb
 
Zend Framework Foundations
Zend Framework FoundationsZend Framework Foundations
Zend Framework FoundationsChuck Reeves
 
php[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Upphp[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground UpJoe Ferguson
 
Amp your site an intro to accelerated mobile pages
Amp your site  an intro to accelerated mobile pagesAmp your site  an intro to accelerated mobile pages
Amp your site an intro to accelerated mobile pagesRobert McFrazier
 
Console Apps: php artisan forthe:win
Console Apps: php artisan forthe:win Console Apps: php artisan forthe:win
Console Apps: php artisan forthe:win Joe Ferguson
 
Presentation Bulgaria PHP
Presentation Bulgaria PHPPresentation Bulgaria PHP
Presentation Bulgaria PHPAlena Holligan
 
Code Coverage for Total Security in Application Migrations
Code Coverage for Total Security in Application MigrationsCode Coverage for Total Security in Application Migrations
Code Coverage for Total Security in Application MigrationsDana Luther
 
Dip Your Toes in the Sea of Security
Dip Your Toes in the Sea of SecurityDip Your Toes in the Sea of Security
Dip Your Toes in the Sea of SecurityJames Titcumb
 

Viewers also liked (20)

XP+Scrum+DevOps
XP+Scrum+DevOpsXP+Scrum+DevOps
XP+Scrum+DevOps
 
Debugging Effectively - SunshinePHP 2017
Debugging Effectively - SunshinePHP 2017Debugging Effectively - SunshinePHP 2017
Debugging Effectively - SunshinePHP 2017
 
From Docker to Production - SunshinePHP 2017
From Docker to Production - SunshinePHP 2017From Docker to Production - SunshinePHP 2017
From Docker to Production - SunshinePHP 2017
 
Debugging Effectively - PHP UK 2017
Debugging Effectively - PHP UK 2017Debugging Effectively - PHP UK 2017
Debugging Effectively - PHP UK 2017
 
Docker for Developers - Sunshine PHP
Docker for Developers - Sunshine PHPDocker for Developers - Sunshine PHP
Docker for Developers - Sunshine PHP
 
MVC in PHP
MVC in PHPMVC in PHP
MVC in PHP
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
Adding 1.21 Gigawatts to Applications with RabbitMQ (Bulgaria PHP 2016 - Tuto...
 
Create, test, secure, repeat
Create, test, secure, repeatCreate, test, secure, repeat
Create, test, secure, repeat
 
Hack the Future
Hack the FutureHack the Future
Hack the Future
 
Engineer - Mastering the Art of Software
Engineer - Mastering the Art of SoftwareEngineer - Mastering the Art of Software
Engineer - Mastering the Art of Software
 
Zend Framework Foundations
Zend Framework FoundationsZend Framework Foundations
Zend Framework Foundations
 
php[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Upphp[world] 2015 Training - Laravel from the Ground Up
php[world] 2015 Training - Laravel from the Ground Up
 
Amp your site an intro to accelerated mobile pages
Amp your site  an intro to accelerated mobile pagesAmp your site  an intro to accelerated mobile pages
Amp your site an intro to accelerated mobile pages
 
Console Apps: php artisan forthe:win
Console Apps: php artisan forthe:win Console Apps: php artisan forthe:win
Console Apps: php artisan forthe:win
 
Presentation Bulgaria PHP
Presentation Bulgaria PHPPresentation Bulgaria PHP
Presentation Bulgaria PHP
 
Code Coverage for Total Security in Application Migrations
Code Coverage for Total Security in Application MigrationsCode Coverage for Total Security in Application Migrations
Code Coverage for Total Security in Application Migrations
 
Git Empowered
Git EmpoweredGit Empowered
Git Empowered
 
Dip Your Toes in the Sea of Security
Dip Your Toes in the Sea of SecurityDip Your Toes in the Sea of Security
Dip Your Toes in the Sea of Security
 
Php extensions
Php extensionsPhp extensions
Php extensions
 
Conscious Coupling
Conscious CouplingConscious Coupling
Conscious Coupling
 

Similar to Automating Your Workflow with Gulp.js - php[world] 2016

Build Automation of PHP Applications
Build Automation of PHP ApplicationsBuild Automation of PHP Applications
Build Automation of PHP ApplicationsPavan Kumar N
 
Frontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeFrontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeDamien Seguin
 
World is changed. i feel it in the front end
World is changed. i feel it in the front endWorld is changed. i feel it in the front end
World is changed. i feel it in the front endAndriy Yun
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
6 tips for improving ruby performance
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performanceEngine Yard
 
DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...
DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...
DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...Aman Kohli
 
Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011Ryan Price
 
Killing the Angle Bracket
Killing the Angle BracketKilling the Angle Bracket
Killing the Angle Bracketjnewmanux
 
Introduction to Apache Amaterasu (Incubating): CD Framework For Your Big Data...
Introduction to Apache Amaterasu (Incubating): CD Framework For Your Big Data...Introduction to Apache Amaterasu (Incubating): CD Framework For Your Big Data...
Introduction to Apache Amaterasu (Incubating): CD Framework For Your Big Data...DataWorks Summit
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSMartin Hochel
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)dantleech
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebJames Rakich
 

Similar to Automating Your Workflow with Gulp.js - php[world] 2016 (20)

JS Essence
JS EssenceJS Essence
JS Essence
 
Build Automation of PHP Applications
Build Automation of PHP ApplicationsBuild Automation of PHP Applications
Build Automation of PHP Applications
 
Frontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeFrontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the like
 
World is changed. i feel it in the front end
World is changed. i feel it in the front endWorld is changed. i feel it in the front end
World is changed. i feel it in the front end
 
Knolx session
Knolx sessionKnolx session
Knolx session
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
PHP Development Tools
PHP  Development ToolsPHP  Development Tools
PHP Development Tools
 
6 tips for improving ruby performance
6 tips for improving ruby performance6 tips for improving ruby performance
6 tips for improving ruby performance
 
DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...
DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...
DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...
 
Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011Drupal Theme Development - DrupalCon Chicago 2011
Drupal Theme Development - DrupalCon Chicago 2011
 
Killing the Angle Bracket
Killing the Angle BracketKilling the Angle Bracket
Killing the Angle Bracket
 
Introduction to Apache Amaterasu (Incubating): CD Framework For Your Big Data...
Introduction to Apache Amaterasu (Incubating): CD Framework For Your Big Data...Introduction to Apache Amaterasu (Incubating): CD Framework For Your Big Data...
Introduction to Apache Amaterasu (Incubating): CD Framework For Your Big Data...
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJS
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)Exploring Async PHP (SF Live Berlin 2019)
Exploring Async PHP (SF Live Berlin 2019)
 
Into The Box 2018 Ortus Keynote
Into The Box 2018 Ortus KeynoteInto The Box 2018 Ortus Keynote
Into The Box 2018 Ortus Keynote
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
AD102 - Break out of the Box
AD102 - Break out of the BoxAD102 - Break out of the Box
AD102 - Break out of the Box
 
Brad Wood - CommandBox CLI
Brad Wood - CommandBox CLI Brad Wood - CommandBox CLI
Brad Wood - CommandBox CLI
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the Web
 

More from Colin O'Dell

Demystifying Unicode - Longhorn PHP 2021
Demystifying Unicode - Longhorn PHP 2021Demystifying Unicode - Longhorn PHP 2021
Demystifying Unicode - Longhorn PHP 2021Colin O'Dell
 
Releasing High Quality Packages - Longhorn PHP 2021
Releasing High Quality Packages - Longhorn PHP 2021Releasing High Quality Packages - Longhorn PHP 2021
Releasing High Quality Packages - Longhorn PHP 2021Colin O'Dell
 
Releasing High Quality PHP Packages - ConFoo Montreal 2019
Releasing High Quality PHP Packages - ConFoo Montreal 2019Releasing High Quality PHP Packages - ConFoo Montreal 2019
Releasing High Quality PHP Packages - ConFoo Montreal 2019Colin O'Dell
 
Debugging Effectively - ConFoo Montreal 2019
Debugging Effectively - ConFoo Montreal 2019Debugging Effectively - ConFoo Montreal 2019
Debugging Effectively - ConFoo Montreal 2019Colin O'Dell
 
Automating Deployments with Deployer - php[world] 2018
Automating Deployments with Deployer - php[world] 2018Automating Deployments with Deployer - php[world] 2018
Automating Deployments with Deployer - php[world] 2018Colin O'Dell
 
Releasing High-Quality Packages - php[world] 2018
Releasing High-Quality Packages - php[world] 2018Releasing High-Quality Packages - php[world] 2018
Releasing High-Quality Packages - php[world] 2018Colin O'Dell
 
Debugging Effectively - DrupalCon Nashville 2018
Debugging Effectively - DrupalCon Nashville 2018Debugging Effectively - DrupalCon Nashville 2018
Debugging Effectively - DrupalCon Nashville 2018Colin O'Dell
 
CommonMark: Markdown Done Right - ZendCon 2017
CommonMark: Markdown Done Right - ZendCon 2017CommonMark: Markdown Done Right - ZendCon 2017
CommonMark: Markdown Done Right - ZendCon 2017Colin O'Dell
 
Debugging Effectively - All Things Open 2017
Debugging Effectively - All Things Open 2017Debugging Effectively - All Things Open 2017
Debugging Effectively - All Things Open 2017Colin O'Dell
 
Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017Colin O'Dell
 
Debugging Effectively - ZendCon 2016
Debugging Effectively - ZendCon 2016Debugging Effectively - ZendCon 2016
Debugging Effectively - ZendCon 2016Colin O'Dell
 
Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Colin O'Dell
 
Hacking Your Way to Better Security - PHP South Africa 2016
Hacking Your Way to Better Security - PHP South Africa 2016Hacking Your Way to Better Security - PHP South Africa 2016
Hacking Your Way to Better Security - PHP South Africa 2016Colin O'Dell
 
Debugging Effectively - DrupalCon Europe 2016
Debugging Effectively - DrupalCon Europe 2016Debugging Effectively - DrupalCon Europe 2016
Debugging Effectively - DrupalCon Europe 2016Colin O'Dell
 
CommonMark: Markdown done right - Nomad PHP September 2016
CommonMark: Markdown done right - Nomad PHP September 2016CommonMark: Markdown done right - Nomad PHP September 2016
CommonMark: Markdown done right - Nomad PHP September 2016Colin O'Dell
 
Debugging Effectively - Frederick Web Tech 9/6/16
Debugging Effectively - Frederick Web Tech 9/6/16Debugging Effectively - Frederick Web Tech 9/6/16
Debugging Effectively - Frederick Web Tech 9/6/16Colin O'Dell
 
Debugging Effectively
Debugging EffectivelyDebugging Effectively
Debugging EffectivelyColin O'Dell
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Colin O'Dell
 
Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Colin O'Dell
 
CommonMark: Markdown Done Right
CommonMark: Markdown Done RightCommonMark: Markdown Done Right
CommonMark: Markdown Done RightColin O'Dell
 

More from Colin O'Dell (20)

Demystifying Unicode - Longhorn PHP 2021
Demystifying Unicode - Longhorn PHP 2021Demystifying Unicode - Longhorn PHP 2021
Demystifying Unicode - Longhorn PHP 2021
 
Releasing High Quality Packages - Longhorn PHP 2021
Releasing High Quality Packages - Longhorn PHP 2021Releasing High Quality Packages - Longhorn PHP 2021
Releasing High Quality Packages - Longhorn PHP 2021
 
Releasing High Quality PHP Packages - ConFoo Montreal 2019
Releasing High Quality PHP Packages - ConFoo Montreal 2019Releasing High Quality PHP Packages - ConFoo Montreal 2019
Releasing High Quality PHP Packages - ConFoo Montreal 2019
 
Debugging Effectively - ConFoo Montreal 2019
Debugging Effectively - ConFoo Montreal 2019Debugging Effectively - ConFoo Montreal 2019
Debugging Effectively - ConFoo Montreal 2019
 
Automating Deployments with Deployer - php[world] 2018
Automating Deployments with Deployer - php[world] 2018Automating Deployments with Deployer - php[world] 2018
Automating Deployments with Deployer - php[world] 2018
 
Releasing High-Quality Packages - php[world] 2018
Releasing High-Quality Packages - php[world] 2018Releasing High-Quality Packages - php[world] 2018
Releasing High-Quality Packages - php[world] 2018
 
Debugging Effectively - DrupalCon Nashville 2018
Debugging Effectively - DrupalCon Nashville 2018Debugging Effectively - DrupalCon Nashville 2018
Debugging Effectively - DrupalCon Nashville 2018
 
CommonMark: Markdown Done Right - ZendCon 2017
CommonMark: Markdown Done Right - ZendCon 2017CommonMark: Markdown Done Right - ZendCon 2017
CommonMark: Markdown Done Right - ZendCon 2017
 
Debugging Effectively - All Things Open 2017
Debugging Effectively - All Things Open 2017Debugging Effectively - All Things Open 2017
Debugging Effectively - All Things Open 2017
 
Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017Hacking Your Way To Better Security - DrupalCon Baltimore 2017
Hacking Your Way To Better Security - DrupalCon Baltimore 2017
 
Debugging Effectively - ZendCon 2016
Debugging Effectively - ZendCon 2016Debugging Effectively - ZendCon 2016
Debugging Effectively - ZendCon 2016
 
Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016Hacking Your Way to Better Security - ZendCon 2016
Hacking Your Way to Better Security - ZendCon 2016
 
Hacking Your Way to Better Security - PHP South Africa 2016
Hacking Your Way to Better Security - PHP South Africa 2016Hacking Your Way to Better Security - PHP South Africa 2016
Hacking Your Way to Better Security - PHP South Africa 2016
 
Debugging Effectively - DrupalCon Europe 2016
Debugging Effectively - DrupalCon Europe 2016Debugging Effectively - DrupalCon Europe 2016
Debugging Effectively - DrupalCon Europe 2016
 
CommonMark: Markdown done right - Nomad PHP September 2016
CommonMark: Markdown done right - Nomad PHP September 2016CommonMark: Markdown done right - Nomad PHP September 2016
CommonMark: Markdown done right - Nomad PHP September 2016
 
Debugging Effectively - Frederick Web Tech 9/6/16
Debugging Effectively - Frederick Web Tech 9/6/16Debugging Effectively - Frederick Web Tech 9/6/16
Debugging Effectively - Frederick Web Tech 9/6/16
 
Debugging Effectively
Debugging EffectivelyDebugging Effectively
Debugging Effectively
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016
 
Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016Hacking Your Way To Better Security - php[tek] 2016
Hacking Your Way To Better Security - php[tek] 2016
 
CommonMark: Markdown Done Right
CommonMark: Markdown Done RightCommonMark: Markdown Done Right
CommonMark: Markdown Done Right
 

Recently uploaded

How Does the Epitome of Spyware Differ from Other Malicious Software?
How Does the Epitome of Spyware Differ from Other Malicious Software?How Does the Epitome of Spyware Differ from Other Malicious Software?
How Does the Epitome of Spyware Differ from Other Malicious Software?AmeliaSmith90
 
ERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptxERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptxAutus Cyber Tech
 
Enterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze IncEnterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze Incrobinwilliams8624
 
Webinar_050417_LeClair12345666777889.ppt
Webinar_050417_LeClair12345666777889.pptWebinar_050417_LeClair12345666777889.ppt
Webinar_050417_LeClair12345666777889.pptkinjal48
 
Deep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - DatacampDeep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - DatacampVICTOR MAESTRE RAMIREZ
 
Streamlining Your Application Builds with Cloud Native Buildpacks
Streamlining Your Application Builds  with Cloud Native BuildpacksStreamlining Your Application Builds  with Cloud Native Buildpacks
Streamlining Your Application Builds with Cloud Native BuildpacksVish Abrams
 
JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIIvo Andreev
 
Generative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilGenerative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilVICTOR MAESTRE RAMIREZ
 
Why Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdfWhy Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdfBrain Inventory
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxJoão Esperancinha
 
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdfARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdfTobias Schneck
 
IA Generativa y Grafos de Neo4j: RAG time
IA Generativa y Grafos de Neo4j: RAG timeIA Generativa y Grafos de Neo4j: RAG time
IA Generativa y Grafos de Neo4j: RAG timeNeo4j
 
online pdf editor software solutions.pdf
online pdf editor software solutions.pdfonline pdf editor software solutions.pdf
online pdf editor software solutions.pdfMeon Technology
 
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLBig Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLAlluxio, Inc.
 
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...OnePlan Solutions
 
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Jaydeep Chhasatia
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadIvo Andreev
 
Your Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software TeamsYour Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software TeamsJaydeep Chhasatia
 
eAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionseAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionsNirav Modi
 

Recently uploaded (20)

How Does the Epitome of Spyware Differ from Other Malicious Software?
How Does the Epitome of Spyware Differ from Other Malicious Software?How Does the Epitome of Spyware Differ from Other Malicious Software?
How Does the Epitome of Spyware Differ from Other Malicious Software?
 
ERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptxERP For Electrical and Electronics manufecturing.pptx
ERP For Electrical and Electronics manufecturing.pptx
 
Enterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze IncEnterprise Document Management System - Qualityze Inc
Enterprise Document Management System - Qualityze Inc
 
Webinar_050417_LeClair12345666777889.ppt
Webinar_050417_LeClair12345666777889.pptWebinar_050417_LeClair12345666777889.ppt
Webinar_050417_LeClair12345666777889.ppt
 
Deep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - DatacampDeep Learning for Images with PyTorch - Datacamp
Deep Learning for Images with PyTorch - Datacamp
 
Streamlining Your Application Builds with Cloud Native Buildpacks
Streamlining Your Application Builds  with Cloud Native BuildpacksStreamlining Your Application Builds  with Cloud Native Buildpacks
Streamlining Your Application Builds with Cloud Native Buildpacks
 
JS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AIJS-Experts - Cybersecurity for Generative AI
JS-Experts - Cybersecurity for Generative AI
 
Salesforce AI Associate Certification.pptx
Salesforce AI Associate Certification.pptxSalesforce AI Associate Certification.pptx
Salesforce AI Associate Certification.pptx
 
Generative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-CouncilGenerative AI for Cybersecurity - EC-Council
Generative AI for Cybersecurity - EC-Council
 
Why Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdfWhy Choose Brain Inventory For Ecommerce Development.pdf
Why Choose Brain Inventory For Ecommerce Development.pdf
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptx
 
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdfARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
ARM Talk @ Rejekts - Will ARM be the new Mainstream in our Data Centers_.pdf
 
IA Generativa y Grafos de Neo4j: RAG time
IA Generativa y Grafos de Neo4j: RAG timeIA Generativa y Grafos de Neo4j: RAG time
IA Generativa y Grafos de Neo4j: RAG time
 
online pdf editor software solutions.pdf
online pdf editor software solutions.pdfonline pdf editor software solutions.pdf
online pdf editor software solutions.pdf
 
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/MLBig Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
Big Data Bellevue Meetup | Enhancing Python Data Loading in the Cloud for AI/ML
 
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
Transforming PMO Success with AI - Discover OnePlan Strategic Portfolio Work ...
 
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
Optimizing Business Potential: A Guide to Outsourcing Engineering Services in...
 
Cybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and BadCybersecurity Challenges with Generative AI - for Good and Bad
Cybersecurity Challenges with Generative AI - for Good and Bad
 
Your Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software TeamsYour Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
Your Vision, Our Expertise: TECUNIQUE's Tailored Software Teams
 
eAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspectionseAuditor Audits & Inspections - conduct field inspections
eAuditor Audits & Inspections - conduct field inspections
 

Automating Your Workflow with Gulp.js - php[world] 2016

  • 1. Automating Your Workflow with Gulp.js php[world] 2016 @colinodell - joind.in/talk/17992
  • 2. Colin O’Dell • Lead Web Developer at Unleashed Technologies • PHP League Member  league/commonmark  league/html-to-markdown • PHP 7 Upgrade Guide e-book @colinodell - joind.in/talk/17992
  • 3. Agenda • What Are Task Runners? • Getting Started with Gulp.js • Gulp API • Task Examples • Q&A @colinodell - joind.in/talk/17992
  • 4. What Are Task Runners? Software that automates, coordinates, and controls the process of running build tasks. • Define tasks & dependencies • Execute those tasks @colinodell - joind.in/talk/17992
  • 5. What Are Task Runners? Three types of tasks: 1. Tranformations 2. Tests 3. Commands @colinodell - joind.in/talk/17992
  • 6. Transformations • Compiling SASS/LESS, CoffeeScript, etc. • Combining/minifying files • Compressing images • Copying files to a different location @colinodell - joind.in/talk/17992 0110011 1001111 0010011 1010010 0110011 1001111 0010011 1010010
  • 7. Running Tests • Linting for syntax errors • Checking code styles • Running automated tests (unit, functional, etc) @colinodell - joind.in/talk/17992 0110011 1001111 0010011 1010010 ✓✗
  • 8. Running Misc. Commands • Deleting previous builds • Installing dependencies with Composer, npm, bower, yarn, etc. • Any shell command @colinodell - joind.in/talk/17992 ✓✗
  • 10. When/Where To Run Build Tasks • Locally during development • Continuous integration • Deployments @colinodell - joind.in/talk/17992
  • 11. Different Task Runners Comparison between Apache Ant, Phing, Grunt, and Gulp @colinodell - joind.in/talk/17992
  • 12. Apache Ant • Like Make, but built in Java • Typically installed via package manager (apt-get) • XML configuration files @colinodell - joind.in/talk/17992 <?xml version="1.0"?> <project name="Hello World Project" default="info"> <target name="info"> <echo>Hello World - Welcome to Apache Ant!</echo> </target> </project>
  • 13. Apache Ant @colinodell - joind.in/talk/17992 <?xml version="1.0"?> <project name="Compress CSS and run PHPUnit" default="build"> <target name="build" depends="compress_css,phpunit"/> <target name="compress_css"> <apply executable="java" parallel="false"> <fileset dir="." includes="foo.css, bar.css"/> <arg line="-jar"/> <arg path="yuicompressor.jar"/> <srcfile/> <arg line="-o"/> <mapper type="glob" from="*.css" to="*-min.css"/> <targetfile/> </apply> </target> <target name="phpunit"> <exec executable="./vendor/bin/phpunit" failonerror="true"> <arg value="--configuration"/> <arg path="phpunit.xml"/> </exec> </target> </project>
  • 14. Phing • Based on Apache Ant, but built in PHP • Typically installed via PEAR or Composer • XML configuration files @colinodell - joind.in/talk/17992 <?xml version="1.0"?> <project name="Hello World Project" default="info"> <target name="info"> <echo>Hello World - Welcome to Apache Ant!</echo> </target> </project>
  • 15. Apache Ant @colinodell - joind.in/talk/17992 <?xml version="1.0"?> <project name="Compress CSS and run PHPUnit" default="build"> <target name="build" depends="compress_css,phpunit"/> <target name="compress_css"> <apply executable="java" parallel="false"> <fileset dir="." includes="foo.css, bar.css"/> <arg line="-jar"/> <arg path="yuicompressor.jar"/> <srcfile/> <arg line="-o"/> <mapper type="glob" from="*.css" to="*-min.css"/> <targetfile/> </apply> </target> <target name="phpunit"> <exec executable="./vendor/bin/phpunit" failonerror="true"> <arg value="--configuration"/> <arg path="phpunit.xml"/> </exec> </target> </project>
  • 16. @colinodell - joind.in/talk/17992 <?xml version="1.0"?> <project name="Compress CSS and run PHPUnit" default="build"> <target name="build" depends="compress_css,phpunit"/> <target name="compress_css"> <apply executable="java" parallel="false"> <fileset dir="." includes="foo.css, bar.css"/> <arg line="-jar"/> <arg path="yuicompressor.jar"/> <srcfile/> <arg line="-o"/> <mapper type="glob" from="*.css" to="*-min.css"/> <targetfile/> </apply> </target> <target name="phpunit"> <phpunit pharlocation="./vendor/bin/phpunit" configuration="phpunit.xml"/> </target> </project>
  • 17. Grunt • Built in JavaScript • Many third-party plugins; easy to install • JS-based configuration with heavy JSON usage @colinodell - joind.in/talk/17992 var grunt = require('grunt'); grunt.registerTask('default', 'The default build task', function(){ console.log('Hello World!'); });
  • 18. @colinodell - joind.in/talk/17992 var grunt = require('grunt'); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-phpunit'); grunt.initConfig({ cssmin: { target: { files: [{ src: ['foo.css', 'bar.css'], dest: 'build/css', ext: '.min.css' }] } }, phpunit: { options: { bin: 'vendor/bin/phpunit', configuration: 'phpunit.xml', coverage: false } } }); grunt.registerTask('default', 'The default build task', ['cssmin', 'phpunit']);
  • 19. Gulp.js • Built in JavaScript • Many third-party plugins; easy to install • Uses JS code instead of configuration • Built around file streams @colinodell - joind.in/talk/17992 var gulp = require('gulp'); gulp.task('default', function() { console.log('Hello world.'); });
  • 20. @colinodell - joind.in/talk/17992 var gulp = require('gulp'); var cssmin = require('gulp-minify-css'); var phpunit = require('gulp-phpunit'); var rename = require('gulp-rename'); gulp.task('cssmin', function() { return gulp.src(['foo.css', 'bar.css']) .pipe(minifycss()) .pipe(rename({ suffix: '.min' })) .pipe(gulp.dest('build/css')); }); gulp.task('phpunit', function() { var options = { noCoverage: true }; return gulp.src('phpunit.xml') .pipe(phpunit('./vendor/bin/phpunit', options)); }); gulp.task('default', ['cssmin', 'phpunit']);
  • 23. Installing gulp-cli @colinodell - joind.in/talk/17992
  • 24. Initializing npm @colinodell - joind.in/talk/17992
  • 25. Adding gulp to a project @colinodell - joind.in/talk/17992
  • 26. Adding gulp to a project @colinodell - joind.in/talk/17992
  • 27. gulpfile.js @colinodell - joind.in/talk/17992 var gulp = require('gulp'); gulp.task('default', function() { // place code for your default task here });
  • 29. Gulp API @colinodell - joind.in/talk/17992
  • 30. gulp.task(name [, deps] [, fn]) • Defines tasks and their dependencies • Three parameters:  Name (required)  Array of task dependencies  Function to run @colinodell - joind.in/talk/17992 gulp.task('sometask', function() { // Do stuff }); gulp.task('sometask', ['dep1', 'dep2'], function() { // Do stuff }); gulp.task('js', ['jshint', 'jsmin']);
  • 31. gulp.src(globs [, options]) • Two parameters:  Globs of files (required)  String or array  Options • Returns a stream of Vinyl files that can be piped to plugins @colinodell - joind.in/talk/17992 gulp.src('styles/foo.css') gulp.src('styles/*.css') gulp.src('styles/**/*.css') gulp.src(['styles/**/*.css', '!*.min.css'])
  • 32. var themeBase = 'src/theme'; var distThemeBase = 'web/theme'; var paths = { img: [themeBase + '/img/**/*.{gif,png,jpg,svg,svgz}'], js: [themeBase + '/js/**/*.js'], font: [themeBase + '/fonts/**/*.{otf,eot,svg,ttf,woff,woff2}'], css: [themeBase + '/styles/**/*.css'], favicons: [themeBase + '/favicons/**/*.{png,xml,ico,json,svg}'], php: ['src/**/*.php'], xml: ['src/**/*.xml'], distContrib: distThemeBase + '/contrib/', distCSS: distThemeBase + '/css/', distJS: distThemeBase + '/js/', distImg: distThemeBase + '/img/', distFont: distThemeBase + '/fonts/', distFavicons: distThemeBase + '/favicons/' }; gulp.src(paths.css); @colinodell - joind.in/talk/17992
  • 33. .pipe(destination) • Called on gulp.src() result stream • destination is a stream (typically an input stream created by a plugin) @colinodell - joind.in/talk/17992 return gulp.src(['foo.css', 'bar.css']) .pipe(minifycss()) .pipe(rename({ suffix: '.min' })) .pipe(gulp.dest('build/css'));
  • 34. gulp.dest(path [,options]) • Writes the streamed files to the given path @colinodell - joind.in/talk/17992 return gulp.src(['foo.css', 'bar.css']) .pipe(minifycss()) .pipe(rename({ suffix: '.min' })) .pipe(gulp.dest('build/css'));
  • 35. Examples Code Linting @colinodell - joind.in/talk/17992
  • 36. jshint @colinodell - joind.in/talk/17992 var jshint = require('gulp-jshint'); gulp.task('jshint', function() { return gulp.src(paths.js) .pipe(jshint()) .pipe(jshint.reporter()) .pipe(jshint.reporter('fail')); });
  • 38. csslint @colinodell - joind.in/talk/17992 var csslint = require('gulp-csslint'); gulp.task('csslint', function() { return gulp.src([paths.css, '!**/*.min.css']) .pipe(csslint('.csslintrc')) .pipe(csslint.reporter()) .pipe(csslint.failReporter()); });
  • 39. phplint @colinodell - joind.in/talk/17992 var phplint = require('gulp-phplint'); gulp.task('phplint', function() { return gulp.src(paths.phpLint) .pipe(phplint()) .pipe(phplint.reporter('fail')); });
  • 40. phpcs @colinodell - joind.in/talk/17992 var phpcs = require('gulp-phpcs'); gulp.task('phpcs', ['phplint'], function() { var options = { bin: 'vendor/bin/phpcs', standard: 'PSR2 }; return gulp.src(paths.php) .pipe(phpcs(options)) .pipe(phpcs.reporter('log')) .pipe(phpcs.reporter('fail')); });
  • 41. eol @colinodell - joind.in/talk/17992 var eol = require('gulp-eol-enforce'); gulp.task('eol', function(){ var paths = [].concat(paths.php, paths.less, paths.js, paths.xml); return gulp.src(paths) .pipe(eol('n')); });
  • 42. 'lint' task group @colinodell - joind.in/talk/17992 gulp.task('lint', ['eol', 'phpcs', 'csslint', 'jshint']); gulp.task('lint', function() { gulp.start('eol', 'phpcs', 'csslint', 'jshint'); });
  • 44. Compile, autoprefix, and minify LESS @colinodell - joind.in/talk/17992 var autoprefixer = require('gulp-autoprefixer'), less = require('gulp-less'), minifycss = require('gulp-minify-css'), rename = require('gulp-rename') ; gulp.task('less', function() { return gulp.src(paths.less) .pipe(less()) .pipe(autoprefixer({ browsers: ['last 3 versions', 'ie >= 8'] })) .pipe(minifycss()) .pipe(rename({ suffix: '.min' })) .pipe(gulp.dest(paths.distCSS)); });
  • 45. Compile, autoprefix, and minify SASS @colinodell - joind.in/talk/17992 var autoprefixer = require('gulp-autoprefixer'), sass = require('gulp-sass'), minifycss = require('gulp-minify-css'), rename = require('gulp-rename') ; gulp.task('sass', function() { return gulp.src(paths.sass) .pipe(sass()) .pipe(autoprefixer({ browsers: ['last 3 versions', 'ie >= 8'] })) .pipe(minifycss()) .pipe(rename({ suffix: '.min' })) .pipe(gulp.dest(paths.distCSS)); });
  • 46. Compressing Images @colinodell - joind.in/talk/17992 var imagemin = require('gulp-imagemin'); gulp.task('images', function () { var options = { svgoPlugins: [{removeViewBox: false}] }; return gulp.src(paths.img) .pipe(imagemin(options)) .pipe(gulp.dest(paths.distImg)); });
  • 47. Examples Unit Tests @colinodell - joind.in/talk/17992
  • 48. PHPUnit Tests @colinodell - joind.in/talk/17992 var phpunit = require('gulp-phpunit'); gulp.task('phpunit', function () { return gulp.src('phpunit.xml') .pipe(phpunit('./vendor/bin/phpunit', {notify: true})); });
  • 50. Run Shell Commands @colinodell - joind.in/talk/17992 var shell = require('gulp-shell'); gulp.task('deps', shell.task([ 'composer install', 'npm install', 'bower install' ]));
  • 51. Examples Task Groups @colinodell - joind.in/talk/17992
  • 52. Task Groups @colinodell - joind.in/talk/17992 gulp.task('lint', function() { gulp.start('eol', 'phpcs', 'csslint', 'jshint'); }); gulp.task('build', function() { gulp.start('css', 'images', 'js', 'fonts', 'favicons'); }); gulp.task('test', function() { gulp.start('lint', 'phpcs'); }); gulp.task('default', function() { gulp.start('test', 'build'); });
  • 55. Useful Utilities @colinodell - joind.in/talk/17992
  • 56. gulp-changed @colinodell - joind.in/talk/17992 var imagemin = require('gulp-imagemin'); gulp.task('images', function () { var options = { svgoPlugins: [{removeViewBox: false}] }; return gulp.src(paths.img) .pipe(imagemin(options)) .pipe(gulp.dest(paths.distImg)); });
  • 57. gulp-changed @colinodell - joind.in/talk/17992 var changed = require('gulp-changed'); var imagemin = require('gulp-imagemin'); gulp.task('images', function () { var options = { svgoPlugins: [{removeViewBox: false}] }; return gulp.src(paths.img) .pipe(changed(paths.distImg)) .pipe(imagemin(options)) .pipe(gulp.dest(paths.distImg)); });
  • 58. gulp-newer @colinodell - joind.in/talk/17992 var gulp = require('gulp'); var newer = require('gulp-newer'); var concat = require('gulp-concat'); gulp.task('concat', function() { return gulp.src('lib/*.js') .pipe(newer('dist/all.js')) .pipe(concat('all.js')) .pipe(gulp.dest('dist')); });
  • 59. var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); gulp.task('build-js', function() { return gulp.src(paths.js) .pipe(concat('app.js')) .pipe(uglify()) .pipe(gulp.dest(paths.distJs)); }); gulp-sourcemaps @colinodell - joind.in/talk/17992
  • 60. var concat = require('gulp-concat'); var uglify = require('gulp-uglify'); var sourcemaps = require('gulp-sourcemaps'); gulp.task('build-js', function() { return gulp.src(paths.js) .pipe(sourcemaps.init()) .pipe(concat('app.js')) .pipe(uglify()) .pipe(sourcemaps.write()) .pipe(gulp.dest(paths.distJs)); }); gulp-sourcemaps @colinodell - joind.in/talk/17992
  • 61. gulp-load-plugins @colinodell - joind.in/talk/17992 { "devDependencies": { "gulp": "~3.9", "gulp-autoprefixer": "~2.3.1", "gulp-bower": "~0.0.10", "gulp-changed": "~1.2.1", "gulp-csslint": "~0.1.5", "gulp-eol-enforce": "*", "gulp-imagemin": "~2.3.0", "gulp-jshint": "~1.11.2", "gulp-less": "~3.0.3", "gulp-minify-css": "~1.2.0", "gulp-phpcs": "~0.6.0", "gulp-rename": "~1.2.2", "gulp-uglify": "~1.2.0" } } var gulp = require('gulp'), autoprefixer = require('gulp-autoprefixer'), bower = require('gulp-bower'), changed = require('gulp-changed'), csslint = require('gulp-csslint'), eol = require('gulp-eol-enforce'), imagemin = require('gulp-imagemin'), jshint = require('gulp-jshint'), less = require('gulp-less'), minifycss = require('gulp-minify-css'), phpcs = require('gulp-phpcs'), rename = require('gulp-rename'), uglify = require('gulp-uglify');
  • 62. gulp-load-plugins @colinodell - joind.in/talk/17992 { "devDependencies": { "gulp": "~3.9", "gulp-autoprefixer": "~2.3.1", "gulp-bower": "~0.0.10", "gulp-changed": "~1.2.1", "gulp-csslint": "~0.1.5", "gulp-eol-enforce": "*", "gulp-imagemin": "~2.3.0", "gulp-jshint": "~1.11.2", "gulp-less": "~3.0.3", "gulp-minify-css": "~1.2.0", "gulp-phpcs": "~0.6.0", "gulp-rename": "~1.2.2", "gulp-uglify": "~1.2.0" } } var gulp = require('gulp'), plugins = require('gulp-load-plugins')(); // ... .pipe(plugins.changed('app.css')) .pipe(plugins.less()) // ...
  • 63. gulp.watch(paths, tasks) @colinodell - joind.in/talk/17992 gulp.task('watch', function() { gulp.watch(paths.less, ['css']); gulp.watch(paths.img, ['images']); gulp.watch(paths.js, ['js']); gulp.watch(paths.font, ['fonts']); gulp.watch(paths.favicons, ['favicons']); gulp.watch(paths.php, ['phpcs']); });
  • 64. gulp.watch(paths, tasks) @colinodell - joind.in/talk/17992 • Example: https://youtu.be/9d9756j2pq8?t=100
  • 65. Other Plugins & Integrations • Browsersync – Live browser reloads • gulp-notify – Sends notifications to OS notification center or Growl • gulp-autopolyfiller – Like autoprefixer, but for JS polyfills • gulp-git – Run Git commands within Gulp • gulp-ssh – Connect to servers via SSH and SFTP @colinodell - joind.in/talk/17992
  • 66. Summary @colinodell - joind.in/talk/17992 • Task runners help automate build processes • Automate during development, CI, and deployment • Gulp is fast, easy-to-use, and has tons of great plugins

Editor's Notes

  1. 2-3 EXAMPLES OF TASKS
  2. Vinyl is a very simple metadata object that describes a file. When you think of a file, two attributes come to mind: path and contents. These are the main attributes on a Vinyl object. A file does not necessarily represent something on your computer’s file system. You have files on S3, FTP, Dropbox, Box, CloudThingly.io and other services. Vinyl can be used to describe files from all of these sources. No intermediate writes Non-blocking
  3. Similar to gulp-changed, but supports many-to-one mappings
  4. FINAL
  5. ASK ALEXA!!!