Make love, not var_dump())

Captain's Log

Efem, 1.5 aydır blog yazamasak da bu süre zarfında kod.io, Özgür Web Teknolojileri Günleri, Google DevFest ve Laravel Türkiye etkinliklerinde sponsor ve konuşmacı olarak görev aldık. Yine çeşitli insanlarla falan tanıştık. Bu telaşede de blog yazmayı biraz ihmal ettik, grunt ile bir geri dönüş yapalım dedik.


Her ne kadar "kendizi çok da geliştirmeyin, belli bir yerde durun" diye ahkam kessem de bu deli sektör sizi bir şeyler öğrenmeye mecbur kılıyor. Bundan iki sene önceki "frontend developer" ile şu anki "frontend developer" tanımlamaları bile oldukça değişti. İki sene önce "eli HTML/CSS tutan adama" frontend developer derken, artık frontend developer dediğimiz kitle yavaş yavaş en azından bir JavaScript MVC framework bilen, less'dir stylus'dur bir css pre-processor bilen, jshint, csslint gibi araçlarla daha düzgün kod yazmaya özen gösteren, test falan yazan insanlar olmaya başladı.


Ama bu süreçte, bu organizmaların otomatize etmesi gereken işler oluşmaya başladı:

  • Hazırladığı css ve javascript dosyalarını jshint, csslint gibi araçlardan geçirme
  • Coffescript, less gibi pre-processor'lerle yazdığı kodları derleme
  • Yine bu dosyaları tek dosya haline getirme
  • Bu dosyaları sıkıştırma
  • Kullanılan resim dosyalarını sıkıştırma
  • ...

Bu tip araçlar için unix dünyasından aşina olduğumuz makefile'lar denendi önce. Bir çok kütüphane (jQuery vs) bu tip işler için makefile kullanıyordu. Yine bazı projelerde Java dünyasından aşina olduğumuz Ant veya Maven gibi araçlar kullanılıyordu. Ya da oturup kendi bash scriptlerimizi yazıyorduk.


Ben hala make varken neden "ant" gibi bir şey icad edip yazılımcılar olarak kendi topuğumuza sıktığımızı bile tam olarak anlamamışken bir grup geliştirici Grunt'ı duyurdu.


Grunt temelde; ant'ın veya makefile'ın yaptığı işi JavaScript ile, Nodejs modülleri ile yapan "Not Invented Here"a örnek gösterilecek(zaaa xd) başka bir "Task Runner". Ve maalesef günümüz "frontend developer"larının bilmesi gereken bir kavram haline geldi. (grunt olmasa da Gulp gibi başka bir task runner).

Kendisi de bir Nodejs modülü olan grunt, yukarıda saydığım tür işleri otomatize etmek, frontend developer'ların yaptığı çoğu hamaliyeye son vermek için oluşturuldu. Bunun yanında günümüz frontend developer'larının ihtiyacı haline gelen bir çok iş için (örneğin; resim dosyalarından sprite üretme) de hazır modüller sunuyor.

Grunt'ı kurmak için temelde 2 dosyaya ihtiyacınız var:

  1. package.json: aslında grunt için değil ama kullanacağımınız node modüllerinin bağımlılıkları için diyelim
  2. Gruntfile.js: make'in Makefile'ı, ant'ın build.xml'i varsa, grunt'ın da Gruntfile.js'i var

package.json dosyasınız eğer yoksa aşağıdaki gibi oluşturduktan sonra $ npm install komutunu vererek gerekli bağımlılıkları kurabilirsiniz.

{
  "name": "my-project-name",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.2",
    "grunt-contrib-jshint": "~0.6.3",
    "grunt-contrib-nodeunit": "~0.2.0",
    "grunt-contrib-uglify": "~0.2.2"
  }
}

Burada dilediğiniz Grunt plugin'inini http://gruntjs.com/plugins adresinden bulup ekleyebilirsiniz veya
npm install node-modülü-adı --save-dev
diyerek de package.json dosyasını güncelleyebilirsiniz.


Gruntfile.js dosyası da içinde bazı yapılandırma fonksiyonları ve parametreleri (kısaca JavaScript kodları) bulunan şunun gibi bir dosya:

module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    // pluginlerin kendi configurasyon parametrelerini plugin'in sayfasından öğrenebilirsiniz
    uglify: { 
      options: {
        // grunt kendi içinde basit bir templating sistemiyle de geliyor
        banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
      },
      build: { // uglify:build taski de bu parametrelerle çalışıyormuş
        src: 'src/<%= pkg.name %>.js',
        dest: 'build/<%= pkg.name %>.min.js'
      }
    },
    
    clean: { // örneğin clean task'i public/static içindeki her şeyi siliyor
      public: ["public/static"] 
    },

  });

  // Burada yüklenecek grunt plugin'lerini ekliyoruz
  grunt.loadNpmTasks('grunt-contrib-uglify');

  // Burada da task'leri oluşturabiliyoruz
  // burada default task gidip  initConfig içindeki "uglify" taskini çalıştırıyormuş mesela
  grunt.registerTask('default', ['uglify']);
  
  // başka bir örnek aşağıdaki gibi olabilir
  // deploy'dan önce "clean" taski sonra da "uglfy" taski çalışıyor olabilir
  grunt.registerTask('deploy', ['clean',  'uglify']);

};

Bunları tanımladıktan sonra istersek teker teker config'deki task'lerin adını verebilir, istersek de register ettiğimiz diğer task'leri çalıştırabiliriz:
$ grunt 
$ grunt deploy
$ grunt uglify
$ grunt herhangi_bir_task


Otomatize edeceğiniz her frontend görevi için bir grunt modülü ekleyip, çoğu işteki hamaliyenizden kurtulabilir, daha maintain edilebilir frontend kodları yazabilirsiniz.


Frontend developer'ların, tasarımcıların ve hatta release manager'ların en çok seveceği grunt paketinden birisi de SpriteSmith.
SpriteSmith koyduğunuz ufak resimlerden, sprite'lar üretip bunların css'lerini üreten çok güzel bir araç. Bu sayede hem tasarımcı sprite dosyası oluşturmakla uğraşmıyor, hem frontend developer "bu resim hangi koordinattaydı, boyutu neydi" gibi şeylerle uğraşmmıyor, hem sprite dosyasında oluşan conflict'ler sonrası sürüm yöneticiniz ağlamıyor.

SpriteSmith ve bunun gibi bir çok hayat kurtaran eklenti için Grunt Plugin'lerini incelemeyi unutmayın