Grunt:来自外部YAML文件的访问序列/列表数据 [英] Grunt: Access Sequence/List Data from External YAML File

查看:150
本文介绍了Grunt:来自外部YAML文件的访问序列/列表数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用以下命令从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模板(即<%= %>)来获取nametype不同的值,请考虑在 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' ]);

};

注释:

  1. 对象的external属性值传递到 方法本质上是上述对象,即它是使用grunt.file.readYAML()解析您的_config.yml的结果.

  1. The value of the external property of the object passed into the grunt.initConfig method is essentially the aforementioned object, i.e. it's the result of utiizing grunt.file.readYAML() to parse your _config.yml.

distsrc属性的值 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' ]);

};

注释:

  1. 这一次,我们将解析_config.yml文件的结果分配给名为external的变量:

  1. This time we assign the result of parsing your _config.yml file to a variable named external:

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中添加新零件(nametyoe).例如:

    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 a parts 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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆