Gruntjs 正在运行在my grunt插件中定义的任务:找不到任务

Gruntjs 正在运行在my grunt插件中定义的任务:找不到任务,gruntjs,Gruntjs,我正在尝试将我在Grunt文件中编写的一些任务用于一个项目,并制作一个可重用的Grunt插件。我一直在努力寻找一些演示如何实现端到端连接的文档,但进展缓慢。简而言之,我的插件将采用一个HTML SWIG模板,并将其本地化为CSV文件指定的一系列不同的地区。(还有一些其他的步骤,但我尽量让这篇文章简单一些) 我使用的是grunt v0.4.5,我使用grunt init并克隆了grunt插件repo,如中所述。以下是到目前为止我得到的信息: grunt-emaillocalization/ (Pl

我正在尝试将我在Grunt文件中编写的一些任务用于一个项目,并制作一个可重用的Grunt插件。我一直在努力寻找一些演示如何实现端到端连接的文档,但进展缓慢。简而言之,我的插件将采用一个HTML SWIG模板,并将其本地化为CSV文件指定的一系列不同的地区。(还有一些其他的步骤,但我尽量让这篇文章简单一些)

我使用的是grunt v0.4.5,我使用grunt init并克隆了grunt插件repo,如中所述。以下是到目前为止我得到的信息:

grunt-emaillocalization/ (Plugin definition)
 - Gruntfile.js
 - package.json
 - tasks/
   - emaillocalization.js
   - bin/
     - convertCSVtoJSONForSWIG.js
     - makeEmailImages.js
下面是GrunFile.js的插件定义。它使用了一个名为的插件。为简洁起见,简化了:

'use strict';

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    emaillocalization: {
      default_options: {
        options: {
          csvFile: 'config/emaillocalization/email.csv',
          templatesDir: 'config/emaillocalization'
        }
      }
    },

    swigLocalization: {
      main: {
        src: ['<%= emaillocalization.default_options.templatesDir %>/templates/*.swig', 'tmp/emaillocalization/json/*.json'],
        outputDir: 'dist/emaillocalization'
      }
    },

    /* Snip some other stuff */

  });

  // Actually load this plugin's task(s).
  grunt.loadTasks('tasks');

  // These plugins provide necessary tasks.
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-swig-localization');
  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-text-replace');

};
'use strict';

module.exports = function(grunt) {

  grunt.registerMultiTask('emaillocalization', 'Localizes email templates using a CSV as input.', function() {
    /* Snip setting some parameters */
    var taskList = ['emailprep', 'emailcsv2json', 'swigLocalization', 'copy:copyEmailImageFiles', 'shell:emailImages', 'replace:emailImageURLPrefix'];
    grunt.task.run(taskList);
  });

  /* Snip some other tasks */

};
如果我从插件定义repo运行grunt emaillocalization,它会完成它应该做的一切;所有任务都会得到处理

包定义中的package.json文件包含以下内容,以强制将swigLocalization插件与npm安装捆绑在一起:

  "dependencies": {
    "grunt-swig-localization": "~0.1.0"
  },
现在在我的项目的repo中,我将grunt emaillocalization插件包含在package.json中,因此:

  "devDependencies": {
    ...,
    "grunt-emaillocalization": "git@bitbucket.org:mycompany/grunt-emaillocalization.git"
  }
然后在项目的repo的Gruntfile.js中,我将其定义如下:

*global module:false*/
module.exports = function(grunt) {

  require("load-grunt-tasks")(grunt);
  require("time-grunt")(grunt);

  // Project configuration.
  grunt.initConfig({

    /* Snip a whole bunch of stuff */

    emaillocalization: {
      default_options: {
        options: {
          csvFile: 'email.csv',
          templatesDir: 'misc/emaillocalization'
        },
        files: {
          'tmp/default_options': ['test/fixtures/testing', 'test/fixtures/123']
        }
      }
    },

    gitinfo: {}

  });

  /* Snip a whole bunch of project registerTasks */

  grunt.loadTasks('tasks');
  grunt.loadNpmTasks('grunt-emaillocalization');

};
问题

我陷入困境的地方是,当我从project repo运行grunt emaillocalization.js(即,我尝试实际使用我的插件)时,我得到以下错误:

警告:未找到任务“swigLocalization”。使用--force继续

调试

在我的插件源代码中,如果我运行grunt--help,swigLocalization将被列为一项可用任务

在我使用插件的项目中,如果我运行npm listgrunt swig本地化插件,它提供了swigLocalization任务),那么肯定可以:

├─┬ grunt-emaillocalization@0.1.0
│ └─┬ grunt-swig-localization@0.1.0
│   └─┬ swig@1.1.0
│     ├─┬ optimist@0.6.0
│     │ ├── minimist@0.0.10
│     │ └── wordwrap@0.0.3
│     └─┬ uglify-js@2.4.0
│       ├── async@0.2.10
│       ├─┬ optimist@0.3.7
│       │ └── wordwrap@0.0.3
│       ├─┬ source-map@0.1.43
│       │ └── amdefine@1.0.0
│       └── uglify-to-browserify@1.0.2

提前谢谢你的帮助

经过多次修补,我找到了解决办法

首先,当任务作为插件在另一个项目中运行时,插件定义中的Gruntfile.js被忽略。因此,任何捆绑插件的配置都必须在插件的任务文件中按程序设置。以下是我简化的工作任务/emaillocalization.js:

'use strict';

module.exports = function(grunt) {
  var path = require('path');

  grunt.task.loadTasks(path.resolve(__dirname, '../node_modules/grunt-swig-localization/tasks'));

  grunt.registerMultiTask('emaillocalization', 'Localizes email templates using a CSV as input.', function() {
    /* Snip setting some parameters */
    var taskList = ['emailprep', 'emailcsv2json', 'generateHtmlFiles:'+this.options().templatesDir /* other tasks */];
    grunt.task.run(taskList);
  });

  grunt.registerTask('generateHtmlFiles', 'Create HTML files from JSON and template', function (src) {
    var templatePath = path.resolve(src) + path.sep + '*.swig';
    var jsonPath = path.resolve('tmp/emaillocalization/json') + path.sep + '*.json';
    // TIP: Don't resolve path for this.
    var outputPath = 'dist/emaillocalization';

    grunt.config.set('swigLocalization', {
      main: {
        src: [templatePath, jsonPath],
        outputDir: outputPath
      }
    });
    var taskList = ['emailprep', 'swigLocalization'];
    grunt.task.run(taskList);
  });

  /* Snip other tasks */
};
我发现在自己的插件中使用第三方任务的关键点是:

  • 确保将依赖插件设置为package.json中的依赖项,而不是devdependency。这可以确保在使用插件时运行npm install时安装它们。(我已经这样做了)
  • 将所有配置从插件的Gruntfile.js移到插件的任务文件中,根据需要添加包装器任务,并在运行任务之前使用按程序进行设置。你可以看报纸
  • 在使用第三方插件之前,请使用显式加载要在任务文件中使用的第三方插件中的任务。您还需要使用节点的和_dirname来引用插件的任务目录,相对于插件的任务文件