Grunt-string-replace 使用键值对对象

Grunt-string-replace using an object of key-value pairs

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

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

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

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

修改后的答案(评论后)

... Is there anyway to loop through the key-value pair of variableToReplace and replace, for example, var1 with var1_replacement.

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

  1. package.json 中读取 variableToReplace 对象。
  2. 动态构建 options.replacements 数组。
  3. Configure/set option.replacements 数组使用 grunt.config.set
  4. 然后最后 运行 使用 grunt.task.run 的任务。

以下 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-replacedocs 状态:

If the pattern is a string, only the first occurrence will be replaced...

为了确保 search/find 字符串的多个实例被匹配和替换,configAndRunStringReplace 自定义任务使用带有 global g flag.

的正则表达式

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

\ ^ $ * + ? . ( ) | { } [ ]

可能会在搜索词中使用(即作为 package.json 中的 key/property 名称)需要转义。在 Regex 中转义这些字符的典型方法是在字符前添加反斜杠 \(例如 \?\+ 等)。但是,因为您在 JSON 中使用 key/property 名称来定义您的搜索词。您需要对前面提到的任何字符进行两次转义,以确保您的 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') 添加到 Gruntfile.jsgrunt.initConfig() 部分。这将解析存储在 package.json.

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

  3. 将上面设计的 Gruntfile.js 配置与您的 package.json 数据一起使用(如您的问题所述)。将发生以下情况:

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

    • 生成的文件将保存到 dist/ 目录。