Интерполированный массив в шаблоне Grunt интерпретируется как строка

Предыдущий заголовок: «Почему concat-задача Grunt не использует значения динамической конфигурации?»

Я пытаюсь динамически настроить файлы, которые объединены Grunt, и при этом я столкнулся с проблемой, когда плагин grunt-contrib-concat, похоже, не получает динамически устанавливаемые значения. Сначала я думал, что делаю что-то не так, но после создания собственной задачи и использования тех же динамических значений все вышло так, как задумано. Таким образом, остается вопрос, почему задача concat не получает и не использует одни и те же значения?

Файл grunt, который воспроизводит это поведение, показан ниже (суть: fatso83/73875acd1fa3662ef360).

// Grunt file that shows how dynamic config (and option!) values
// are not used in the grunt-contrib-concat task. Run using 'grunt'
module.exports = function(grunt){

    grunt.initConfig({

        concat : {
            foo : {
                nonull : true,
                src: '<%= grunt.config.get("myfiles") %>',
                dest : 'outfile.txt'
            }
        },

        myTask : {
            bar : '<%= grunt.config.get("myfiles") %>'
        }
    });

    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-concat');

    grunt.registerMultiTask('myTask', function() {
        grunt.log.writeln('myTask:' + this.target + ' data=' + this.data);
    });

    grunt.registerTask('default', ['myTask','concat']);

    grunt.config.set('myfiles',['file1.txt', 'file2.txt'])
}

РЕДАКТИРОВАТЬ: новая зацепка: после буквально нескольких часов бездействия я наткнулся на это предложение на Домашняя страница Grunt:

nonnull Если установлено значение true, операция будет включать несовпадающие шаблоны. В сочетании с флагом grunt --verbose этот параметр может помочь отладить проблемы с путями к файлам.

Добавив это в конфигурацию (отредактированную выше, чтобы отразить это), я получил это сообщение об ошибке, которое, по крайней мере, показывает, что что-то делает с динамическими значениями:

Running "concat:foo" (concat) task
>> Source file "file1.txt,file2.txt" not found.
Warning: Unable to write "outfile.txt/file1.txt,file2.txt" file 
(Error code: ENOTDIR). Use --force to continue.

После еще одной отладки в другой задаче, myTask, я обнаружил, что данные, отправленные в задачу как this.data, являются строковым значением, а не массивом. Это, возможно, не очень удивительно, учитывая, что мы делаем интерполяцию строк, но это не согласуется с другими функциями интерполяции. Например, <%= otherTask.fooTarget.src %> получит свойство src другой задачи в виде значения массива.

Теперь вопрос в том, как я могу избежать передачи интерполированного значения в виде массива, а не строки, в задачу concat?


person oligofren    schedule 26.06.2014    source источник
comment
'<%= grunt.config.get("myfiles") %>' это строка, а не массив   -  person jantimon    schedule 27.06.2014
comment
Я тоже это только что узнал!   -  person oligofren    schedule 27.06.2014
comment
@jantimon Но grunt выполняет интерполяцию строк для значений массива, таких как ‹%= otherTask.fooTarget.src %›, поэтому в идеале он должен был работать так же.   -  person oligofren    schedule 27.06.2014


Ответы (1)


Обновлено после прочтения исходного кода Grunt.

После того, как я узнал, что проблема в том, что наш массив интерпретировался как строка, я быстро нашел связанный вопрос с решением, которое показалось многообещающим. Просто заключив интерполированную строку массива в фигурные скобки, Grunt смог найти файлы!

К сожалению, шаблон подстановки, который мы эффективно создаем, не сохраняет указанный порядок файлов. В соответствующем вопросе выше я опубликовал подробное объяснение того, что происходит и как вы можете обойти это в общем случае. .

В моем конкретном случае, когда я ссылаюсь на поле в объекте конфигурации, на самом деле нет необходимости в вызове функции для его извлечения, поскольку оно доступно непосредственно в собственной области действия шаблонов! Поэтому вместо вызова grunt.config.get('myfiles') я могу просто выполнить <%= myfiles %>.

Для приведенного выше примера:

grunt.initConfig({

    concat : {
        foo : {
            nonull : true,
            src: '<%= myfiles %>',
            dest : 'outfile.txt'
        }
    },

    myTask : {
        bar : '<%= myfiles %>'
    }
});
person oligofren    schedule 26.06.2014