6

我有几个繁重的任务,我试图在这些任务之间共享全局变量,但我遇到了问题。

我编写了一些自定义任务,根据构建类型设置正确的输出路径。这似乎是正确设置的东西。

// Set Mode (local or build)
grunt.registerTask("setBuildType", "Set the build type. Either build or local", function (val) {
  // grunt.log.writeln(val + " :setBuildType val");
  global.buildType = val;
});

// SetOutput location
grunt.registerTask("setOutput", "Set the output folder for the build.", function () {
  if (global.buildType === "tfs") {
    global.outputPath = MACHINE_PATH;
  }
  if (global.buildType === "local") {
    global.outputPath = LOCAL_PATH;
  }
  if (global.buildType === "release") {
    global.outputPath = RELEASE_PATH;
  }
  if (grunt.option("target")) {
    global.outputPath = grunt.option("target");
  }
  grunt.log.writeln("Output folder: " + global.outputPath);
});

grunt.registerTask("globalReadout", function () {
  grunt.log.writeln(global.outputPath);
});

所以,我试图在后续任务中引用 global.outputPath,并遇到错误。

如果我grunt test从命令行调用,它输出正确的路径没问题。

但是,如果我有这样的任务: clean: { release: { src: global.outputPath } }

它抛出以下错误: Warning: Cannot call method 'indexOf' of undefined Use --force to continue.

此外,我在 setOutput 任务中的常量设置在 Gruntfile.js 的顶部

有什么想法吗?我在这里做错了吗?

4

3 回答 3

13

So, I was on the right path. The issue is that the module exports before those global variables get set, so they are all undefined in subsequent tasks defined within the initConfig() task.

The solution I came up with, although, there may be better, is to overwrite a grunt.option value.

I have an optional option for my task --target

working solution looks like this:

grunt.registerTask("setOutput", "Set the output folder for the build.", function () {
  if (global.buildType === "tfs") {
    global.outputPath = MACHINE_PATH;
  }
  if (global.buildType === "local") {
    global.outputPath = LOCAL_PATH;
  }
  if (global.buildType === "release") {
    global.outputPath = RELEASE_PATH;
  }
  if (grunt.option("target")) {
    global.outputPath = grunt.option("target");
  }

  grunt.option("target", global.outputPath);
  grunt.log.writeln("Output path: " + grunt.option("target"));
});

And the task defined in initConfig() looked like this:

clean: {
  build: {
    src: ["<%= grunt.option(\"target\") %>"]
  }
}

Feel free to chime in if you have a better solution. Otherwise, perhaps this may help someone else.

于 2013-03-27T15:54:39.793 回答
4

我有一种方法可以让您使用诸如--dev. 到目前为止,它工作得很好,我非常喜欢它。以为我会分享它,因为其他人也可能喜欢它。

    # Enum for target switching behavior
    TARGETS =
      dev: 'dev'
      dist: 'dist'

    # Configurable paths and globs
    buildConfig =
      dist: "dist"
      dev: '.devServer'
      timestamp: grunt.template.today('mm-dd_HHMM')

    grunt.initConfig
        cfg: buildConfig
        cssmin:
            crunch:
                options: report: 'min'
                files: "<%= grunt.option('target') %>/all-min.css": "/**/*.css"

    # Set the output path for built files.
    # Most tasks will key off this so it is a prerequisite
    setPath = ->
      if grunt.option 'dev'
        grunt.option 'target', buildConfig.dev
      else if grunt.option 'dist'
        grunt.option 'target', "#{buildConfig.dist}/#{buildConfig.timestamp}"
      else # Default path
        grunt.option 'target', buildConfig.dev
      grunt.log.writeln "Output path set to: `#{grunt.option 'target'}`"
      grunt.log.writeln "Possible targets:"
      grunt.log.writeln target for target of TARGETS

    setPath()

使用此设置,您可以运行以下命令:

grunt cssmin --dist #sent to dist target
grunt cssmin --dev #sent to dev target
grunt cssmin --dev #sent to default target (dev)
于 2013-08-23T17:33:03.923 回答
0

这是一个较老的问题,我只是想投入我的 5 美分。

如果您需要可以从任何任务访问配置变量,只需在您的主(您将始终加载的)配置文件中定义它,如下所示:

module.exports = function(grunt)
{
    //
    // Common project configuration
    //
    var config = 
    {
        pkg: grunt.file.readJSON('package.json'),

        options: // for 'project'
        {
            dist:
            {
                outputPath: '<%= process.cwd() %>/lib',
            },
            dev:
            {
                outputPath: '<%= process.cwd() %>/build',
            },
        },
    }

    grunt.config.merge( config )
}

然后您可以像这样简单地访问值:

  • 在配置文件中

... my_thingie: [ ends_up_here: '<%= options.dev.outputPath %>/bundle', ], ...

  • 在任务中

// as raw value grunt.config.data.options.dist.outputPath // after (eventual) templates have been processed grunt.config('options.dist.outputPath')

我在这里使用 keyoptions只是为了符合约定,但是你可以使用任何东西,只要你记得不要注册一个名为的任务'options'或你用于 key 的任何东西 :)

于 2017-06-01T04:21:05.480 回答