使用键值对的对象进行Grunt-string-replace

时间:2018-03-19 15:40:34

标签: gruntjs grunt-string-replace

我在构建过程中开始使用grunt。在package.json中,我包含要以这种方式替换的变量:

{
  "name": "myApp",
  "variableToReplace":{
    "var1":"var1_replacement",
    "var2":"var2_replacement"
  },
  ...
}

但是,我不知道如何在variableToReplace中使用此Gruntfile.js,以便它会自动查找所有属性,然后用相应的值替换它们。是否可以使用Grunt?

'string-replace': {
  dist: {
    files: {
      //A list of files
    },
    options: {
      //What to put here?
    }
  }
}

1 个答案:

答案 0 :(得分:2)

修订后的答案(评论后)

  

...无论如何都要遍历variableToReplace的键值对,并将var1替换为var1_replacement

是的,这可以通过使用Custom Task来实现。自定义任务应执行以下操作:

  1. variableToReplace
  2. 中读取package.json对象
  3. 动态构建options.replacements数组。
  4. 使用grunt.config.set
  5. 配置/设置option.replacements数组
  6. 然后最后使用grunt.task.run运行任务。
  7. 以下Gruntfile.js演示了此解决方案:

    <强> Gruntfile.js

    module.exports = function(grunt) {
    
      grunt.loadNpmTasks('grunt-string-replace');
    
      grunt.initConfig({
    
        'string-replace': {
          dist: {
            files: [{
              expand: true,
              cwd: 'src/',
              src: '**/*.css',
              dest: 'dist/'
            }],
            options: {
              replacements: [] // <-- Intentionally empty and will be dynamically
                               //     configured via `configAndRunStringReplace`.
            }
          }
        }
      });
    
      /**
       *  Helper task to dynamically configure the Array of Objects for the
       * `options.replacements` property in the `dist` target of the `string-replace`
       *  task. Each property name of the `variableToReplace` Object (found in
       * `package.json`) is set as the search string, and it's respective value
       *  is set as the replacement value.
       */
      grunt.registerTask('configAndRunStringReplace', function () {
    
        // 1. Read the `variableToReplace` object from `package.json`.
        var replacements = grunt.file.readJSON('package.json').variableToReplace,
          config = [];
    
        // 2. Dynamically build the `options.replacements` array.
        for (key in replacements) {
          config.push({
            pattern: new RegExp(key, 'g'),
            replacement: replacements[key]
          });
        }
    
        // 3. Configure the option.replacements values.
        grunt.config.set('string-replace.dist.options.replacements', config);
    
        // 4. Run the task.
        grunt.task.run('string-replace:dist');
      });
    
      // Note: In the `default` Task we add the `configAndRunStringReplace`
      // task to the taskList array instead of `string-replace`.
      grunt.registerTask('default', ['configAndRunStringReplace']);
    }
    

    关于正则表达式的重要说明:

    grunt-string-replace州的docs

      

    如果模式是字符串,则只会替换第一个匹配项...

    为了确保匹配和替换搜索/查找字符串的多个实例,configAndRunStringReplace自定义任务使用带有global g flag的正则表达式。

    因此,以下正则表达式特殊字符的任何实例:

    \ ^ $ * + ? . ( ) | { } [ ]
    
    可以在搜索词中使用的

    (即package.json中的键/属性名称)将需要进行转义。在正则表达式中转义这些字符的典型方法是在字符(例如\\?等)之前添加反斜杠\+。但是,因为您在JSON中使用键/属性名来定义搜索词。您需要双重转义任何前面提到的字符,以确保您的JSON保持有效。例如:

    假设您想要用感叹号(?)替换问号(!)。而不是像package.json这样定义这些规则:

    ...
    "variableToReplace":{
      "?": "!"
    },
    ...
    

    或者像这样:

    ...
    "variableToReplace":{
      "\?": "!"
    },
    ...
    

    您需要这样做(即使用双重转义\\):

    ...
    "variableToReplace":{
      "\\?": "!"
    },
    ...
    

    原始答案

    以下设想的例子说明了如何实现这一目标:

    <强> Gruntfile.js

    module.exports = function(grunt) {
    
      grunt.loadNpmTasks('grunt-string-replace');
    
      grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'), // 1. Read the package.json file.
    
        'string-replace': {
          dist: {
            files: {
              'dist/': ['src/css/**/*.css'],
            },
            options: {
              replacements: [{
                // 2. Use grunt templates to reference the properties in package.json
                pattern: '<%= pkg.variableToReplace.var1 %>',
                replacement: '<%= pkg.variableToReplace.var2 %>',
              }]
            }
          }
        }
      });
    
      grunt.registerTask('default', ['string-replace']);
    
    }
    

    备注

    1. pkg: grunt.file.readJSON('package.json')添加到grunt.initConfig()的{​​{1}}部分。这将解析存储在Gruntfile.js

    2. 中的JSON数据
    3. 使用grunt templates访问package.json的属性。标准JavaScript点表示法用于访问属性值(例如package.json),并包含在前导pkg.variableToReplace.var1和尾随<%=

    4. 使用上面设计的%>配置和Gruntfile.js数据(如您的问题中所述)。将发生以下情况:

      • package.json目录中存储的任何var1_replacement文件中找到的字符串.css的任何实例都将替换为字符串src/css/

      • 结果文件将保存到var2_replacement目录。