2013-03-26 12 views
6

我有幾個grunt任務,我試圖在這些任務之間共享全局變量,並且遇到了問題。使用全局變量在Grunt中設置生成輸出路徑

我寫了一些自定義任務,根據構建類型設置正確的輸出路徑。這似乎是正確設置的東西。

// 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,它會輸出正確的路徑沒有問題。

但是,如果我有這樣的任務: 清潔:{ 版本:{ 源:global.outputPath }}

它引發以下錯誤: Warning: Cannot call method 'indexOf' of undefined Use --force to continue.

而且,我的常量在setOutput任務設置在我的Gruntfile.js頂部

有什麼想法?我在這裏做錯了什麼?

+0

我想這可能與global.outputPath被設置在grunt.initConfig({})之外,而我試圖訪問grunt.initConfig ({}) – ThePuzzleMaster 2013-03-26 21:19:04

回答

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

我喜歡全局設置構建目標目錄的想法。另一種方法是爲每個過程定義單獨的規則,僅僅因爲目的地不同。 (如:sass:dev','coffee:dev','sass:dist','coffee:dist')。這是一個痛苦,不是很乾。感謝您在這方面做腿部工作! – SimplGy 2013-08-23 16:49:40

+0

如果定義了'global.Outputpath'等於'grunt.option('target')',那麼我將它設置爲'grunt.option('target')' 'global.Outputpath'。那你有什麼打算? – SimplGy 2013-08-23 17:06:05

+0

啊。現在看看,如果在運行時設置了選項(「target」),更好的方法是在該函數的第一行放置返回值。否則,我將global.Outputpath設置爲grunt.option(「target」),這樣如果它們在運行時傳入目標,它將覆蓋所有默認值。 – ThePuzzleMaster 2013-08-24 03:47:19

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

你的Gruntfile是coffescript?鏈接到設置/如何請:)好的提示順便說一句 – oligofren 2014-06-26 14:14:56

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

然後,你可以簡單地訪問值像這樣:

  • 在配置文件(S)

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

我用鑰匙options這裏只是爲了符合慣例線,但只要你還記得不註冊任務命名爲'options',或者你可以使用任何無論你使用的關鍵:)