By Milan Herda / @moriquend 11/2014
Milan Herda, na internete perún alebo moriquend
 
                 
                Composer, nejdůležitější nástroj pro PHP vývojáře
                    $ curl -sS https://getcomposer.org/installer | php
                    
                    $ alias composer='composer.phar'
                    
                    $ composer require symfony/yaml
                     
				
                    $ composer require doctrine/orm
                     
                Špecifikácia vyžadovaných knižníc. Verzie nemusia byť zapísané presne, stačí približne a composer si automaticky dotiahne najnovšiu vyhovujúcu.
{
    "require": {
        "symfony/yaml": "~2.5",
        "doctrine/orm": "~2.4"
    }
}
                    Do tohto súboru si composer poznačí presné verzie (tj. major.minor.patch alebo git hash musí sedieť) nainštalovaných knižníc a ktokoľvek kedykoľvek napíše v adresári s projektom príkaz:
                    $ composer install
                    Composer mu automaticky nainštaluje všetky chýbajúce knižnice podľa definície v composer.lock.
Dva základné príkazy pre composer
.
                    $ composer install
                    Pokiaľ existuje súbor composer.lock, tak nainštaluje knižnice podľa špecifikácie v tomto súbore.
Pokiaľ neexistuje, inštaluje podľa compose.json
                    $ composer update
                    Inštaluje podľa composer.json a nainštalované verzie zapisuje do composer.lock
Composer automaticky inštaluje do adresáru s názvom vendor a po každej inštalácii vytvorí aj súbory pre autoloading.
Vytvoríme si knižnicu na generovanie náhodnej farby a ukážeme si, ako ju nainštalovať do nášho projektu.
$ mkdir -p random-color
$ cd random-color
$ composer init
                    
{
    "name": "perun/random-color",
    "description": "Stupid library to generate random color code",
    "authors": [
        {
            "name": "Milan Herda",
            "email": "perun@perunhq.org"
        }
    ],
    "minimum-stability": "dev",
    "autoload": {
        "psr-0": {
            "": "src"
        }
    },
    "require": {}
}
                    PSR-0 vyžaduje, aby sme mali zdrojové súbory v adresároch podľa vzoru vendor-name/package-name a je zaužívané, že táto štruktúra je ešte uložená v adresári src. V našom prípade teda vytvoríme príslušný adresár:
$ mkdir -p src/Perun/RandomColor
                    Pokiaľ chcete jednoduchšiu štruktúru, použite PSR-4. PSR-0 je už aj tak deprecated.
<?php
namespace Perun\RandomColor;
/**
 * Generates random color
 *
 * @author Milan Herda <perun@perunhq.org>
 */
class RandomColorGenerator
{
    /**
     * @return string
     */
    public function generate()
    {
        return 'rgb(' . rand(0, 255) . ', ' . rand(0, 255) . ', ' . rand(0, 255) . ')';
    }
}
                    Aby bol balíček inštalovateľný cez composer, tak sa k nemu composer musí dostať.
$ git init
$ git add .
$ git ci -am "initial commit"
$ git tag v0.0.1
                     
                Niekde inde na disku si vytvoríme adresár s naším novým projektom a v ňom vytvoríme composer.json s nasledovným obsahom:
{
    "name": "perun/project",
    "authors": [
        {
            "name": "Milan Herda",
            "email": "perun@perunhq.org"
        }
    ],
    "repositories": [
        {
            "type": "vcs",
            "url": "/home/perun/lib/random-color/"
        }
    ],
    "require": {
        "perun/random-color": "~0.0.1"
    }
}
                     
                
<?php
require 'vendor/autoload.php';
use Perun\RandomColor\RandomColorGenerator;
$randomColorGenerator = new RandomColorGenerator();
echo $randomColorGenerator->generate();
                    Skutočnú silu uvidíte až vo chvíli, keď si balíčky budete umiestňovať do nejakého repozitára dostupného všetkým členom tímu:
Inštaluje balíčky a poskytuje načítavanie tried cez autoloading
Už nikdy nebudete sťahovať jquery, bootstrap, angular ručne.
* a cssBower sa inštaluje pomocou NPM
 
                    
                    $ npm install -g bower
                    bower.json
{
  "name": "perun/project",
  "version": "0.0.1",
  "authors": [
    "Milan Herda <perun@perunhq.org>"
  ],
  "license": "proprietary",
  "private": true,
  "dependencies": {
    "lodash": "~2.4.1",
    "bootstrap": "~3.2.0"
  }
}
                    .bowerrc
{
    "directory": "assets/vendor"
}
                    
                    $ bower install
                    Stiahne balíčky definované v bower.json do adresára (defaultne bower_components)
                    $ bower update
                    bower nemá žiaden lock súbor ako má composer. Pri install a update priamo porovnáva to, čo už nainštaloval. Pokiaľ nejaký balíček chýba, tak ho dotiahne.
bower iba sťahuje balíčky a rieši ich vzájomné závislosti pri inštalácii.
Neposkytuje žiadnu funcionalitu pre "includovanie". Tj. stiahnutý balíček si musíte do webu vložiť ručne cez <script> tag alebo pomocou nejakého loaderu (napr. requirejs)
                    $ npm install -g grunt-cli
                    Gruntfile.js
module.exports = function(grunt) {
    // Project configuration.
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        srcAssetsDir: 'assets',
        webDir: 'www',
        clean: ['www/assets'],
        copy: {
            main: {
                files: [
                    {
                        expand: true,
                        src: ['assets/**'],
                        dest: 'www/'
                    },
                    {
                        expand: true,
                        cwd: 'assets/vendor/bootstrap/fonts',
                        src: ['*'],
                        dest: 'www/assets/css/fonts/'
                    }
                ]
            }
        },
        sass: {
            dist: {
                files: [{
                    expand: true,
                    cwd: 'assets/sass',
                    src: ['*.scss'],
                    dest: 'assets/css',
                    ext: '.css'
                }]
            }
        },
        watch: {
            all: {
                files: [
                    'assets/**/*',
                    'www/*html',
                ],
                tasks: ['clean', 'sass', 'copy', 'jshint', 'jslint'],
                options: {
                    livereload: true,
                    spawn: false
                }
            }
        },
        jshint: {
            options: {
                reporter: require('jshint-stylish'),
                bitwise: true,
                camelcase: true,
                curly: true,
                eqeqeq: true,
                forin: true,
                immed: true,
                indent: 4,
                latedef: true,
                newcap: true,
                noarg: true,
                //nonbsp: true,
                nonew: true,
                plusplus: true,
                quotmark: 'single',
                undef: true,
                unused: true,
                strict: true,
                trailing: true,
                globals: {
                    define: true,
                    require: true,
                    window: true,
                    document: true
                }
            },
            all: [
                'assets/js/**/*.js'
            ]
        },
        jslint: {
            main: {
                src: 'assets/js/**/*.js',
                directives: {
                    predef: ['define', 'require', 'window', 'document']
                },
                options: {
                    failOnError: false,
                }
            }
        },
    });
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-jslint');
    // Default task(s).
    grunt.registerTask('default', ['clean', 'copy']);
};
                    
                    $ grunt watch
                    Gulp a Grunt sú konkurenti a oba robia to isté. Rozdiel je v spôsobe.
Gruntove tasky sa zapisujú pomocou konfigurácie. Pokiaľ máte task zložený so subtaskov, tak každý task sa vykonáva samostatne a teda po každom sa zmeny v súboroch zapíšu na disk.
Gulpove tasky sa zapisujú direktívne. Namiesto konfigurácie píšete javascriptové príkazy. Zložené tasky vedia zmeny posielať cez pipe-u, tj. na disk sa zapíše až na konci.
Gulp je z definície rýchlejší a flexibilnejší.
Grunt existuje dlhšie a má viac pluginov.
Aktuálne je len vecou vkusu, čo si kto vyberie. Časom ale zrejme prevládne Gulp. Pokiaľ nepríde tretí hráč.