Grunt: есть package.json и Gruntfile.js в разных папках

#javascript #node.js #npm #gruntjs

#javascript #node.js #npm #gruntjs

Вопрос:

У меня возникли проблемы при попытке реализовать grunt в разных папках, в моем корне у меня есть:

 <root>/package.json
<root>/node_modules
  

И внутри другой папки мой gruntfile с разными вложенными папками и файлами, с которыми я работаю:

 <root>/apps/static/Gruntfile.js
  

Если я перейду к root и выполню

 grunt --gruntfile /apps/static/Gruntfile.js MyTaskName
  

Я получаю:

Локальный модуль Npm «grunt-contrib-concat» не найден. Он установлен?

Локальный модуль Npm «grunt-contrib-cssmin» не найден. Он установлен?

Локальный модуль Npm «grunt-contrib-clean» не найден. Он установлен?

Локальный модуль Npm «grunt-contrib-watch» не найден. Он установлен?

Локальный модуль Npm «grunt-contrib-uglify» не найден. Он установлен?

И я несколько раз запускаю установку npm.

В моем gruntfile.js у вас есть

grunt.loadNpmTasks('grunt-contrib-concat');

grunt.loadNpmTasks('grunt-contrib-cssmin');

grunt.loadNpmTasks('grunt-contrib-clean');

grunt.loadNpmTasks('grunt-contrib-watch');

grunt.loadNpmTasks('grunt-contrib-uglify');

Я трижды проверяю, и папки в порядке (на самом деле, изначально gruntfile и package находились в одной папке, и все работало идеально, запустите несколько задач, и все в порядке). Мне действительно нужно иметь общий package.json и node_modules для root и Gruntfile.js в определенной папке проекта

Есть идеи, что происходит? заранее спасибо

Ответ №1:

Grunt делает определенные предположения относительно местоположения gruntfile.js .

Когда вы указываете местоположение gruntfile.js использования --gruntfile опции, Grunt устанавливает текущий каталог в каталог, содержащий указанный файл:

 // Change working directory so that all paths are relative to the
// Gruntfile's location (or the --base option, if specified).
process.chdir(grunt.option('base') || path.dirname(gruntfile));
  

И когда Grunt загружает задачи NPM, он делает это относительно текущего каталога:

 var root = path.resolve('node_modules');
var pkgfile = path.join(root, name, 'package.json');
  

Существует --base опция, с помощью которой можно указать текущий каталог, но решит ли это вашу проблему (без создания других проблем) Я не знаю. Самое простое решение, скорее всего, будет размещаться gruntfile.js там, где оно хочет и ожидает, что оно будет расположено.

Комментарии:

1. Я читал о —base, но у меня все еще есть проблемы, я в корневой папке и получаю: не удалось найти действительный файл Gruntfile. Пожалуйста, ознакомьтесь с руководством по началу работы для получения дополнительной информации о том, как настроить grunt: gruntjs.com/getting-started Неустранимая ошибка: не удается найти Gruntfile. И gruntfile есть. Моя проблема в том, что это большой проект, и наличие всего в одном файле может быть сложным. Я работаю с этим на 8 веб-сайтах, и у каждого должен быть свой конкретный grunt, чтобы упростить его

2. Я думаю, что, пытаясь найти gruntfile.js место, где оно на самом деле не хочет находиться, вы попадаете в мир боли. Это похоже на проблему XY . Если ваша проблема сложная, у Grunt есть некоторые другие механизмы, которые могут предложить менее болезненные решения (например grunt.config.merge ). Я бы предложил задать еще один вопрос, в котором спрашивается, как можно решить вашу проблему сложности. Я думаю, что на вопрос «почему это не работает» был дан ответ.

Ответ №2:

Иногда может потребоваться, чтобы проект Gruntfile.js находился в другой папке, чем package.json .

У меня был очень похожий вариант использования, когда было несколько подмодулей, каждый со своим собственным процессом сборки, один из них был Grunt. Но в то же время я хотел иметь общий package.json , чтобы избежать создания нескольких node_modules папок, чтобы общие зависимости (включая транзитивные) использовались для установки один раз. Это помогло сократить время установки, а также использование диска.

Я ожидал решения в самом Grunt. Но, как упоминал @cartant, Grunt сделал определенные предположения.

Итак, вот что я сделал:

В Gruntfile.js ,

Определите функцию:

 function loadExternalNpmTasks(grunt, name) {
  const tasksdir = path.join(root, 'node_modules', name, 'tasks');
  if (grunt.file.exists(tasksdir)) {
    grunt.loadTasks(tasksdir);
  } else {
    grunt.log.error('Npm module "'   name   '" not found. Is it installed?');
  }
}
  

И вместо

 grunt.loadNpmTasks('grunt-contrib-concat');
  

сделать:

 loadExternalNpmTasks(grunt, 'grunt-contrib-concat');
  

Ссылка: https://github.com/gruntjs/grunt/blob/master/lib/grunt/task.js#L396