如何遍历数组并运行Grunt任务,将数组中的每个值作为Grunt选项传递

时间:2016-06-09 00:15:12

标签: javascript gruntjs frontend

我有一个类似于以下的数组:

var themes = grunt.option('themes') || [
    'theme1',
    'theme2',
    'theme3'
];

另一个变量:

var theme = grunt.option('theme') || 'theme1';

此值用于我的grunt文件中的各个位置,用于确定某些资源的路径等。

简而言之,我运行以下命令来编译单个主题的资产:

grunt compile --theme=theme2

我正在寻找一种循环遍历主题数组的方法,并使用适当的grunt.option运行compile grunt任务。从本质上讲,我期望实现的目标与此相当:

grunt compile --theme=theme1 && grunt compile --theme=theme2 && grunt compile --theme=theme3

我尝试了以下内容:

grunt.registerTask('compile:all', function() {
    themes.forEach(function(currentTheme) {
        grunt.option('theme', currentTheme);
        grunt.task.run('compile');
    });
});

这会使compile任务运行适当的次数,但theme选项似乎无法设置。所以我的Scss文件生成了,但它们都是空的。

我也试过这个:

grunt.registerTask('compile:all', function() {
    themes.forEach(function(currentTheme) {
        grunt.util.spawn({
            grunt : true,
            args  : ['compile', '--theme=' + currentTheme]
        });
    });
});

这项任务几乎立即完成并取得了成功"消息,但它似乎没有做任何事情。

我尝试过的最后一件事情与上述类似,只是我尝试使用异步:

grunt.registerTask('compile:all', function() {
    themes.forEach(function(currentTheme) {
        var done = grunt.task.current.async();
        grunt.util.spawn({
            grunt : true,
            args  : ['compile', '--theme=' + currentTheme]
        }, done);
    });
});

但是这个任务失败了。我不确定自己哪里出错了,

感谢您的帮助

3 个答案:

答案 0 :(得分:4)

我认为你的问题是你的个人编译任务在grunt.task.run('compile');排队等待,但是,当他们执行时,你的themes.forEach循环已经完成,theme选项已经完成设置为themes中的最后一个值。

我认为你需要注册一个单独的任务,负责设置运行编译任务的theme选项

grunt.registerTask('compile_theme', function (theme) {
    grunt.option('theme', theme);
    grunt.task.run('compile');
});

您可以针对每个主题在compile:all任务中将此任务排入队列:

themes.forEach(function(currentTheme) {
    grunt.task.run('compile_theme:' + currentTheme);
});

如果您希望能够在命令行中指定要编译的主题,则需要更新compile:all任务以读取所有--theme=参数并强制该值为数组:

grunt.registerTask('compile:all', function () {
    var compileThemes = grunt.option('theme') || 'theme1';

    if (grunt.util.kindOf(compileThemes) === 'string') {
        compileThemes = [compileThemes];
    }

    compileThemes.forEach(function(currentTheme) {
        grunt.task.run('compile_theme:' + currentTheme);
    });
});

您可以按如下方式调用命令:

grunt compile:all // compiles 'theme1'
grunt compile:all --theme=theme2 // compiles 'theme2'
grunt compile:all --theme=theme2 --theme=theme3 // compiles 'theme2' and 'theme3'

注意:您可能希望此时重命名compile:all任务,因为它不再必须编译所有主题。

修改

它无效,因为我们期待theme选项过多。我们正在尝试使用它来获取在命令行中输入的主题,以便在我们的配置中动态组合值(例如,dest: theme + '/app.js'。通过我构建答案的方式,{ {1}}无法在配置中使用。

我会使用将在配置中使用的theme配置变量。这意味着更新theme任务:

compile_theme

我们需要通过替换grunt.registerTask('compile_theme', function (theme) { grunt.config('theme', theme); grunt.task.run('compile'); }); 的模板字符串来更新我们的配置。例如:

theme

答案 1 :(得分:1)

如果要使用forEach方法构建一系列任务,请将任务推送到任务数组,而不是在forEach块中运行:

grunt.registerTask('buildAll', function() {
    var tasks = [];
    themes.forEach(function(currentTheme) {
        tasks.push('compile:' + currentTheme);
    });

    grunt.tasks.run(tasks);
});

compile任务中,您可以使用currentThemethis.args[0]传递给正常任务,或将this.target传递给多任务:

grunt.registerTask('compile', function() {
    var theme = this.args[0];  // sets local variable for use within task.
    grunt.option('theme', this.args[0]);  //sets option that can be referenced within this instance of `compile` 
});

答案 2 :(得分:1)

使用每个从未为我工作,但这确实是基于来自grunt的这个帮助文档: https://gruntjs.com/creating-tasks#multi-tasks

我将列表添加到initConfig,即

grunt.initConfig({
    run_themes: {
        theme1: 'sdi',
        theme2: 'syd',
        theme3: 'phl'
    }});

然后:

//register task to loop through the themes
grunt.task.registerMultiTask('run_themes', 'Compile themes.', function() {
    //grunt.themes.writeln(this.target + ': ' + this.data);
    grunt.log.writeln(this.target + ': ' + this.data);
    grunt.option('theme', this.data);
    grunt.task.run('sass');
});

我的sass定义使用这样的grunt.option(' theme')将相同编译的css的副本放在每个主题目录中,如sdi / default / ... syd / default。 .. phl / default ...

// compile our sass to css
sass: {
    // sass compilation for "dev", unminified files
    dev: {
        options: {
            style: 'expanded'
        },
        files: [{
            expand: true,
            cwd:'shared-resources/css/sass',
            src: ['*.scss', 'standalone/*.scss'],
            dest: "../<%= grunt.option('theme') %>/default/template-resources/css/dev",
            ext: '.css'
        }]
    }},