如何遍历数组和 运行 G运行t 任务将数组中的每个值作为 G运行t 选项传递

How to loop through an array and run a Grunt task passing each value in the array as a Grunt option

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

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

还有另一个变量:

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

这个值在我的 g运行t 文件的不同地方使用,用于确定某些资产的路径等。

长话短说,我运行以下命令为单个主题编译资产:

grunt compile --theme=theme2

我正在寻找一种方法来循环遍历主题数组和 运行 compile g运行t 任务以及适当的 grunt.option。本质上,我想要实现的目标相当于:

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

任务几乎立即完成并显示 "success" 消息,但它似乎没有执行任何操作。

我尝试的最后一件事与上面的类似,除了我尝试使用异步:

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

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

感谢您的帮助

我认为你的问题是你的个人编译任务在 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'。按照我构建我的方式回答,配置中不能使用theme

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

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

我们需要通过用模板字符串替换 theme 来更新我们的配置。例如:

dest: '<%= theme %>/app.js'

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

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

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

在您的 compile 任务中,您可以将 currentTheme 传递给对正常任务使用 this.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` 
});

对我使用 for each 从来没有用过,但这确实基于来自 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'
        }]
    }},