Доступ к данным конфигурации Grunt в initConfig()

Как мне получить доступ к свойству конфигурации Grunt site для чтения файла project.json по пути, указанному значением свойства конфигурации?

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 build:sitename

>> Error: Unable to read "./sites/undefined/project.json"

Используя пример из документов, я также пробовал это:

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 global:site:sitename

>> Error: Unable to read "./sites/undefined/project.json"

Обновление

Используя ответ @FelixKling в качестве руководства, я сделал некоторый прогресс:

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'
      }
    }
  },
});

Теперь я могу прочитать файл project.json успешно, и (каким-то образом) он даже способен распознавать, когда редактируются файлы наблюдения. Но по какой-то причине, когда он запускает задачу sass:dist, я получаю эту ошибку: Warning: An error occurred while processing a template (Cannot read property 'dev' of undefined).

Я не понимаю, как задача watch может получить правильное значение для site, но что более важно, мне нужно выяснить способ получения того же значения для задачи sass.

Ответ 1

initConfig и grunt.file.readJSON выполняются до запуска вашей задачи. Кажется, что вам нужны строки шаблонов, и вы можете вызывать только grunt.file.readJSON, когда у вас действительно есть целевое имя.

Например:

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'
});

Дополнительная информация: http://gruntjs.com/api/grunt.config


Что касается вашего обновления: вы в основном повторяете ту же ошибку, что и в первом примере. Вы пытаетесь получить доступ к config site до его установки.

Вы должны понимать, что шаг инициализации, т.е. grunt.initConfig, имеет место до, если выполняется любой связанный с задачей код:

Initialize config -> Run task

Давайте рассмотрим grunt.initConfig по отдельности:

grunt.initConfig({
  pkg: grunt.file.readJSON('package.json'),
  site: grunt.config.get('site'),
});

Это шаг инициализации, который происходит раньше всего. Аргумент, переданный initConfig, объект конфигурации, оценивается первым. То, что вы пытаетесь сделать здесь, - это доступ к параметрам конфигурации site, прежде чем конфиг будет даже создан. Надеюсь, вы признаете, что это не имеет смысла.

Может быть, это поможет вам понять процесс, если вы положите grunt.initConfig на самый верх, прежде чем регистрировать какие-либо задачи.


Решение:

Я думаю, что на самом деле вы можете использовать аргументы командной строки, с помощью которых вы можете контролировать, какой сайт строить. Подробнее см. grunt.option.

Например:

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'));

И затем вы запустите задачу с помощью

grunt watch --site=somesite