Hitta nått kul:
13 Pixlar   /   Artiklar   /   Kom igång med Grunt

Kom igång med Grunt

Guide till Grunt. Hur Grunt fungerar och varför det är ett fantastiskt verktyg för frontendutvecklare.

30 april, 2014

När man som frontendutvecklare arbetar med webbprojekt finns det vissa delar i ens workflow som är både tråkiga och arbetsamma men ack så viktiga. Det kan handla om att minifiera Javascript och CSS, optimera bilder eller kompilera SASS eller LESS till CSS. Visst vore det skönt om vi kunde automatisera detta?

Grunt är en uppgiftsautomatiserare (puh, långt ord) som kan hjälpa oss med detta. Grunt kan även göra en uppsjö andra saker och när man väl kommit igång är det lätt att låta Grunt ta över mer och mer av sina repetitiva och trista uppgifter. I denna artikel går vi igenom Grunt från början och sätter upp dessa uppgifter i vårt projekt.

Varför en till guide om Grunt?

Det finns redan en hel del Grunt-guider att läsa, många är bra, andra är mindre bra. Det som inte funnits är en guide till Grunt på svenska. Denna artikel försöker råda bot på detta och beskriver processen för att komma igång med Grunt och tipsar om en hel del bra Grunt-plugins. Som allt innehåll här på 13 Pixlar är denna Grunt-artikel skriven på svenska.

Vad kan Grunt göra?

Här är några exempel på vad grunt kan hjälpa en frontendutvecklare med:

  • Konkatenera (slå ihop) Javascript-filer för att minimera antalet requests
  • Minifiera Javascript och CSS för att minska filstorleken
  • Optimera bilder för att minska filstorleken
  • Kompilera SASS och/eller LESS till CSS
  • Hålla koll på filer och utföra uppgifter när dessa ändras
  • Automatiskt lägga till browser prefix till CSS
  • Ladda om webbläsaren när en fil ändras
  • Mycket, mycket annat

Installera Grunt

Systemkrav

För att köra Grunt behöver du Node.js. Om du inte har Node installerat kan du gå till http://nodejs.org/. Du behöver även öppna ett terminal-fönster för att installera Grunt men oroa dig inte, det är lätt. När du har installerat Node behöver du installera Node Package Manager (NPM). NPM är ett tillägg till Node som gör det lätt att installera Node-program.

Nu kör vi igång.

Installation

Öppna först ett terminalfönster.

Windows:

  1. Tryck på windowstangenten
  2. Skriv cmd
  3. Tryck enter

Mac:

  1. Tryck Command (⌘) + mellanslag
  2. Skriv terminal
  3. Tryck enter

För att installera NPM som vi behöver för att installera Grunt så kör vi ett kommando i terminalen. Skriv npm install och tryck enter.

NPM laddas ner och installeras. Nästa steg är att installera själva Grunt. För att installera Grunt så navigerar till vår projektmapp

cd /sökväg/till/projektets/katalog

och kör sedan följande kommando:

npm install -g grunt-cli

OBS att alla kommandon vi använder alltid skall köras från ditt projekts root-mapp

Färdigt! Du har nu installerat Grunt för ditt projekt. Inte så svårt va? Nu går vi vidare.

Skapa uppgifter åt Grunt

Grunt behöver två filer för att fungera. Den första behöver vi skapa 1 gång. Den kommer sedan att uppdateras automatiskt med alla moduler vi installerar. Filen skall döpas till package.json och ligga i samma katalog som Grunt installerats i, alltså rootmappen i ditt projekt. Filens innehåll skall vara följande:

{
  "name": "ditt-projekts-namn",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.1"
  }
}

Du kan ändra Ditt projekts namn till ditt vad du vill men låt resten vara som det är. Namnet får dock inte innehålla mellanrum eller vissa andra specialtecken.

Den andra filen vi behöver skapa är Gruntfile.js som Grunt använder sig av för att utföra uppgifter. Det är i denna fil som vi talar om för Grunt vad/när/hur den skall göra. Även denna fil skall ligga i projektets rootmapp. När vi skapar vår första uppgift (task) åt Grunt nedan så skapar vi även den filen.

Grunt i sig gör inte mycket. Det vi behöver göra är att installera olika grunt-plugins som utför de uppgifter vi önskar. Nu när vi installerat och konfigurerat Grunt skall vi skapa några uppgifter. Varje uppgift använder sig av en plugin. Vi installerar dessa med ett kommando i terminalen och gör sedan inställningar i Gruntfile.js för den specifika uppgiften.

Det går att ha många olika uppgifter baserade på olika tillfällen och syften. Då då meningen med denna guide är att ge en grundläggande förståelse för Grunt så har vi fokuserat på enkla varianter på några av de vanligaste uppgifterna.

Minifiera Javascript med Grunt

Att minifiera javascript innebär att man tar bort all onödigt innehåll som kommentarer, radmatningar och mellanrum. På detta sätt komprimeras filen och vi minimerar på så vis mängden data som behöver laddas ner vilket leder till en snabbare webbsida. För att åstadkomma detta med Grunt installerar vi pluginen grunt-contrib-uglify med följande kommando i terminalen:

npm install grunt-contrib-uglify --save-dev

Genom att lägga till flaggan --save-dev till vårt kommando sparas pluginen som en ”dependency” och läggs automatiskt till i vår package.json.

Skapa sedan en ny fil och döp till Gruntfile.js. Filens innehåll skall vara följande:

module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        
        // 1. Här konfigurerar vi våra uppgifter
        uglify: {
            build: {
                src: '/sökväg/till/projektets/katalog/js/site.js',
                dest: '/sökväg/till/projektets/katalog/js/site.min.js'
            }
        }
    });

    // 2. Här säger vi åt Grunt att ladda de uppgifter vi tänker köra
    grunt.loadNpmTasks('grunt-contrib-uglify');
    
    // 3. Här talar vi om för grunt vilka uppgifter som skall köras och i vilken ordning
    grunt.registerTask('default', [
        'uglify'
    ]);

};

Varje gång vi installerar en plugin är det tre saker vi behöver göra i Gruntfile.js.

  1. Konfigurera vår uppgift
  2. Säga åt grunt att ladda vår plugin
  3. Säga åt grunt att köra vår uppgift

I exemplet ovan säger vi åt Grunt att leta efter filen site.js i katalogen /sökväg/till/projektets/katalog/js/, minifiera innehållet och spara resultatet som site.min.js i samma katalog. Kopiera koden ovan till din egen fil, spara filen och skriv sedan Grunt i terminalen. Du borde nu ha fått en minifierad version av din fil redo att användas live.

Notera att det går att använda *.js om man skulle vilja minifiera alla filer i en katalog

Konkatenera Javascript med Grunt

Att konkatenera (slå ihop) våra Javasciptfiler är bra när vi skall publicera vårt projekt eftersom det minimerar antalet HTTP-requests som krävs för att vår hemsida skall laddas. För att åstadkomma detta med grunt installerar vi Grunt-pluginen grunt-contrib-concat med följande kommando:

npm install grunt-contrib-concat --save-dev

Öppna sedan Gruntfile.js. och gör följande ändringar

module.exports = function(grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        // 1. Här konfigurerar vi våra uppgifter
        uglify: { 
            build: {
                src: '/sökväg/till/projektets/katalog/js/site.js',
                dest: '/sökväg/till/projektets/katalog/js/site.min.js'
            }
        },

        concat: {   
            dist: {
                src: '/sökväg/till/projektets/katalog/js/*.min.js',
                dest: '/sökväg/till/projektets/katalog/js/production.js'
            }
        }
    });

    // 2. Här säger vi åt Grunt att ladda de uppgifter vi tänker köra
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-concat');
    
    // 3. Här talar vi om för grunt vilka uppgifter som skall köras och i vilken ordning
    grunt.registerTask('default', [
        'uglify',
        'concat'
    ]);

};

OBS Notera kommatecknet mellan våra två konfigurationer

Vi har nu sagt åt Grunt att slå ihop alla .js-filer i vår katalog och spara dom som production.js.

Optimera bilder med Grunt

Att optimera bilder betyder kortfattat att komprimera dessa så att deras filstorlek blir mindre utan att de tappar kvalité. Man bör alltid optimera bilder som man använder i skarpa projekt.

Installera Grunt-pluggen grunt-contrib-imagemin:

npm install grunt-contrib-imagemin --save-dev

Uppdatera Gruntfile.js på samma sätt som tidigare och lägg till följande konfiguration:

imagemin: {
    dynamic: {
        files: [{
            expand: true,
            cwd: '/sökväg/till/projektets/katalog/img/',
            src: ['**/*.{png,jpg,gif}'],
            dest: '/sökväg/till/projektets/katalog/img/'
        }]
    }
}

Kompilera LESS till CSS med Grunt

LESS är ett objektorienterat sätt att skriva CSS vilket gör koden mer lätthanterlig. Om du hellre vill använda SASS är processen ungefär den samma.

Installera Grunt-pluggen grunt-contrib-less:

npm install grunt-contrib-less --save-dev

Lägg till följande konfiguration:

less: {
    development: {
            options: {
                compress: false
            },
        files: {
            '/sökväg/till/projektets/katalog/css/style.css': // Mål
            '/sökväg/till/projektets/katalog/css/style.less' // Källa
        }
    }
}

Minifiera CSS med Grunt

Installera Grunt-pluggen grunt-contrib-cssmin:

npm install grunt-contrib-cssmin --save-dev

Konfiguration:

cssmin: {
	minify: {
    	src: '/sökväg/till/projektets/katalog/css/style.css',
    	dest: '/sökväg/till/projektets/katalog/css/style.min.css'
	}
}  

Automatisera automatiseringen

Visst vore det skönt om vi slapp öppna terminalen och skriva Grunt varje gång vi uppdaterat någon fil. Inga problem. Med grunt-contrib-watch kan vi övervaka förändringar i våra filer och automatiskt köra vissa uppgifter. I vårt exempel nedan lyssnar Grunt efter förändringar i alla CSS- och Javascript-filer och kör relevanta uppgifter varje gång en förändring gjorts.

En skön grej med watch-pluginen är att den även kan ladda om vår webbläsare varje gång vi sparar en fil. På så viss slipper vi manuellt klicka reload när vi vill se hur vår ändring ser ut.

Installation:

npm install grunt-contrib-watch --save-dev

Konfiguration:

watch: {
	options: {
		livereload: true
	},
    js: {
        files: ['*.js'],
        tasks: ['uglify','concat'],
    },
    css: {
        files: ['*.less'],
        tasks: ['less','cssmin'],
	}
}

Kompilera endast ändrade filer

Tillagd 2014-12-01

Ett problem med watch-pluginen när den körs med konfigurationen ovan är att alla filer kompileras varje gång en fil ändras. Genom att använda grunt-newer kan vi optimera vår process och se till att endast den fil som ändrats kompileras. Detta kan vara guld värt i större projekt där många filer behöver kompileras. Givetvis hade det gått att sätta upp enskilda tasks för varje fil men det hade blivit rätt tradigt.

Installation:

npm install grunt-newer --save-dev

Konfiguration:

Ingen alls egentligen. Sätt bara newer: framför den task som skall du vill applicera detta på, typ:

watch: {
    css: {
        files: ['*.less'],
        tasks: ['newer:less',':newer:cssmin'],
	}
}

Fler möjligheter till konfiguration

Alla plugins vi har använt har fler inställningar än vad vi utnyttjat. Denna guides syfte är endast att ge en grundläggande förståelse för hur Grunt fungerar. För ytterligare information kan du besöka respektive plugins Githubsida genom att klicka på dess namn ovan.

Kan Grunt göra fler saker?

Givetvis kan Grunt göra mycket mer än vad vi gått igenom här. Det finns som sagt mängder med plugins för alla tänkbara uppgifter.

Alternativ till Grunt

Det finns flera andra applikationer som helt eller delvis gör samma arbete som Grunt. Några värda att kolla in är Broccoli och Gulp.

Sammanfattning

I denna artikel har vi lärt oss att installera Grunt för att automatisera CSS- och Javascript-komprimering, optimering av bilder, kompilering av LESS/SASS samt hur vi kan göra detta automatiskt varje gång vi ändrar en fil. Vi har gått igenom hur man laddar ner och konfigurerar grunt-plugins och vi har skapat en mall att använda i framtida projekt. Vår fullständiga Gruntfil kan du ladda ner här.

Frågor och feedback tas tacksamt emot i kommentarsfälten nedan.

Mer om grunt

Grunts officiella webplats: http://gruntjs.com/
Grunt på Github: https://github.com/gruntjs/grunt
Guide till Compass/Sass och Grunt på 80 Ridge Street: http://ridgestreet.se/blogg/snabba-upp-din-webb-med-compass-och-grunt


  • Bra artikel, skulle nog inte klara mig utan Grunt/Gulp nu när jag kört med det i ett antal veckor nu.. 🙂

    • Tack! Ja, riktigt smidigt. Jag har fått respons från flera utvecklare som föredrar Gulp. Kanske kommer det en artikel som förklarar Gulp och beskriver skillnaderna mellan dem.

      • Ja verkligen, det hade varit perfekt! Roligt med en blogg på svenska, kommer definitivt att följas! 🙂

  • Daniel Andersson

    Låt säga att jag har en katalog vid namn ”daniel”. När jag kör installationen av ”npm” via kommandotolken/terminalen så hamnar filerna inte i roten utan i en katalog och underkatalog vid namn ”node_modules” respektive ”npm”, det vill säga. ”daniel/node_modules/npm/”.- Ska filerna ligga där eller ska de flyttas till roten och katalogen ”daniel”?

    • Dom
      skall ligga där dom hamnar och inte flyttas. Om du kör install i
      mappen ‘daniel’ skall det skapas en mapp där som heter node_modules som i
      sin tur innehåller olika mappar för de plugins du installerar. Allt är i
      sin ordning.