我希望有一个包含2个任务的gruntfile:less(编译所有较少的文件)和watch(监听更改并重新编译已更改的文件)。
我有以下Gruntfile.js:
module.exports = function(grunt) {
var files = [
{
expand: true,
cwd: 'media/less',
src: ['*.less'],
dest: 'media/css/',
ext: '.css'
},
{
expand: true,
cwd: 'media/less/vendor',
src: ['*.less'],
dest: 'media/css/vendor/',
ext: '.css'
},
{
expand: true,
cwd: 'media/admin/less',
src: ['*.less'],
dest: 'media/admin/css/',
ext: '.css'
}
];
grunt.initConfig({
less: {
development: {
options: {
compress: false,
yuicompress: true,
optimization: 2
},
files: files
},
production: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: files
}
},
watch: {
styles: {
files: ['media/**/*.less'],
tasks: ['less:development'],
options: {
nospawn: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less:development']);
};
less
任务正确运行,没有任何问题。但是watch
任务会监听更改,但在更改一个文件时会重新编译所有文件。我怀疑它与我如何设置less
任务有关,因为我希望我的文件列表更少动态,而不是手动添加每个文件。
根据this answer grunt应该已经支持了这一点,但我不确定如何。
答案 0 :(得分:1)
使用watch
事件结束并覆盖files
任务的less
属性。这是我的最终代码:
module.exports = function(grunt) {
var files = [
{
expand: true,
cwd: 'media/less',
src: ['*.less'],
dest: 'media/css/',
ext: '.css',
extDot: 'last'
},
{
expand: true,
cwd: 'media/less/vendor',
src: ['*.less'],
dest: 'media/css/vendor/',
ext: '.css',
extDot: 'last'
},
{
expand: true,
cwd: 'media/admin/less',
src: ['*.less'],
dest: 'media/admin/css/',
ext: '.css',
extDot: 'last'
}
];
grunt.initConfig({
less: {
development: {
options: {
compress: false,
yuicompress: true,
optimization: 2
},
files: files
},
production: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: files
}
},
watch: {
styles: {
files: ['media/**/*.less'],
tasks: ['less:development'],
options: {
nospawn: true
}
}
}
});
grunt.event.on('watch', function(action, filepath){
// ignore include files, TODO: have naming convention
// if an include file has been changed, all files will be re-compiled
if(filepath.indexOf('.inc.') > -1)
return true;
// might not be the most efficient way to do this
var srcDir = filepath.split('/');
var filename = srcDir[srcDir.length - 1];
delete srcDir[srcDir.length - 1];
srcDir = srcDir.join('/');
var destDir = srcDir.replace(/less/g, 'css');
grunt.config('less.development.files', [{
src: filename,
dest: destDir,
expand: true,
cwd: srcDir,
ext: '.css',
extDot: 'last'
}]);
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less:development']);
};
答案 1 :(得分:0)
我不确定您对问题的当前标题的意思 Grunt只关注更改文件。你的意思是那是一个问题吗?这是watch
任务的预期行为,它将监视为更改指定的文件并运行您指定的任务 - 在本例中为LESS
编译。
我对您的文件进行了一些更改。其中一些是简化的,一些是改变的,保持脚本的灵活性和可扩展性。
首先通过运行:
安装underscore
作为依赖项
npm install underscore --save-dev
然后对Gruntfile.js
:
module.exports = function(grunt) {
var _ = require('underscore');
var files = {
app : {
'<%= path.styles.css %>/styles.css' : '<%= path.styles.less %>/*.less'
},
vendor : {
'<%= path.styles.css %>/styles-vendor.css' : '<%= path.styles.vendor %>/*.less'
},
admin : {
'<%= path.styles.css %>/styles-admin.css' : '<%= path.styles.admin %>/*.less'
}
}
function all() {
'use strict';
var allfiles = {},
i = {};
for (i in files) {
_.extend(allfiles, files[i]);
}
return allfiles;
}
grunt.initConfig({
path : {
media : 'media',
styles : {
css: 'media/css',
less: 'media/less',
admin: 'media/admin/less',
vendor: '<%= path.styles.less %>/vendor'
}
},
less: {
development: {
options: {
compress: false,
yuicompress: true,
optimization: 2
},
files: (all())
},
production: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: (all())
}
},
watch: {
styles: {
files: ['<%= path.media %>/**/*.less'],
tasks: ['less:development'],
options: {
nospawn: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
// run several tasks as default (handy for complex projects)
grunt.registerTask('dist', [ // run with 'grunt dist'
'less:production'
]);
grunt.registerTask('dev', [ // default, will run with 'grunt' only
'less:development'
]);
grunt.registerTask('default', 'dev');
};
如果您想要实际编译文件集单独(files.app
,files.vendor
&amp; files.admin
),您可能需要拆分更多的任务,如下:
less: {
app: {
options: {
compress: false,
yuicompress: true,
optimization: 2
},
files: files.app
},
vendor: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: files.vendor
},
admin: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: files.admin
},
development: {
options: {
compress: false,
yuicompress: true,
optimization: 2
},
files: (all())
},
production: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: (all())
}
},
watch: {
all: {
files: ['<%= path.media %>/**/*.less'],
tasks: ['less:development'],
options: {
nospawn: true
}
},
app : {
files: ['<%= path.styles.less %>/*.less'],
tasks: ['less:app'],
options: {
nospawn: true
}
},
vendor : {
files: ['<%= path.styles.vendor %>/*.less'],
tasks: ['less:vendor'],
options: {
nospawn: true
}
},
admin : {
files: ['<%= path.styles.admin %>/*.less'],
tasks: ['less:admin'],
options: {
nospawn: true
}
}
}
然后你可以运行其中任何一个:
grunt watch:app
grunt watch:vendor
grunt watch:admin
您可以随时选择直接运行任务:
grunt less:app
grunt less:vendor
grunt less:admin
希望这有帮助!请注意,我没有测试过这个。