[英]Grunt: Access Sequence/List Data from External YAML File
I am trying to access values from an external YAML file in my Gruntfile using:我正在尝试使用 Gruntfile 中的外部 YAML 文件访问值:
external = grunt.file.readYAML('_config.yml');
The _config.yml
file has the following example data: _config.yml
文件具有以下示例数据:
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.我一直在尝试使用
<%= %>
grunt 模板访问多级 YAML 数据以获取不同的名称和类型值。
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
.主要目标是以这种方式将来自不同目录的文件合并为一个,但我似乎无法从
external.computer.parts
之外的_config.yml
文件中访问数据。 FYI, the structure of the _config.yml
file has to remained unchanged.仅供参考,
_config.yml
文件的结构必须保持不变。
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.yml
file does.但是,首先让我们了解使用
grunt.file.readYAML()
解析_config.yml
文件的作用。 It essentially produces the following object:它基本上产生以下 object:
{
computer: {
parts: [
{
name: 'brand1',
type: 'cpu'
},
{
name: 'brand2',
type: 'gpu'
},
{
name: 'brand3',
type: 'hd'
}
]
}
}
Note how the value of parts
is an array of objects.请注意,
parts
的值是一个对象数组。
Given that you want to utilize grunt templates (ie <%= %>
) to obtain the different name
and type
values, consider configuring your concat
task in your Gruntfile.js as follows:鉴于您想利用grunt 模板(即
<%= %>
)来获取不同的name
和type
值,请考虑在Gruntfile.js中配置您的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' ]);
};
Notes:笔记:
The value of the external
property of the object passed into thegrunt.initConfig
method is essentially the aforementioned object, ie it's the result of utiizing grunt.file.readYAML()
to parse your _config.yml
.传入
grunt.initConfig
方法的 object 的external
属性值本质上就是前面提到的 object,即使用grunt.file.readYAML()
解析您的_config.yml
的结果。
The value of the src
property of the dist
target , (which is associated with the concat
task ), is an array. dist
目标的src
属性的值(与concat
任务相关联)是一个数组。 Each item of this array is where we utilize the <%... %>
notation to reference the parts from your .yml
file.这个数组的每一项都是我们利用
<%... %>
符号来引用.yml
文件中的部分的地方。
Note how we reference each object in the external.computer.parts
array by it's index, ie [0]
, [1]
, [2]
请注意我们如何通过索引引用
external.computer.parts
数组中的每个 object,即[0]
、 [1]
、 [2]
'htdocs/<%= external.computer.parts[0].type %>/<%= external.computer.parts[0].name %>/*.js' ^ ^
Another way to achieve your requirement is to not utilize grunt templates, ie <%... %>
, at all.实现您的要求的另一种方法是根本不使用 grunt 模板,即
<%... %>
。 Consider the following solution:考虑以下解决方案:
Gruntfile.js 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' ]);
};
Notes:笔记:
This time we assign the result of parsing your _config.yml
file to a variable named external
:这次我们将解析你的
_config.yml
文件的结果分配给一个名为external
的变量:
var external = grunt.file.readYAML('_config.yml');
The value of the src
property is computed by utilizing the map()
method. src
属性的值是通过使用map()
方法计算的。 Here we create a new array of glob patterns .在这里,我们创建了一个新的glob 模式数组。
src: external.computer.parts.map(function(part) { return 'htdocs/' + part.type + '/' + part.name + '/*.js' }),
One of the key benefits that Solution 2 has over Solution 1 is:解决方案 2相对于解决方案 1的主要优势之一是:
If we need to add a new part ( name
and tyoe
) to _config.yml
.如果我们需要向
_config.yml
添加一个新部分( name
和tyoe
)。 For example:例如:
computer:
parts:
- name: brand1
type: cpu
- name: brand2
type: gpu
- name: brand3
type: hd
- name: brand4 <-------
type: foo <-------
With Solution 1 we will need to add it to the src
configuration in the Gruntfile.js .使用解决方案 1 ,我们需要将其添加到Gruntfile.js的
src
配置中。 For example:例如:
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'
],
With Solution 2 we don't have to change the src
configuration in the Gruntfile.js at all.使用解决方案 2 ,我们根本不需要更改Gruntfile.js中的
src
配置。
If you're using a fairly recent version of node.js then you can also refactor Solution 2 as follows:如果您使用的是相当新的 node.js 版本,那么您还可以重构解决方案 2 ,如下所示:
Gruntfile.js 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' ]);
};
Please ignore StackOverflow's inability to syntax highlight the above example correctly.请忽略 StackOverflow 无法正确突出上述示例的语法。
Notes:笔记:
This refactored version utilizes some ES6 features as follows:这个重构版本利用了一些 ES6 特性,如下所示:
Object destructuring is used to unpack the parts
property/value from the parsed _config.yml
, into a parts
variable: Object 解构用于将解析后的
_config.yml
中的parts
属性/值解压缩到parts
变量中:
var { computer: { parts } } = grunt.file.readYAML('_config.yml');
The value of the src
property is computed using an Arrow function with the map()
method, and Template Literals are used instead of the plus operator ( +
) for string concatenation. src
属性的值是使用带有map()
方法的Arrow function计算的,并且使用模板文字代替加号运算符 ( +
) 进行字符串连接。
src: parts.map(({ type, name }) => `htdocs/${type}/${name}/*.js`),
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.