使用全局变量在Grunt中设置构建输出路径

时间:2013-03-26 21:10:23

标签: javascript gruntjs

我有几个笨拙的任务,我正在尝试分享这些任务中的全局变量,我遇到了问题。

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

// 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,它会输出正确的路径没问题。

但是,如果我有这样的任务:     干净:{       发布: {         src:global.outputPath       }     }

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

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

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

3 个答案:

答案 0 :(得分:13)

所以,我走的是正确的道路。问题是模块在这些全局变量设置之前导出,因此在initConfig()任务中定义的后续任务中它们都是未定义的。

我提出的解决方案虽然可能更好,但是要覆盖grunt.option值。

我的任务有一个可选选项--target

工作解决方案如下所示:

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

initConfig()中定义的任务如下所示:

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

如果您有更好的解决方案,请随意加入。否则,也许这可能有助于其他人。

答案 1 :(得分: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)

答案 2 :(得分: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', ], ...

  • in tasks

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

我在这里使用了键 options 只是为了符合惯例,但只要你记得不注册名为'options'的任务或其他任何东西,你就可以使用任何东西你用来做钥匙:)