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áč.