How can I access the Grunt config property site
to read the project.json
file at the path specified by the config property value?
grunt.registerTask('build', function(target) {
grunt.config('site', target);
grunt.task.run('foo:dist', 'bar:dist');
});
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
site: grunt.file.readJSON('./sites/' + grunt.config('site') + '/project.json')
});
grunt-cli:
grunt build:sitename
>> Error: Unable to read "./sites/undefined/project.json"
Using an example from the docs, I also tried this:
grunt.registerTask('global', 'site', function(prop, value) {
global[prop] = val;
});
grunt.registerTask('build', ['foo:dist', 'bar:dist']);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
site: grunt.file.readJSON('./sites/' + global.site + '/project.json')
});
grunt-cli:
grunt global:site:sitename
>> Error: Unable to read "./sites/undefined/project.json"
Update:
Using the @FelixKling answer as a guide, I've made some progress:
grunt.registerTask('build', function(target) {
grunt.config.set('target', target);
grunt.config.set('site', grunt.file.readJSON('./sites/' + grunt.config.get('target') + '/project.json'));
grunt.task.run('watch');
});
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
site: grunt.config.get('site'),
watch: {
sass: {
files: ['<%= site.dev %>/scss/*.scss'],
tasks: ['sass:dist']
}
},
sass: {
dist: {
files: {
'<%= site.dist %>/style.css': '<%= site.dev %>/scss/style.scss'
}
}
},
});
Now I'm able to read in the project.json
file successfully, and (somehow) it's even able to recognize when edits are made to watched files. But for some reason when it runs the sass:dist
task, I get this error: Warning: An error occurred while processing a template (Cannot read property 'dev' of undefined).
I'm not clear on how the watch
task is able to get the correct value for site
, but more importantly, I need to figure out a way to get that same value to the sass
task.
config. Access project-specific configuration data defined in the Gruntfile . Note that any method marked with a ☃ (unicode snowman) is also available directly on the grunt object, and any method marked with a ☆ (white star) is also available inside tasks on the this object.
When a task is run, Grunt looks for its configuration under a property of the same name. Multi-tasks can have multiple configurations, defined using arbitrarily named "targets." In the example below, the concat task has foo and bar targets, while the uglify task only has a bar target.
The Grunt community is still going strong and both tools look like they're going to be around for a while yet. I should mention that another up and coming alternative to task runners like Grunt and Gulp is simply using npm scripts with command-line tools.
initConfig
and grunt.file.readJSON
run before your task runs. It seems like what you need are template strings and you can only call grunt.file.readJSON
when you actually have the target name.
For example:
grunt.registerTask('build', function(target) {
grunt.config.set('target', target);
grunt.config.set('site', grunt.file.readJSON(grunt.config.get('path'));
grunt.task.run('foo:dist', 'bar:dist');
});
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
path: './sites/<%= target %>/project.json'
});
More info: http://gruntjs.com/api/grunt.config
Regarding your update: You are basically making the same mistake again as you did in your first example. You are trying to access the config site
before it was set.
You have to understand that the initialization step, i.e. grunt.initConfig
takes place before any task related code runs:
Initialize config -> Run task
Lets look at grunt.initConfig
in isolation:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
site: grunt.config.get('site'),
});
This is the initialization step, which happens before everything else. The argument passed to initConfig
, the configuration object, is evaluated first. What you are trying to do here is access the config options site
, before the config was even created. I hope you recognize that this doesn't make sense.
Maybe it helps you to understand the process if you put grunt.initConfig
at the very top, before you register any tasks.
The solution:
I think what you actually might be after are command-line arguments, with which you can control which site to build. See grunt.option
for more information.
For example:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
sass: {
files: ['<%= site.dev %>/scss/*.scss'],
tasks: ['sass:dist']
}
}
});
grunt.config.set('site', grunt.file.readJSON('./sites/' + grunt.option('site') + '/project.json'));
And then you run the task with
grunt watch --site=somesite
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With