Grunt是一个JavaScript任务运行器
Grunt基于Node.js,用JS 开发,这样就可以借助Node.js实现跨系统跨平台的桌面端的操作,例如文件操作等等。此外,Grunt以及它的插件们,都作为一个包,可以用 NPM 安装进行管理。
古老的构建工具,基本很少用了
操作步骤
npm install -g grunt-cli 安装grunt的命令行工具
npm init 生成package.json文件
npm install grunt --save-dev 安装grunt并加入到依赖
npm install --save-dev grunt-contrib-concat grunt-contrib-jshint grunt-contrib-sass grunt-contrib-uglify grunt-contrib-watch grunt-contrib-connect 安装常用插件并加入到依赖
其中 :
合并文件:grunt-contrib-concat
语法检查:grunt-contrib-jshint
Scss 编译:grunt-contrib-sass
压缩文件:grunt-contrib-uglify
监听文件变动:grunt-contrib-watch
建立本地服务器:grunt-contrib-connect
angular 缓存模板 : grunt-angular-templates
复制文件 : grunt-contrib-copy
删除文件 : grunt-contrib-clean
压缩以及合并CSS文件 : grunt-contrib-cssmin
图像压缩模块 : grunt-contrib-imagemin主目录下创建Gruntfile.js,并进行配置
输入grunt执行default,或 grunt 对应名 执行对应操作
js压缩uglify示例:
module.exports = function(grunt) {
// 配置任务
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),//固定写法
uglify: {
options: {//通用配置(会被私有配置覆盖)
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
footer:'\n/*! 我是footer */'
},
builda: {//按原目录批量压缩
expand:true,//允许使用占位符*代替其他字符
cwd:'oldjs',//只压缩该目录下的文件
src: '**/*.js',//**表示任意包括/和空,因此可以用于表示多层文件
dest: 'newjs',//目标文件夹
ext:'.min.js'//压缩文件后缀名
},
buildb:{
options:{//私有配置
mangle:false,//不进行代码混淆
banner:'//hello nihao\n'
},
files:{
'out/out.js':['jss/**/*.js','src/hello.js']//合并压缩
}
}
}
});
//加载插件
grunt.loadNpmTasks('grunt-contrib-uglify');//加载插件
//任务注册
grunt.registerTask('aa', ['uglify:builda']);
grunt.registerTask('bb', ['uglify:buildb']);//输入grunt bb则运行uglify中的buildb方法
grunt.registerTask('default', ['uglify']);//输入grunt 即可运行整个uglify
};
熊猫保保
'use strict';
module.exports = function (grunt) {
grunt.initConfig({
//jshint
jshint: {
all: [
'anniversary/js/controllers**.js',
],
options: {
jshintrc: true
}
},
//清空 .build目录
clean: ['.build/'],
//将所有模版文件加入缓存
ngtemplates: {
pandaTemplates: {
src: ['commonPartials/**/*.html', 'panda/partials/**/**.html'],
dest: 'panda/js/templates.js',
options: {
prefix: '/',
htmlmin: {
collapseWhitespace: true,
collapseBooleanAttributes: true
},
standalone: true
}
},
productsTemplates: {
src: ['commonPartials/**/*.html', 'products/partials/**/**.html'],
dest: 'products/js/templates.js',
options: {
prefix: '/',
htmlmin: {
collapseWhitespace: true,
collapseBooleanAttributes: true
},
standalone: true
}
},
weaselTemplates: {
src: ['commonPartials/**/*.html', 'weasel/partials/**/**.html'],
dest: 'weasel/js/templates.js',
options: {
prefix: '/',
htmlmin: {
collapseWhitespace: true,
collapseBooleanAttributes: true
},
standalone: true
}
},
okpandaTemplates: {
src: ['okpanda/partials/**/**.html'],
dest: 'okpanda/js/templates.js',
options: {
prefix: '/',
htmlmin: {
collapseWhitespace: true,
collapseBooleanAttributes: true
},
standalone: true
}
},
ruihengTemplates: {
src: ['ruiheng/partials/**/**.html'],
dest: 'ruiheng/js/templates.js',
options: {
prefix: '/',
htmlmin: {
collapseWhitespace: true,
collapseBooleanAttributes: true
},
standalone: true
}
}, activityTemplates: {
src: ['activity/partials/**/**.html'],
dest: 'activity/js/templates.js',
options: {
prefix: '/',
htmlmin: {
collapseWhitespace: true,
collapseBooleanAttributes: true
},
standalone: true
}
}, claimTemplates: {
src: ['claim/partials/**/**.html'],
dest: 'claim/js/templates.js',
options: {
prefix: '/',
htmlmin: {
collapseWhitespace: true,
collapseBooleanAttributes: true
},
standalone: true
}
}, vehicleTemplates: {
src: ['vehicle/partials/**/**.html'],
dest: 'vehicle/js/templates.js',
options: {
prefix: '/',
htmlmin: {
collapseWhitespace: true,
collapseBooleanAttributes: true
},
standalone: true
}
},
reservationTemplates: {
src: ['reservation/partials/**/**.html'],
dest: 'reservation/js/templates.js',
options: {
prefix: '/',
htmlmin: {
collapseWhitespace: true,
collapseBooleanAttributes: true
},
standalone: true
}
}
},
//复制文件到.build目录
copy: {
main: {
files: [
{
expand: true,
cwd: './',
src: ['index.html', 'favicon.ico', 'spa.appcache', 'version.json', 'images/**/*', 'commonPartials/**/*'],
dest: '.build/'
}, {
expand: true,
cwd: './',
src: ['products/index.html', 'products/iframe.html', 'products/images/**', 'products/js/app.js'],
dest: '.build/'
}, {
expand: true,
cwd: './',
src: ['panda/*.html', 'panda/images/**', 'panda/js/app.js'],
dest: '.build/'
}, {
expand: true,
cwd: './',
src: ['weasel/index.html', 'weasel/images/**', 'weasel/js/app.js'],
dest: '.build/'
}, {
expand: true,
cwd: './',
src: ['okpanda/index.html', 'okpanda/images/**', 'okpanda/js/app.js'],
dest: '.build/'
}, {
expand: true,
cwd: './',
src: ['ruiheng/index.html', 'ruiheng/images/**', 'ruiheng/js/app.js'],
dest: '.build/'
}, {
expand: true,
cwd: './',
src: ['activity/index.html', 'activity/images/**', 'activity/js/app.js'],
dest: '.build/'
}, {
expand: true,
cwd: './',
src: ['claim/index.html', 'claim/images/**', 'claim/js/app.js'],
dest: '.build/'
}, {
expand: true,
cwd: './',
src: ['vehicle/index.html', 'vehicle/images/**', 'vehicle/js/app.js'],
dest: '.build/'
}, {
expand: true,
cwd: './',
src: ['reservation/index.html', 'reservation/images/**', 'reservation/js/app.js'],
dest: '.build/'
}
]
}
},
//将所有js压缩成一个
uglify: {
options: {
mangle: true
},
products: {
files: {
'.build/products/js/app.js': ['js/**/*.js', '.build/products/js/app.js', 'products/js/**/*.js', '!products/js/app.js', '!products/js/controllers.js']
}
},
panda: {
files: {
'.build/panda/js/app.js': ['js/**/*.js', '.build/panda/js/app.js', 'panda/js/**/*.js', '!panda/js/app.js'],
}
},
weasel: {
files: {
'.build/weasel/js/app.js': ['js/**/*.js', '.build/weasel/js/app.js', 'weasel/js/**/*.js', '!weasel/js/app.js']
}
},
okpanda: {
files: {
'.build/okpanda/js/app.js': ['js/**/*.js', '.build/okpanda/js/app.js', 'okpanda/js/**/*.js', '!okpanda/js/app.js']
}
},
ruiheng: {
files: {
'.build/ruiheng/js/app.js': ['js/**/*.js', '.build/ruiheng/js/app.js', 'ruiheng/js/**/*.js', '!ruiheng/js/app.js', '!ruiheng/js/componentJS/**']
}
}
,
activity: {
files: {
'.build/activity/js/app.js': ['js/**/*.js', '.build/activity/js/app.js', 'activity/js/**/*.js', '!activity/js/app.js', '!activity/js/componentJS/**']
}
}, claim: {
files: {
'.build/claim/js/app.js': ['js/**/*.js', '.build/claim/js/app.js', 'claim/js/**/*.js', '!claim/js/app.js', '!claim/js/componentJS/**']
}
}, vehicle: {
files: {
'.build/vehicle/js/app.js': ['js/**/*.js', '.build/vehicle/js/app.js', 'vehicle/js/**/*.js', '!vehicle/js/app.js', '!vehicle/js/componentJS/**']
}
}, reservation: {
files: {
'.build/reservation/js/app.js': ['js/**/*.js', '.build/reservation/js/app.js', 'reservation/js/**/*.js', '!reservation/js/app.js', '!reservation/js/componentJS/**']
}
}
},
stripDebug: {
dist: {
files: {
'.build/products/js/app.js': '.build/products/js/app.js',
'.build/panda/js/app.js': '.build/panda/js/app.js',
'.build/weasel/js/app.js': '.build/weasel/js/app.js',
'.build/okpanda/js/app.js': '.build/okpanda/js/app.js',
'.build/ruiheng/js/app.js': '.build/ruiheng/js/app.js',
'.build/activity/js/app.js': '.build/activity/js/app.js',
'.build/claim/js/app.js': '.build/claim/js/app.js',
'.build/vehicle/js/app.js': '.build/vehicle/js/app.js',
'.build/reservation/js/app.js': '.build/reservation/js/app.js'
}
}
},
//压缩css文件
cssmin: {
options: {
shorthandCompacting: false,
roundingPrecision: -1
},
target: {
files: {
'.build/panda/css/app.css': ['panda/css/*.css', 'css/*.css'],
'.build/products/css/app.css': ['products/css/*.css', 'css/*.css'],
'.build/weasel/css/app.css': ['weasel/css/*.css', 'css/*.css'],
'.build/okpanda/css/app.css': ['okpanda/css/*.css', 'css/*.css'],
'.build/ruiheng/css/app.css': ['ruiheng/css/*.css', 'css/*.css'],
'.build/activity/css/app.css': ['activity/css/*.css', 'css/*.css'],
'.build/claim/css/app.css': ['claim/css/*.css', 'css/*.css'],
'.build/vehicle/css/app.css': ['vehicle/css/*.css', 'css/*.css'],
'.build/reservation/css/app.css': ['reservation/css/*.css', 'css/*.css']
}
}
},
concat: {
panda: {
files: {
'.build/panda/js/app.js': ['.build/panda/js/app.js'],
'.build/panda/index.html': ['.build/panda/index.html']
},
options: {
process: function (src, filepath) {
if (filepath.endsWith('app.js')) {
src = src.replace('$compileProvider.debugInfoEnabled(true);', '$compileProvider.debugInfoEnabled(false);');
return src.replace('/*templates-here*/', "'pandaTemplates',");
}
if (filepath.endsWith('index.html')) {
var start = src.indexOf('<!--start customize js-->') + '<!--start customize js-->'.length;
var end = src.indexOf('<!--end customize js-->');
src = src.replace(src.substring(start, end), '<script src="js/app.js?v=' + (new Date()).getTime() + '"></script>');
start = src.indexOf('<!--start customize css-->') + '<!--start customize css-->'.length;
end = src.indexOf('<!--end customize css-->');
return src.replace(src.substring(start, end), '<link href="css/app.css?="' + (new Date()).getTime() + ' rel="stylesheet">');
}
}
}
},
products: {
files: {
'.build/products/js/app.js': ['.build/products/js/app.js'],
'.build/products/index.html': ['.build/products/index.html']
},
options: {
process: function (src, filepath) {
if (filepath.endsWith('app.js')) {
src = src.replace('$compileProvider.debugInfoEnabled(true);', '$compileProvider.debugInfoEnabled(false);');
return src.replace('/*templates-here*/', "'productsTemplates',");
}
if (filepath.endsWith('index.html')) {
var start = src.indexOf('<!--start customize js-->') + '<!--start customize js-->'.length;
var end = src.indexOf('<!--end customize js-->');
src = src.replace(src.substring(start, end), '<script src="js/app.js?v=' + (new Date()).getTime() + '"></script>');
start = src.indexOf('<!--start customize css-->') + '<!--start customize css-->'.length;
end = src.indexOf('<!--end customize css-->');
return src.replace(src.substring(start, end), '<link href="css/app.css?="' + (new Date()).getTime() + ' rel="stylesheet">');
}
}
}
},
weasel: {
files: {
'.build/weasel/js/app.js': ['.build/weasel/js/app.js'],
'.build/weasel/index.html': ['.build/weasel/index.html']
},
options: {
process: function (src, filepath) {
if (filepath.endsWith('app.js')) {
src = src.replace('$compileProvider.debugInfoEnabled(true);', '$compileProvider.debugInfoEnabled(false);');
return src.replace('/*templates-here*/', "'weaselTemplates',");
}
if (filepath.endsWith('index.html')) {
var start = src.indexOf('<!--start customize js-->') + '<!--start customize js-->'.length;
var end = src.indexOf('<!--end customize js-->');
src = src.replace(src.substring(start, end), '<script src="js/app.js?v=' + (new Date()).getTime() + '"></script>');
start = src.indexOf('<!--start customize css-->') + '<!--start customize css-->'.length;
end = src.indexOf('<!--end customize css-->');
return src.replace(src.substring(start, end), '<link href="css/app.css?="' + (new Date()).getTime() + ' rel="stylesheet">');
}
}
}
},
okpanda: {
files: {
'.build/okpanda/js/app.js': ['.build/okpanda/js/app.js'],
'.build/okpanda/index.html': ['.build/okpanda/index.html']
},
options: {
process: function (src, filepath) {
if (filepath.endsWith('app.js')) {
src = src.replace('$compileProvider.debugInfoEnabled(true);', '$compileProvider.debugInfoEnabled(false);');
return src.replace('/*templates-here*/', "'okpandaTemplates',");
}
if (filepath.endsWith('index.html')) {
var start = src.indexOf('<!--start customize js-->') + '<!--start customize js-->'.length;
var end = src.indexOf('<!--end customize js-->');
src = src.replace(src.substring(start, end), '<script src="js/app.js?' + (new Date()).getTime() + '"></script>');
start = src.indexOf('<!--start customize css-->') + '<!--start customize css-->'.length;
end = src.indexOf('<!--end customize css-->');
return src.replace(src.substring(start, end), '<link href="css/app.css?="' + (new Date()).getTime() + ' rel="stylesheet">');
}
}
}
},
ruiheng: {
files: {
'.build/ruiheng/js/app.js': ['.build/ruiheng/js/app.js'],
'.build/ruiheng/index.html': ['.build/ruiheng/index.html']
},
options: {
process: function (src, filepath) {
if (filepath.endsWith('app.js')) {
src = src.replace('$compileProvider.debugInfoEnabled(true);', '$compileProvider.debugInfoEnabled(false);');
return src.replace('/*templates-here*/', "'ruihengTemplates',");
}
if (filepath.endsWith('index.html')) {
var start = src.indexOf('<!--start customize js-->') + '<!--start customize js-->'.length;
var end = src.indexOf('<!--end customize js-->');
src = src.replace(src.substring(start, end), '<script src="js/app.js?' + (new Date()).getTime() + '"></script>');
start = src.indexOf('<!--start customize css-->') + '<!--start customize css-->'.length;
end = src.indexOf('<!--end customize css-->');
return src.replace(src.substring(start, end), '<link href="css/app.css?="' + (new Date()).getTime() + ' rel="stylesheet">');
}
}
}
},
activity: {
files: {
'.build/activity/js/app.js': ['.build/activity/js/app.js'],
'.build/activity/index.html': ['.build/activity/index.html']
},
options: {
process: function (src, filepath) {
if (filepath.endsWith('app.js')) {
src = src.replace('$compileProvider.debugInfoEnabled(true);', '$compileProvider.debugInfoEnabled(false);');
return src.replace('/*templates-here*/', "'activityTemplates',");
}
if (filepath.endsWith('index.html')) {
var start = src.indexOf('<!--start customize js-->') + '<!--start customize js-->'.length;
var end = src.indexOf('<!--end customize js-->');
src = src.replace(src.substring(start, end), '<script src="js/app.js?' + (new Date()).getTime() + '"></script>');
start = src.indexOf('<!--start customize css-->') + '<!--start customize css-->'.length;
end = src.indexOf('<!--end customize css-->');
return src.replace(src.substring(start, end), '<link href="css/app.css?="' + (new Date()).getTime() + ' rel="stylesheet">');
}
}
}
}, claim: {
files: {
'.build/claim/js/app.js': ['.build/claim/js/app.js'],
'.build/claim/index.html': ['.build/claim/index.html']
},
options: {
process: function (src, filepath) {
if (filepath.endsWith('app.js')) {
src = src.replace('$compileProvider.debugInfoEnabled(true);', '$compileProvider.debugInfoEnabled(false);');
return src.replace('/*templates-here*/', "'claimTemplates',");
}
if (filepath.endsWith('index.html')) {
var start = src.indexOf('<!--start customize js-->') + '<!--start customize js-->'.length;
var end = src.indexOf('<!--end customize js-->');
src = src.replace(src.substring(start, end), '<script src="js/app.js?' + (new Date()).getTime() + '"></script>');
start = src.indexOf('<!--start customize css-->') + '<!--start customize css-->'.length;
end = src.indexOf('<!--end customize css-->');
return src.replace(src.substring(start, end), '<link href="css/app.css?="' + (new Date()).getTime() + ' rel="stylesheet">');
}
}
}
},vehicle: {
files: {
'.build/vehicle/js/app.js': ['.build/vehicle/js/app.js'],
'.build/vehicle/index.html': ['.build/vehicle/index.html']
},
options: {
process: function (src, filepath) {
if (filepath.endsWith('app.js')) {
src = src.replace('$compileProvider.debugInfoEnabled(true);', '$compileProvider.debugInfoEnabled(false);');
return src.replace('/*templates-here*/', "'vehicleTemplates',");
}
if (filepath.endsWith('index.html')) {
var start = src.indexOf('<!--start customize js-->') + '<!--start customize js-->'.length;
var end = src.indexOf('<!--end customize js-->');
src = src.replace(src.substring(start, end), '<script src="js/app.js?' + (new Date()).getTime() + '"></script>');
start = src.indexOf('<!--start customize css-->') + '<!--start customize css-->'.length;
end = src.indexOf('<!--end customize css-->');
return src.replace(src.substring(start, end), '<link href="css/app.css?="' + (new Date()).getTime() + ' rel="stylesheet">');
}
}
}
},
reservation: {
files: {
'.build/reservation/js/app.js': ['.build/reservation/js/app.js'],
'.build/reservation/index.html': ['.build/reservation/index.html']
},
options: {
process: function (src, filepath) {
if (filepath.endsWith('app.js')) {
src = src.replace('$compileProvider.debugInfoEnabled(true);', '$compileProvider.debugInfoEnabled(false);');
return src.replace('/*templates-here*/', "'reservationTemplates',");
}
if (filepath.endsWith('index.html')) {
var start = src.indexOf('<!--start customize js-->') + '<!--start customize js-->'.length;
var end = src.indexOf('<!--end customize js-->');
src = src.replace(src.substring(start, end), '<script src="js/app.js?' + (new Date()).getTime() + '"></script>');
start = src.indexOf('<!--start customize css-->') + '<!--start customize css-->'.length;
end = src.indexOf('<!--end customize css-->');
return src.replace(src.substring(start, end), '<link href="css/app.css?="' + (new Date()).getTime() + ' rel="stylesheet">');
}
}
}
}
},
compress: {
main: {
options: {
mode: 'gzip'
},
expand: true,
cwd: '.build/',
src: ['**/*.js'],
dest: '.build/',
ext: '.js.gz'
}
}
});
grunt.loadNpmTasks('grunt-angular-templates');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks("grunt-strip-debug");
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.registerTask('build', ['clean', 'ngtemplates', 'copy', 'concat', 'uglify', 'stripDebug', 'cssmin', 'compress']);
// grunt.registerTask('build', ['clean', 'ngtemplates', 'copy', 'concat', 'uglify', 'cssmin']);
// Register group tasks
//grunt.registerTask('build', [ 'jshint', 'less', 'i18n', 'copyto' ]);
};