I am trying to access values from an external YAML file in my Gruntfile using:
external = grunt.file.readYAML('_config.yml');
The _config.yml file has the following example data:
computer:
parts:
- name: brand1
type: cpu
- name: brand2
type: gpu
- name: brand3
type: hd
I've been trying to access the multi-level YAML data using <%= %> grunt templating to get the different name and type values.
module.exports = {
concat: {
src: ['htdocs/<%= external.computer.parts['type'] %>/<%= external.computer.parts['name'] %>/*.js'],
dest: 'htdocs/output.js'
}
};
The main goal has been to concat files from different directories this way into one, but I can't seem to access data from the _config.yml file beyond external.computer.parts. FYI, the structure of the _config.yml file has to remained unchanged.
How do you access a sequence/list with different properties this way?
Below are a couple of solutions to consider. However, firstly let's understand what using
grunt.file.readYAML()to parse your_config.ymlfile does. It essentially produces the following object:Note how the value of
partsis an array of objects.Solution 1:
Given that you want to utilize grunt templates (i.e.
<%= %>) to obtain the differentnameandtypevalues, consider configuring yourconcattask in your Gruntfile.js as follows:Gruntfile.js
Notes:
The value of the
externalproperty of the object passed into thegrunt.initConfigmethod is essentially the aforementioned object, i.e. it's the result of utiizinggrunt.file.readYAML()to parse your_config.yml.The value of the
srcproperty of thedisttarget, (which is associated with theconcattask), is an array. Each item of this array is where we utilize the<% ... %>notation to reference the parts from your.ymlfile.Note how we reference each object in the
external.computer.partsarray by it's index, i.e.[0],[1],[2]Solution 2:
Another way to achieve your requirement is to not utilize grunt templates, i.e.
<% ... %>, at all. Consider the following solution:Gruntfile.js
Notes:
This time we assign the result of parsing your
_config.ymlfile to a variable namedexternal:The value of the
srcproperty is computed by utilizing themap()method. Here we create a new array of glob patterns.Benefits:
One of the key benefits that Solution 2 has over Solution 1 is:
If we need to add a new part (
nameandtyoe) to_config.yml. For example:With Solution 1 we will need to add it to the
srcconfiguration in the Gruntfile.js. For example:With Solution 2 we don't have to change the
srcconfiguration in the Gruntfile.js at all.Edit:
If you're using a fairly recent version of node.js then you can also refactor Solution 2 as follows:
Gruntfile.js
Please ignore StackOverflow's inability to syntax highlight the above example correctly.
Notes:
This refactored version utilizes some ES6 features as follows:
Object destructuring is used to unpack the
partsproperty/value from the parsed_config.yml, into apartsvariable:The value of the
srcproperty is computed using an Arrow function with themap()method, and Template Literals are used instead of the plus operator (+) for string concatenation.