如何遍历数组和 运行 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'
}]
}},
我有一个类似于下面的数组:
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'
}]
}},