问题
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.
回答1:
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
来源:https://stackoverflow.com/questions/22996343/access-grunt-config-data-within-initconfig