Meet Grunt The Build Tool voor JavaScript

Als u aan een groot project werkt, zult u ongetwijfeld een build-script of een aantal taakscripts hebben om te helpen met enkele van de repetitieve delen van het proces. U kunt Ant of Rake gebruiken, afhankelijk van de taal waarin het project is geschreven.

Maar wat gebruik je als het project voornamelijk JavaScript is? Dat is het probleem dat Ben Alman wilde oplossen toen hij Grunt creëerde.


Wat is Grunt, hoe dan ook?

Wat is Grunt precies? Nou, de README op Github zegt

Grunt is een taakgebaseerde tool voor het bouwen van opdrachtregels voor JavaScript-projecten.

Dit is het idee: wanneer u aan een JavaScript-project werkt, zijn er een heleboel dingen die u regelmatig wilt doen. Wat vind je ervan, vraag je? Wel, zoals het samenvoegen van gegeven bestanden, het uitvoeren van JSHint op uw code, het uitvoeren van tests of het verkleinen van uw scripts. Als je je JavaScript in JSHint online plakt, realiseer je je waarschijnlijk dat er een betere manier is om het te doen; zelfs als je gebruikt kat om bestanden samen te voegen of een commandoregel minifier, zou het leuk zijn om een ​​enkele, uniforme reeks commando's te hebben voor al die extra taken, die voor elk JavaScript-project werkten, juist?

Dat is wat Grunt wil zijn. Het heeft een aantal ingebouwde taken die je aardig ver brengen, met de mogelijkheid om je eigen plug-ins en scripts te bouwen die de basisfunctionaliteit uitbreiden.

Zie Ben's bericht op zijn persoonlijke blog en de Bocoup-blog voor meer gruntintro-goedheid.


Hoe installeer ik grunt?

Grunt is gebouwd op Node.js en is beschikbaar als pakket via de Node-pakketbeheerder (npm). U wilt het globaal installeren, dus gebruik deze opdracht:

npm install -g grunt

U zult merken dat het nogal wat afhankelijkheden installeert; er zijn andere npm-pakketten die door Grunt worden gebruikt. Als dat klaar is, ben je klaar om te gaan!


Hoe gebruik ik Grunt?

Zoals je weet, is Grunt een opdrachtregelprogramma; daarom neem ik aan dat je een terminalvenster open hebt voor de rest van deze tutorial.

Laten we beginnen met het maken van een voorbeeldprojectmap; we gaan hier niet echt een project bouwen, maar we zullen zien hoe Grunt in deze map werkt. Zodra u zich in die map bevindt, voert u de knorren commando (volgens de documentatie, als je Windows gebruikt, moet je misschien uitvoeren grunt.cmd). U ziet waarschijnlijk zoiets als dit:

 Kan het configuratiebestand 'grunt.js' niet vinden. Heb je hulp nodig? 

Voordat je Grunt echt optimaal kunt gebruiken, heb je een grunt.js bestand in de projectdirectory. Gelukkig kan Grunt automatisch een genereren grunt.js bestand - en een ander project skeletmateriaal - met de in het taak, die kan draaien zonder een grunt.js bestand op zijn plaats. Maar grunt init nog steeds niet genoeg om je project te starten, zoals je zult zien als je het uitvoert. U moet een type project kiezen om te genereren. hardlopen grunt init geeft je een lijst met projecttypen om uit te kiezen:

  • jQuery: Een jQuery-plug-in
  • knooppunt: Een knooppuntmodule
  • commonjs: Een CommonJS-module
  • gruntplugin: Een grunt-plugin
  • gruntfile: Een gruntbestand (grunt.js)

Als uw project niet echt overeenkomt met een van de eerste vier projecttypen, kunt u de laatste gebruiken: gruntfile: het maakt gewoon een basis grunt.js die je kunt invullen. Laten we dit eens proberen, met de jQuery-plug-insjabloon. Rennen grunt init: jQuery in uw terminal.

Je zult veel beginoutput merken. Als u de tijd neemt om de sjabloonnotities te lezen, ziet u dat we enkele waarden moeten invullen, zoals de projectnaam en projecttitel. In feite, na die opmerking, zie je zoiets als dit:

Beantwoord het volgende: [?] Projectnaam (jquery.demo)

Wanneer je een project initialiseert, zal Grunt je een aantal vragen stellen, zodat het een paar opties kan invullen. Die waarde tussen haakjes? Dat is de standaard suggestie, gebaseerd op het projecttype en de naam van de projectdirectory. Als u dit wilt wijzigen, schrijft u aan het einde van de regel uw eigen projectnaam en drukt u op 'enter'; anders drukt u gewoon op 'enter' om de standaardnaam te gebruiken.

Blijf doorgaan en vul de rest van de velden in. Voor een jQuery-plugin-project, hier is wat je nog meer nodig hebt om het te geven:

  • Project titel
  • Omschrijving
  • Versie
  • Project git repository
  • Project startpagina
  • Projectproblemen tracker
  • licenties
  • Auteur naam
  • E-mail van auteur
  • Author url
  • Vereiste jQuery-versie

Veel van deze hebben standaardwaarden; als u de standaardwaarde wilt gebruiken, drukt u op Enter voor die regel; om het veld leeg te laten, kunt u gewoon "none" typen. Zodra u alle opties hebt doorgenomen, ziet u dat Grunt een aantal elementaire projectbestanden aanmaakt. Zoals? Zoals dit:

LICENSE-GPL LICENTIE-MIT README.md grunt.js libs | - jquery | | - jquery.js | - qunit | - qunit.css | - qunit.js package.json src | - jquery.demo.js test | - jquery.demo.html | - jquery.demo_test. js

Zoals je ziet, geeft dit ons een goede start: niet alleen hebben we ons plugin-bestand (src / jquery.demo.js), hebben we ook Qunit-tests (test / jquery.demo_test.js). En dit zijn ook geen lege bestanden. Ze hebben wat initiële inhoud, met een zo-super-basis jQuery plug-in en unit tests. Ga je gang en bekijk de inhoud van deze bestanden, je zult zien wat ik bedoel.

Grunt doet meer dan het project voor je opzetten.

Natuurlijk doet Grunt meer dan het project voor je opzetten. Met name heeft ons project nu grunt.js: een projectspecifiek configuratiebestand; vanwege de opties die worden ingesteld, kunnen we nu de andere ingebouwde taken van Grunt gebruiken. Binnenkort zullen we het openbreken en een aantal aanpassingen maken, maar laten we nu wat taken uitvoeren.

Als je rent knorren zonder opties nu, zullen we de standaardtaak uitvoeren, als die is ingesteld. In het geval van een jQuery-plug-in-project komt dat overeen met het uitvoeren van deze vier opdrachten:

  • gruis pluis: controleert uw JavaScript tegen JSHint
  • grunt qunit: voert uw Qunit-tests uit
  • gegrom concat: samenvoegen uw projectbestanden samen en plaatst het nieuwe bestand in een dist map
  • gegrom min: verkleint het bestand concat doe uit.

Ik zou hier iets moeten opmerken over de Qunit-tests: Qunit-tests moeten standaard in de browser worden uitgevoerd; net open proeven / jquery.demo.html (of uw equivalent) in de browser. echter, de grunt qunit test wil ze op de terminal uitvoeren, wat betekent dat je PhantomJS moet hebben geïnstalleerd. Het is niet moeilijk: ga gewoon naar phantomjs.org en download en installeer de nieuwste versie. Als Grunt dat op je pad kan vinden, kan het de Qunit-tests vanaf de terminal uitvoeren.

Dus, rennen knorren zou je output moeten geven vergelijkbaar met dit:

Zoals u kunt zien, is elk van onze vier taken uitgevoerd. Als een van hen zou falen, zou de rest van de taken worden geannuleerd (tenzij u Grunt belt met de --dwingen vlag).


Hoe pas ik mijn taken aan??

We hebben al grunt veel geweldige functionaliteit van Grunt en gebruiken het precies zoals het komt. Laten we dat echter openbreken grunt.js bestand en doe wat aan het configureren.

Binnen grunt.js, je zult zien dat alle configuratie gebeurt door een letterlijk object door te geven grunt.initConfig (). Laten we eens kijken naar enkele eigenschappen van ons configuratieobject.

pkg

Deze eigenschap verwijst naar de package.json bestand dat Grunt heeft gemaakt in onze projectdirectory. Een .... hebben package.json bestand is onderdeel van de CommonJS Packages-specificatie; het is een enkele plaats waar de meeste metadata over het project (naam, versie, startpagina, repository-link ... veel van de waarden die u instelt bij het initialiseren van het project) kunnen worden opgeslagen. Dit echter pkg eigenschap doet meer dan verwijzen naar het pakketbestand: let op de syntaxis: ''. Dat is een van de ingebouwde richtlijnen van Grunt: het laadt het JSON-bestand daadwerkelijk, zodat Grunt (of jij) toegang heeft tot alle eigenschappen in het bestand package.json van de pkg eigendom.

meta

De meta eigenschap is een object met slechts één eigenschap: een banner. Deze banner is de opmerking die boven aan samengevoegde of verkleinde projectbestanden staat. Zoals u kunt zien, is het een string met enkele sjabloontags (<%= %>); in de meeste gevallen omringen de tags een aanroep naar een eigenschap op de pkg eigendom, zoals pkg.title. U kunt echter ook functies uitvoeren vanuit die tags: het gebruik van grunt.template.today () en _.plukken() laat ons dat zien.

concat / min / qunit / pluis / kijk maar

Ik heb de volgende vijf eigenschappen samen gegroepeerd omdat ze erg op elkaar lijken. Ze stellen allemaal opties in voor specifieke taken, de taken waaraan ze zijn genoemd. Bij het configureren van deze taken is het belangrijk op te merken dat Grunt onderscheid maakte tussen twee soorten taken: normale taken en multitasks. In wezen is het verschil dat reguliere taken slechts één set configuratie-opties hebben, terwijl multitasks meerdere sets instructies kunnen hebben (genaamd doelen). Van de vijf taken die ik in de kop van deze sectie heb genoemd, is de enige die geen multitasking is kijk maar.

Merk op dat in ons configuratie-object, de qunit en pluis eigenschappen zijn beide objecten met de bestanden eigendom. bestanden is een enkel doel voor deze taak. In beide gevallen zijn het een aantal bestanden die kunnen worden gebruikt bij het uitvoeren van deze taak. Laten we zeggen dat ik alleen de bestanden in de computer wil src sub-directory. Ik zou een ander doel kunnen toevoegen, zodat de pluis eigendom ziet er als volgt uit:

lint: bestanden: ['grunt.js', 'src / ** / *. js', 'test / ** / *. js'], src: ['src / ** / *. js'],

Nu, om alleen de bestanden in te pluizen src, ik ren gruis pluis: src: Ik geef de doelnaam door na een dubbele punt. Als ik alleen ren gruis pluis, beide doelen worden uitgevoerd.

In het geval van de concat en min taken, de doelen zijn ingewikkelder: het zijn objecten met bron (src) en bestemming (dest) eigenschappen. Natuurlijk vertelt dit Grunt waar de bestanden moeten worden opgehaald en waar ze moeten worden geplaatst wanneer het klaar is met verwerken. Als u andere bestanden aan uw project toevoegt, moet u deze op de juiste plaats toevoegen om ervoor te zorgen dat ze correct worden samengevoegd en verkleind. Dus als ik er een toevoeg src / utils.js bestand waarvan mijn jQuery-plug-in afhankelijk was, zou ik veranderen concat.dist.src hieraan:

src: ['',' src / utils.js ','.js> '],

Als u een aantal van deze taken van naderbij bekijkt, zult u enkele andere richtlijnen opmerken: de belangrijkste is waarschijnlijk de richtlijn. Hierdoor kunt u de eigenschappen van andere taken gebruiken voor hergebruik. U zult merken dat de configuratie voor de kijk maar taak gebruikt , zodat het werkt op dezelfde lijst met bestanden die we hebben gegeven aan de pluis taak. U kunt meer leren over de andere richtlijnen in de Grunt-documenten.

Over de kijktaak gesproken, wat doet het precies? Heel simpel: het voert de taken uit in de taken eigenschap wanneer een bestand in die lijst met bestanden is gewijzigd. Standaard is de pluis en qunit taken worden uitgevoerd.

jshint

Deze eigenschap configureert eenvoudig wat "slechte onderdelen" JSHint zoekt in uw JavaScript. De volledige lijst met opties is te vinden op de optiepagina's van de JSHint-website.


Helemaal onderaan onze grunt.js bestand, ziet u deze regel:

grunt.registerTask ('standaard', 'lint qunit concat min');

Dit is wat onze standaardtaak creëert; weet je, degene die loopt als we net lopen knorren. Het maakt eigenlijk een alias-taak en u kunt zoveel aliastaken maken als u wilt:

grunt.registerTask ('src', 'lint: src qunit: src concat: src min: src');

Ervan uitgaande dat je gemaakt src doelen voor elk van die taken, je kunt nu bellen grunt src en precies doen wat je wilt.


Hoe gebruik ik taken van derden?

Hoewel de taken die met Grunt worden geleverd je vrij ver zullen raken, kun je waarschijnlijk andere dingen bedenken die je graag zou willen automatiseren. Geen zorgen: Grunt wordt geleverd met een API waarmee iedereen Grunt-taken en -plug-ins kan maken. Hoewel we in deze zelfstudie geen Grunt-taken zullen maken, zou je, als je hierin geïnteresseerd bent, moeten beginnen met de Grunt-plug-insjabloon (uitvoeren grunt init: gruntplugin) en lees vervolgens de API-documenten door. Nadat u uw taak hebt geschreven, kunt u deze in een project laden door deze regel toe te voegen aan uw project grunt.js het dossier:

grunt.loadTasks (PATH_TO_TASKS_FOLDER);

Merk op dat de parameter niet het pad naar het taakbestand zelf is, maar het pad naar de map waarin het taakbestand zich bevindt.

Er verschijnen echter andere Grunt-plug-ins en sommige zijn beschikbaar op NPM. Nadat je ze hebt geïnstalleerd via npm installeren, je laadt ze in je project met deze regel:

grunt.loadNpmTasks (PLUGIN_NAME);

Natuurlijk wilt u de documentatie van de plug-in controleren om te zien wat u aan uw configuratieobject zou moeten toevoegen.

Welke Grunt-plug-ins zijn beschikbaar? Omdat Grunt zo nieuw is (minder dan een maand oud als ik dit schrijf), zijn er nog niet veel. Ik heb er twee gevonden:

  • grunt-css: voor pluizen en verkleinen CSS
  • grunt-jasmijn-task: voor het uitvoeren van Jasmine-specificaties

Als je anderen hebt gevonden, zou ik het leuk vinden om erover te horen; plaats ze in de reacties!


Conclusie

Terwijl Grunt een heel nieuw project is, is het nauwelijks incompleet; zoals we hebben gezien, het komt met vrijwel alles wat je nodig hebt om het te gebruiken voor een groot project, en kan zo veel worden uitgebreid als je wilt.

Ik hoop dat Grunt een communitystandaard wordt en dat we in de nabije toekomst veel taken, plug-ins en init-sjablonen zullen zien verschijnen. Hoe voel je je erover??