2013-04-12 1 views
9

Dire che ho una variabile nella mia configurazione di grunt con un array come valore. Un esempio reale è grunt.regarde.changed dal plug-in grunt-regarde, che elenca tutti i file che sono stati modificati.Grunt - risoluzione di modelli non stringa (ad es. Array)

voglio risolvere tale matrice utilizzando un modello, in modo da poter (in questo caso) copiare i file modificati:

copy: { 
    staticWeb: { 
     src: '<%= grunt.regarde.changed %>', 
     dest: 'someDir' 
    }, 

Cosa src ottiene in questo caso è un è una virgola stringa delimitata invece di un array. Il file processor di Grunt non analizza la stringa e quindi non riesce a trovare il file src.

Non riesco a rimuovere le virgolette singole attorno al modello perché è javascript non valido.

Quindi, come passare l'array grunt.regarde.changed alla variabile src?

+0

In futuro, spero che i modelli grunt gestiscano nativamente valori non stringa. Per ora però, [la risposta di oligofren] (http://stackoverflow.com/a/24447293/1298086) è la nostra migliore opzione. Dovrebbe essere la risposta accettata. – matty

risposta

10

Il problema è molto facile da risolvere una volta che sai come, solo poche righe di codice, ma mi ci è voluto un po 'per trovare tutte le informazioni rilevanti dal codice sorgente di Grunt per capire cosa fare, così nudo con me mentre io vi porterà attraverso il fondo ...


il modo generale di entrare in possesso di una proprietà sull'oggetto di configurazione è semplice:

<%= some.property %> // fetches grunt.config.get('some.property') 

Funziona per tutte le proprietà che sono state impostate sull'oggetto grunt.config, che (ovviamente) includono la configurazione che viene passata a grunt.initConfig(). Questo è il motivo per cui è possibile fare riferimento ad altre variabili di attività direttamente, come ad esempio in <%= concat.typescriptfiles.dest %>, poiché tutte le proprietà nell'oggetto di configurazione sono nello stesso ambito del modello.

Tecnicamente questa espansione avviene quando il (LoDash) modello viene trasmesso sia con l'oggetto options (se definito) o grunt.config oggetto al processore template (LoDash' funzione template).

Quindi questo funziona per i valori che sono stati impostati nella configurazione stessa o utilizzando valori assegnati dinamicamente tramite grunt.config.set(). Vedi lo API docs per maggiori informazioni.

Ciò che non funziona allo stesso modo è l'accesso a valori che non sono disponibili sull'oggetto di configurazione. Sembra che per qualche motivo non ne sono del tutto sicuro, tutti gli altri valori finiscono sempre come stringhe. Ciò accade indipendentemente dal fatto che tu acceda direttamente o tramite le chiamate di metodo. Ad esempio, tentare di accedere a un array sulla configurazione tramite grunt.config.get() ottiene una stringa.

Una soluzione per il problema che conserva ordine dei file

La risposta accettata funziona in un modo, ma a causa della sintassi globbing sarà analizzato dal modulo glob()che non conserva ordine dei file. Questo era un no-no per la mia build.

Una soluzione alternativa, nel caso in cui l'array che si desidera utilizzare non sia disponibile sull'oggetto di configurazione, è quello di aggiungerlo alla configurazione tramite un'attività intermedia. Qualcosa come il seguente dovrebbe funzionare:

// This variable will be used twice to demonstrate the difference 
// between directly setting an attribute on the grunt object 
// and using the setter method on the grunt.config object 
var myFiles = ['c/file1.txt', 'a/file2.txt', 'b/file3.txt'] 
module.exports = function(grunt){ 

    grunt.initConfig({ 

     debug : { 
      using_attribute: { 
       src : '<%= grunt.value_as_attribute %>' // will be a string 
      }, 
      using_task: { 
       src : '<%= value_by_setter %>' // will be an array 
      }, 
      no_task_direct_setter: { 
       src : '<%= value_by_setter_early %>' // will be an array 
      } 
     }   
    }); 

    grunt.registerTask('myValSetter', function() { 
     grunt.config.set('value_by_setter', myFiles); 
    }); 

    // a task that will report information on our set values 
    grunt.registerMultiTask('debug', function(){ 
     grunt.log.writeln('data.src: ', this.data.src); 
     grunt.log.writeln('type: ', Array.isArray(this.data.src)? "Array" : typeof this.data.src); 
    }); 

    grunt.value_as_attribute = myFiles; 

    grunt.config.set('value_by_setter_early', myFiles); 

    grunt.registerTask('default',['myValSetter', 'debug']); 
} 

Questa volontà di uscita

$ grunt 
Running "myValSetter" task 

Running "debug:using_attribute" (debug) task 
data.src: c/file1.txt,a/file2.txt,b/file3.txt 
type: string 

Running "debug:using_task" (debug) task 
data.src: [ 'c/file1.txt', 'a/file2.txt', 'b/file3.txt' ] 
type: Array 

Running "debug:no_task_direct_setter" (debug) task 
data.src: [ 'c/file1.txt', 'a/file2.txt', 'b/file3.txt' ] 
type: Array 

Done, without errors. 

Questo esempio è solo lo scopo di illustrare il concetto, ma si dovrebbe essere in grado di personalizzare facilmente all'istanza :)

+0

Questo è geniale Grazie Un cambiamento che ho fatto per la mia implementazione sta usando 'grunt.config.set' per creare un singolo grugnito" globale "chiamato' grunt.values' per contenere tutti i valori non stringa utilizzati più volte nella configurazione, ad esempio 'grunt.config.set ('valori', {a: [1,2], b: [2,3], ecc. [3,4]}). Inoltre, non vedo la necessità di creare altre proprietà 'grunt' come mostrato nel tuo esempio come' grunt.somevalue'. "Registrazione" il non -string valori direttamente con 'grunt.config.set' sembra essere sufficiente – matty

+0

Bene che qualcuno ne abbia fatto uso - Ricordo di aver usato un'intera notte di hacking, inclusa la lettura di tutto il codice sorgente di Grunt per capire come Stavo succedendo sotto il cofano! Hai ragione riguardo alla cosa 'grunt.somevalue'. L'ho sostituito con una variabile normale nella risposta ora. – oligofren

+0

Oh, ora ricordo. Lo uso per mostrare la differenza tra la lettura direttamente imposta i valori degli attributi e l'uso di grunt.config.set. Devo ripristinare la mia modifica, altrimenti i commenti non hanno senso. // src: '<% = grunt.somevalue%>' // sarà una stringa – oligofren

-2

Hai provato:

copy: { 
    staticWeb: { 
    src: '<%= grunt.regarde.changed.split(",") %>', 
    dest: 'someDir' 
    } 
} 
+0

Hai provato questo? Non funziona per me con Grunt v0.4.5, che attualmente è l'ultima versione stabile. –

8

Ho avuto esattamente lo stesso problema come la tua, risolverlo circonda il vostro modello con parentesi graffe.

Così qui è il tuo codice, modificato

copy: { 
    staticWeb: { 
    src: '{<%= grunt.regarde.changed %>}', // added curly brackets 
    dest: 'someDir' 
    } 
} 

E 'in uscita il src come {source1,source2,source3}, che è lo stesso che utilizzare un array. (Vedi Globbing Patterns in Grunt Documentation)

+1

Eccellente! Ero alle prese con questo per parecchie ore ... http://stackoverflow.com/questions/24440863/interpolated-array-in-grunt-template-is-interpreted-as-a-string/24441290#24441290 – oligofren

+1

One il problema è che per qualche motivo non conserva l'ordine dei file ... :-( – oligofren