Ниже приведено несколько решений для рассмотрения. Однако сначала давайте разберемся, что делает grunt.file.readYAML()
для анализа вашего _config.yml
файла. По сути, он создает следующий объект:
{
computer: {
parts: [
{
name: 'brand1',
type: 'cpu'
},
{
name: 'brand2',
type: 'gpu'
},
{
name: 'brand3',
type: 'hd'
}
]
}
}
Примечание , как значение parts
представляет собой массив объектов.
Решение 1:
Учитывая, что вы хотите использовать шаблоны grunt (то есть <%= %>
) для получения различных значений name
и type
, рассмотрите возможность настройки задачи concat
в вашем Gruntfile . js следующим образом:
Gruntfile. js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.initConfig({
external: grunt.file.readYAML('_config.yml'),
concat: {
dist: {
options: {
// ...
},
src: [
'htdocs/<%= external.computer.parts[0].type %>/<%= external.computer.parts[0].name %>/*.js',
'htdocs/<%= external.computer.parts[1].type %>/<%= external.computer.parts[1].name %>/*.js',
'htdocs/<%= external.computer.parts[2].type %>/<%= external.computer.parts[2].name %>/*.js'
],
dest: 'htdocs/output.js'
}
}
// ...
});
grunt.registerTask('default', [ 'concat' ]);
};
Примечания:
Значение свойства external
объекта, переданного в метод grunt.initConfig
, по сути является вышеупомянутым объектом, т.е. это результат использования grunt.file.readYAML()
для анализа вашего _config.yml
.
Значение свойства src
цели dist
target (которая связана с задачей concat
), это массив. В каждом элементе этого массива мы используем обозначение <% ... %>
для ссылки на части из вашего файла .yml
.
Обратите внимание, как мы ссылаемся на каждый объект в массиве external.computer.parts
по его индексу, то есть [0]
, [1]
, [2]
'htdocs/<%= external.computer.parts[0].type %>/<%= external.computer.parts[0].name %>/*.js'
^ ^
Решение 2:
Еще один способ удовлетворить ваши требования - вообще не использовать шаблонов grunt, то есть <% ... %>
. Рассмотрим следующее решение:
Gruntfile. js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-concat');
var external = grunt.file.readYAML('_config.yml');
grunt.initConfig({
concat: {
dist: {
options: {
// ...
},
src: external.computer.parts.map(function(part) {
return 'htdocs/' + part.type + '/' + part.name + '/*.js'
}),
dest: 'htdocs/output.js'
}
}
// ...
});
grunt.registerTask('default', [ 'concat' ]);
};
Примечания:
На этот раз мы присваиваем результат анализа вашего _config.yml
файла переменной external
:
var external = grunt.file.readYAML('_config.yml');
Значение свойства src
вычисляется с использованием map()
метод. Здесь мы создаем новый массив шаблонов глобуса .
src: external.computer.parts.map(function(part) {
return 'htdocs/' + part.type + '/' + part.name + '/*.js'
}),
Преимущества:
Одно из ключевых преимуществ Решение 2 имеет более Решение 1 :
Если нам нужно добавить новую деталь (name
и tyoe
) к _config.yml
. Например:
computer:
parts:
- name: brand1
type: cpu
- name: brand2
type: gpu
- name: brand3
type: hd
- name: brand4 <-------
type: foo <-------
С Решение 1 нам нужно добавить его в конфигурацию src
в Gruntfile. js. Например:
src: [
'htdocs/<%= external.computer.parts[0].type %>/<%= external.computer.parts[0].name %>/*.js',
'htdocs/<%= external.computer.parts[1].type %>/<%= external.computer.parts[1].name %>/*.js',
'htdocs/<%= external.computer.parts[2].type %>/<%= external.computer.parts[2].name %>/*.js',
// Newly added...
'htdocs/<%= external.computer.parts[3].type %>/<%= external.computer.parts[3].name %>/*.js'
],
С Решение 2 нам не нужно изменять конфигурацию src
в Gruntfile. js вообще.
Редактировать:
Если вы используете довольно свежую версию node.js, вы также можете выполнить рефакторинг Solution 2 следующим образом:
Gruntfile. js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-concat');
const { computer: { parts } } = grunt.file.readYAML('_config.yml');
grunt.initConfig({
concat: {
dist: {
options: {
// ...
},
src: parts.map(({ type, name }) => `htdocs/${type}/${name}/*.js`),
dest: 'htdocs/output.js'
}
}
// ...
});
grunt.registerTask('default', [ 'concat' ]);
};
Пожалуйста, игнорируйте невозможность синтаксиса StackOverflow, выделите приведенный выше пример правильно.
Примечания:
В этой переработанной версии некоторые функции ES6 используются следующим образом:
Уничтожение объектов используется для распаковки свойства / значения parts
из проанализированного _config.yml
в переменную parts
:
var { computer: { parts } } = grunt.file.readYAML('_config.yml');
Значение свойства src
вычисляется с использованием функции Arrow с метод map()
и литералы шаблона используются вместо оператора плюс (+
) для объединения строк.
src: parts.map(({ type, name }) => `htdocs/${type}/${name}/*.js`),