最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Access Grunt config data within initConfig() - Stack Overflow

programmeradmin2浏览0评论

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.

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.

Share Improve this question edited Apr 11, 2014 at 14:22 cantera asked Apr 10, 2014 at 18:39 canteracantera 25k25 gold badges102 silver badges140 bronze badges 1
  • Regarding your update, at the moment grunt.file.readJSON('./sites/' + global.site + '/project.json') runs, global.site doesn't exist yet since the global task didn't run yet. Check my answer again, I fixed what was wrong. – Felix Kling Commented Apr 10, 2014 at 19:45
Add a comment  | 

1 Answer 1

Reset to default 18

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
发布评论

评论列表(0)

  1. 暂无评论