Revised Answer (after comment)
... Is there anyway to loop through the key-value pair of variableToReplace
and replace, for example, var1
with var1_replacement
.
Yes, this can be achieved by utilizing a Custom Task. The custom task should perform the following:
- Read the
variableToReplace
object from package.json
.
- Dynamically build the
options.replacements
array.
- Configure/set the
option.replacements
array using grunt.config.set
- Then finally run the task using
grunt.task.run
.
The following Gruntfile.js
demonstrates this solution:
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']);
}
Important note regarding Regular Expressions:
The docs for grunt-string-replace
states:
If the pattern is a string, only the first occurrence will be replaced...
To ensure that multiple instances of the search/find string are matched and replaced the configAndRunStringReplace
custom task utilizes a Regular Expression with the global g
flag.
So, any instances of the following regex special characters:
\ ^ $ * + ? . ( ) | { } [ ]
which may be used in a search word (i.e. as a key/property name in your package.json
) will need to be escaped. The typical way to escape these characters in a Regex is to add a backslash \
before the character (E.g. \?
or \+
etc..). However, because you're using key/property names in JSON to define your search word. You'll need to double escape any of the previously mentioned characters to ensure your JSON remains valid. For Example:
Lets say you wanted to replace question marks (?
) with exclamation marks (!
). Instead of defining those rules in package.json
like this:
...
"variableToReplace":{
"?": "!"
},
...
Or like this:
...
"variableToReplace":{
"\?": "!"
},
...
You'll need to do this (i.e. use double escapes \\
):
...
"variableToReplace":{
"\\?": "!"
},
...
Original Answer
The following contrived example shows how this can be achieved:
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']);
}
Notes
Add pkg: grunt.file.readJSON('package.json')
to the grunt.initConfig()
section of your Gruntfile.js
. This will parse the JSON data stored in package.json
.
Use grunt templates to access the properties of package.json
. The standard JavaScript dot notation is used to access the property values, (e.g. pkg.variableToReplace.var1
), and is wrapped in a leading <%=
and trailing %>
Using the contrived Gruntfile.js
configuration above with your the package.json
data (as described in your question). The following would occur:
Any instances of the string var1_replacement
found in any of the .css
files stored in the src/css/
directory will be replaced with the string var2_replacement
.
The resultant files will be saved to the dist/
directory.