Meet Grunt lo strumento di costruzione per JavaScript

Se stai lavorando su un progetto di grandi dimensioni, avrai senza dubbio uno script di build o una serie di script di attività per aiutare con alcune delle parti ripetitive del processo. È possibile utilizzare Ant o Rake, a seconda della lingua in cui è scritto il progetto.

Ma cosa usi se il progetto è principalmente JavaScript? Questo è il problema che Ben Alman ha deciso di risolvere quando ha creato Grunt.


Cos'è Grunt, comunque?

Che cosa è esattamente Grunt? Bene, il README su Github dice

Grunt è uno strumento di compilazione della riga di comando basato su attività per progetti JavaScript.

Ecco l'idea: quando lavori su un progetto JavaScript, ci sono un sacco di cose che vorresti fare regolarmente. Come cosa, chiedi? Bene, come concatenare i file dati, eseguire JSHint sul proprio codice, eseguire test o minimizzare gli script. Se stai incollando il tuo JavaScript su JSHint online, probabilmente ti rendi conto che esiste un modo migliore per farlo; anche se stai usando gatto per concatenare file o un minificatore della riga di comando, sarebbe bello avere un unico insieme unificato di comandi per tutte quelle attività extra, che hanno funzionato per ogni singolo progetto JavaScript, giusto?

Questo è ciò che Grunt intende essere. Ha un sacco di attività integrate che ti porteranno molto lontano, con la possibilità di creare i tuoi plugin e script che estendono le funzionalità di base.

Per maggiori informazioni su Grunt Intro, guarda il post di Ben sul suo blog personale e sul blog di Bocoup.


Come installo Grunt?

Grunt è costruito su Node.js ed è disponibile come pacchetto tramite il gestore di pacchetti Node (npm). Dovrai installarlo globalmente, quindi usa questo comando:

npm install -g grunt

Noterai che installa alcune dipendenze; ci sono altri pacchetti npm che Grunt usa. Una volta fatto, sei pronto per partire!


Come faccio a usare Grunt?

Come sai, Grunt è uno strumento da riga di comando; pertanto, presumo che tu abbia una finestra di terminale aperta per il resto di questo tutorial.

Iniziamo creando una directory di progetto di esempio; in realtà non stiamo costruendo un progetto qui, ma vedremo come funziona Grunt in questa directory. Una volta che sei all'interno di quella directory, esegui il grugnito comando (secondo la documentazione, se sei su Windows, potresti dover eseguire grunt.cmd). Probabilmente vedrai qualcosa di simile a questo:

 Impossibile trovare il file di configurazione "grunt.js". Hai bisogno di aiuto? 

Prima che tu possa davvero sfruttare al meglio il Grunt, avrai bisogno di un grunt.js file nella directory del progetto. Per fortuna, Grunt può auto-generare a grunt.js file - e qualche altro materiale scheletro del progetto - con il dentro compito, che può essere eseguito senza a grunt.js file in atto. Ma grunt init non è ancora sufficiente per avviare il tuo progetto, come vedrai se lo esegui. Devi scegliere un tipo di progetto da generare. In esecuzione grunt init ti fornirà un elenco di tipi di progetti tra cui scegliere:

  • jquery: Un plugin jQuery
  • nodo: Un modulo Node
  • commonjs: Un modulo CommonJS
  • gruntplugin: Un plugin Grunt
  • gruntfile: A Gruntfile (grunt.js)

Se il tuo progetto non corrisponde realmente a nessuno dei primi quattro tipi di progetto, puoi utilizzare quello finale: gruntfile: crea solo una base grunt.js che puoi compilare. Quindi, proviamo con il modello di plugin jQuery. Correre grunt init: jquery nel tuo terminale.

Noterai un sacco di risultati iniziali. Se prendi il tempo di leggere le note del modello, vedrai che dovremo inserire alcuni valori, come il nome del progetto e il titolo del progetto. Infatti, dopo quella nota, vedrai qualcosa di simile a questo:

Per favore rispondi al seguente: [?] Nome del progetto (jquery.demo)

Ogni volta che si inizializza un progetto, Grunt ti farà una serie di domande, quindi può inserire alcune opzioni. Quel valore tra parentesi? Questo è il suggerimento predefinito, in base al tipo di progetto e al nome della directory del progetto. Se vuoi cambiarlo, scrivi il nome del tuo progetto alla fine della riga e premi "invio"; altrimenti, basta premere 'invio' per usare il nome predefinito.

Continuate e riempite il resto dei campi. Per un progetto di plugin jQuery, ecco cos'altro devi dargli:

  • Titolo del progetto
  • Descrizione
  • Versione
  • Repository git del progetto
  • Homepage del progetto
  • Tracker dei problemi del progetto
  • licenze
  • Nome dell'autore
  • Email dell'autore
  • Url autore
  • Versione jQuery richiesta

Molti di questi hanno valori predefiniti; se si desidera utilizzare il valore predefinito, basta premere Invio per quella linea; per lasciare il campo vuoto, puoi semplicemente digitare "none". Una volta esaminate tutte le opzioni, vedrai che Grunt sta creando alcuni file di progetto di base. Tipo cosa? Come questo:

LICENSE-GPL LICENSE-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

Come puoi vedere, questo ci dà un buon inizio: non solo abbiamo il nostro file plugin (src / jquery.demo.js), abbiamo anche test Qunit (test / jquery.demo_test.js). E questi non sono neanche file vuoti. Hanno alcuni contenuti iniziali, con un plugin jQuery così super-base e test unitari. Vai avanti e controlla il contenuto di questi file, vedrai cosa intendo.

Grunt fa più che impostare il progetto per te.

Certo, Grunt fa molto di più che impostare il progetto per te. In particolare, il nostro progetto ha ora grunt.js: un file di configurazione specifico del progetto; a causa delle opzioni impostate, siamo ora in grado di utilizzare le altre attività integrate di Grunt. Presto lo apriremo e faremo alcune regolazioni, ma per ora eseguiamo alcuni compiti.

Se corri grugnito senza opzioni ora, eseguiremo l'attività di default, se ne è stata impostata una. Nel caso di un progetto di plugin jQuery, è equivalente all'esecuzione di questi quattro comandi:

  • peluria: controlla il tuo JavaScript contro JSHint
  • qunit grunt: esegue i test Qunit
  • grugnito concat: concatena i file di progetto e inserisce il nuovo file in a dist cartella
  • grunt min: minimizza il file concat mettere fuori.

Dovrei notare qualcosa sui test di Qunit qui: i test di Qunit sono pensati per funzionare nel browser di default; semplicemente aperto test / jquery.demo.html (o il tuo equivalente) nel browser. comunque, il qunit grunt test vuole eseguirli sul terminale, il che significa che è necessario avere PhantomJS installato. Non è difficile: basta andare su phantomjs.org e scaricare e installare l'ultima versione. Se Grunt riesce a trovarlo sul tuo percorso, sarà in grado di eseguire i test di Qunit dal terminale.

Quindi, correndo grugnito dovrebbe dare un output simile a questo:

Come puoi vedere, ognuna delle nostre quattro attività è stata eseguita. Se qualcuno dovesse fallire, il resto delle attività verrebbe annullato (a meno che non chiami Grunt con il --vigore bandiera).


Come personalizzo le mie attività?

Abbiamo già ottenuto grandi funzionalità da Grunt, utilizzandolo così come viene. Tuttavia, apriamolo grunt.js file e fare qualche configurazione.

Dentro grunt.js, vedrai che tutta la configurazione viene eseguita passando un oggetto letterale a grunt.initConfig (). Diamo un'occhiata ad alcune delle proprietà del nostro oggetto config.

pkg

Questa proprietà punta al package.json file che Grunt ha creato nella nostra directory di progetto. Avere un package.json il file fa parte delle specifiche dei pacchetti CommonJS; è un luogo unico in cui è possibile memorizzare la maggior parte dei metadati relativi al progetto (nome, versione, homepage, link del repository ... molti dei valori impostati durante l'inizializzazione del progetto). Tuttavia, questo pkg la proprietà fa più che puntare al file del pacchetto: nota la sintassi: ''. Questa è una delle direttive incorporate di Grunt: carica effettivamente il file JSON, quindi Grunt (o tu) può accedere a tutte le proprietà nel file package.json dal pkg proprietà.

meta

Il meta la proprietà è un oggetto con una sola proprietà: un banner. Questo banner è il commento che si trova nella parte superiore dei file di progetto concatenati o miniati. Come puoi vedere, è una stringa con alcuni tag di modello (<%= %>); nella maggior parte dei casi, i tag circondano una chiamata a una proprietà sul pkg proprietà, come pkg.title. Tuttavia, è anche possibile eseguire funzioni all'interno di tali tag: l'uso di grunt.template.today () e _.pluck () ce lo mostra.

concat / min / qunit / garza / orologio

Ho raggruppato le prossime cinque proprietà insieme perché sono molto simili. Tutti impostano le opzioni per attività specifiche, le attività a cui prendono il nome. Quando si configurano queste attività, è importante notare che Grunt distingue tra due tipi di attività: attività regolari e multitasks. Fondamentalmente, la differenza è che le attività regolari hanno solo un singolo set di opzioni di configurazione, mentre i multitasks possono avere più set di istruzioni (chiamati obiettivi). Dei cinque compiti che ho elencato nell'intestazione di questa sezione, l'unico che non è un multitasking è orologio.

Si noti che nel nostro oggetto di configurazione, il qunit e garza le proprietà sono entrambi oggetti con il File proprietà. File è un singolo obiettivo per questa attività. In entrambi i casi, sono una serie di file da utilizzare durante l'esecuzione di questa attività. Diciamo che voglio essere in grado di filtrare solo i file in src sub-directory. Potrei aggiungere un altro obiettivo in modo che il garza proprietà sarebbe simile a questa:

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

Ora, per filtrare solo i file in src, io corro peluria: src: Passo il nome dell'obiettivo dopo due punti. Se corro solo peluria, entrambi i bersagli saranno eseguiti.

Nel caso del concat e min compiti, gli obiettivi sono più complicati: sono oggetti con sorgente (src) e destinazione (dest) proprietà. Ovviamente, questo indica a Grunt dove trovare i file e dove metterli quando viene elaborato, rispettivamente. Se aggiungi altri file al tuo progetto, dovrai aggiungerli nel posto giusto per assicurarti che siano concatenati e miniati correttamente. Quindi, se ho aggiunto un src / utils.js file da cui dipendeva il mio plugin jQuery, cambierei concat.dist.src a questo:

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

Osservando alcuni di questi compiti più da vicino, noterete alcune altre direttive: la più importante è probabilmente la direttiva. Ciò consente di accedere alle proprietà di altre attività per il riutilizzo. Noterai che la configurazione per il orologio compito usa , in modo che funzioni sullo stesso elenco di file che abbiamo dato al garza compito. Puoi saperne di più sulle altre direttive nei documenti di Grunt.

Parlando del compito dell'orologio, che cosa fa esattamente? Molto semplice: esegue i compiti in compiti proprietà quando viene modificato un file in quell'elenco di file. Di default, il garza e qunit le attività vengono eseguite.

jshint

Questa proprietà semplicemente configura quali "parti danneggiate" JSHint cerca nel tuo JavaScript. L'elenco completo delle opzioni è disponibile nelle pagine delle opzioni del sito Web JSHint.


In fondo alla nostra grunt.js file, vedrai questa riga:

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

Questo è ciò che crea il nostro compito predefinito; sai, quello che corre quando corriamo giusto grugnito. In realtà sta creando un'attività di alias e puoi creare tutte le attività di alias che desideri:

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

Supponendo che tu abbia creato src obiettivi per ciascuna di queste attività, ora puoi chiamare grunt src e fai esattamente quello che vuoi.


Come faccio a utilizzare attività di terze parti?

Mentre i compiti che accompagnano Grunt ti porteranno molto lontano, probabilmente puoi pensare ad altre cose che ti piacerebbe essere in grado di automatizzare. Non preoccuparti: Grunt viene fornito con un'API che consente a chiunque di creare attività e plugin Grunt. Mentre non creeremo alcuna attività Grunt in questo tutorial, se sei interessato a farlo, dovresti iniziare con il modello di plugin Grunt (esegui grunt init: gruntplugin), quindi leggere i documenti dell'API. Una volta che hai scritto il tuo compito, puoi caricarlo in un progetto aggiungendo questa linea all'interno del tuo progetto grunt.js file:

grunt.loadTasks (PATH_TO_TASKS_FOLDER);

Si noti che il parametro non è il percorso del file di attività stesso, è il percorso della cartella in cui si trova il file di attività.

Tuttavia, stanno iniziando a comparire altri plugin Grunt e alcuni sono disponibili su NPM. Dopo averli installati tramite installazione di npm, li carichi nel tuo progetto con questa linea:

grunt.loadNpmTasks (PLUGIN_NAME);

Ovviamente, vorrai controllare la documentazione del plugin per vedere cosa dovresti aggiungere al tuo oggetto di configurazione.

Quali plugin di Grunt sono disponibili? Bene, dal momento che Grunt è così nuovo (meno di un mese mentre scrivo questo), non ce ne sono ancora molti. Ne ho trovati due:

  • grugnito-css: per linting e minifying CSS
  • grugnito-jasmine-task: per eseguire le specifiche di Jasmine

Se ne hai trovati altri, mi piacerebbe sapere di loro; inseriscili nei commenti!


Conclusione

Mentre Grunt è un progetto molto nuovo, è difficilmente incompleto; come abbiamo visto, viene fornito con praticamente tutto ciò che serve per usarlo su un grande progetto e può essere esteso quanto vuoi.

Spero che Grunt diventerà uno standard della comunità e che vedremo molte attività, plug-in e modelli di inizializzazione che si apriranno nel prossimo futuro. Come ti senti al riguardo?