Grunt:来自外部YAML文件的访问序列/列表数据 [英] Grunt: Access Sequence/List Data from External YAML File
问题描述
我正在尝试使用以下命令从Gruntfile中的外部YAML文件访问值:
I am trying to access values from an external YAML file in my Gruntfile using:
external = grunt.file.readYAML('_config.yml');
_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
我一直在尝试使用<%= %>
grunt模板访问多级YAML数据,以获取不同的名称和类型值.
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'
}
};
主要目标是通过这种方式将来自不同目录的文件合并为一个,但是我似乎无法访问external.computer.parts
之外的_config.yml
文件中的数据.仅供参考,_config.yml
文件的结构必须保持不变.
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?
推荐答案
以下是要考虑的两个解决方案.但是,首先让我们了解一下使用 grunt.file.readYAML()
来解析您的_config.yml
文件.它实质上产生以下对象:
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. It essentially produces the following object:
{
computer: {
parts: [
{
name: 'brand1',
type: 'cpu'
},
{
name: 'brand2',
type: 'gpu'
},
{
name: 'brand3',
type: 'hd'
}
]
}
}
注意:parts
的值如何是对象数组.
Note how the value of parts
is an array of objects.
鉴于您要使用 grunt模板(即<%= %>
)来获取name
和type
不同的值,请考虑在 Gruntfile.js 中配置您的concat
任务,如下所示:
Given that you want to utilize grunt templates (i.e. <%= %>
) to obtain the different name
and type
values, consider configuring your concat
task in your Gruntfile.js as follows:
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' ]);
};
注释:
The value of the
external
property of the object passed into thegrunt.initConfig
method is essentially the aforementioned object, i.e. it's the result of utiizinggrunt.file.readYAML()
to parse your_config.yml
.
dist
的src
属性的值 target ,(与concat
task ),是一个数组.我们使用<% ... %>
表示法从该数组的每个项目中引用.yml
文件中的各个部分.
The value of the src
property of the dist
target, (which is associated with the concat
task), is an array. Each item of this array is where we utilize the <% ... %>
notation to reference the parts from your .yml
file.
请注意我们如何通过external.computer.parts
数组中的每个对象的索引来引用它们,即[0]
,[1]
,[2]
Note how we reference each object in the external.computer.parts
array by it's index, i.e. [0]
, [1]
, [2]
'htdocs/<%= external.computer.parts[0].type %>/<%= external.computer.parts[0].name %>/*.js'
^ ^
解决方案2:
满足要求的另一种方法是根本不使用grunt模板,即<% ... %>
.考虑以下解决方案:
Solution 2:
Another way to achieve your requirement is to not utilize grunt templates, i.e. <% ... %>
, at all. Consider the following solution:
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
的变量:
This time we assign the result of parsing your
_config.yml
file to a variable namedexternal
:
var external = grunt.file.readYAML('_config.yml');
src
属性的值是通过使用全局模式的数组.
The value of the src
property is computed by utilizing the map()
method. Here we create a new array of glob patterns.
src: external.computer.parts.map(function(part) {
return 'htdocs/' + part.type + '/' + part.name + '/*.js'
}),
好处:
解决方案2 优于解决方案1 的主要优势之一是:
Benefits:
One of the key benefits that Solution 2 has over Solution 1 is:
如果需要在_config.yml
中添加新零件(name
和tyoe
).例如:
If we need to add a new part (name
and tyoe
) to _config.yml
. For example:
computer:
parts:
- name: brand1
type: cpu
- name: brand2
type: gpu
- name: brand3
type: hd
- name: brand4 <-------
type: foo <-------
使用解决方案1 ,我们需要将其添加到 Gruntfile.js 中的src
配置中.例如:
With Solution 1 we will need to add it to the src
configuration in the Gruntfile.js. 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'
],
使用解决方案2 ,我们不必完全更改 Gruntfile.js 中的src
配置.
With Solution 2 we don't have to change the src
configuration in the Gruntfile.js at all.
如果您使用的是最新版本的node.js,则还可以按以下方式重构解决方案2 :
If you're using a fairly recent version of node.js then you can also refactor Solution 2 as follows:
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功能,如下所示:
This refactored version utilizes some ES6 features as follows:
-
对象解构用于将解析的
_config.yml
中的parts
属性/值解压缩为parts
变量:
Object destructuring is used to unpack the
parts
property/value from the parsed_config.yml
, into aparts
variable:
var { computer: { parts } } = grunt.file.readYAML('_config.yml');
src
属性的值是使用带有map()
方法的箭头功能,并且模板文字用于代替字符串串联的加号(+
).
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: parts.map(({ type, name }) => `htdocs/${type}/${name}/*.js`),
这篇关于Grunt:来自外部YAML文件的访问序列/列表数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!