这一节,我打算主要讲讲Gruntfile.js怎么去写。顺便搭建一个昨天说的用于实时编译coffee, less,并且打包压缩js,css文件的grunt。
说一下这一次的项目结构:
├── src
│ ├──index.html
│ ├── scripts
│ └── styles
└── utils
├── node_modules
│ ├── grunt
│ └── grunt-contrib-xxxx
├── Gruntfile.js
└── package.json
src是我开发的项目的目录,utils是grunt的目录。涉及到的package.json如下:
{
"name": "utils",
"version": "0.1.0",
"devDependencies": {
"grunt": "*",
"grunt-contrib-less": "*",
"grunt-contrib-coffee": "*",
"grunt-contrib-concat": "*",
"grunt-contrib-uglify": "*",
"grunt-contrib-watch": "*"
}
}
典型的模块写法:
module.exports = function(grunt) {
// config here
};
config需要写什么呢,我个人用到的是三部分:
格式如下:
grunt.initConfig({
});
grunt.initConfig
里面写什么呢,第一个,写pkg : grunt.file.readJSON('package.json'),
使得之后可以通过<% %>
获取package里的内容。
接下来,就是任务的定义了。具体什么任务,要看加载了什么任务包。用什么任务包,去plugin查查吧。我这里用的都是grunt-contrib-*
就是官方提供的。
比如grunt-contrib-less
任务包,命令可以如下:
less: {
compile: {
options: {},
files: {
'../src/styles/result.css': '../src/styles/source.less',
// '../src/styles/another.css': ['../src/styles/sources/*.less', '../src/styles/more/*.less']
}
},
glob_to_multiple: {
expand: true,
flatten: true,
cwd: '../src/styles/',
src: ['*.less'],
dest: '../src/styles/',
ext: '.css'
}
}
说明一下,如果不需要子命令。那么直接在less:{}
去写files等参数,调用也是直接grunt less
调用。但是,如果需要子命令,比如为了开发,发布时候做的不同处理。需要在less:{}
中再命名一个子命令subTaskName: {}
,这里的subTaskName
是随意取的。使用的时候,通过grunt less:subTaskName
使用。
搜索plugin查找你需要使用的任务包,通过npm install <module> --save-dev
来安装。-save-dev
参数自动维护package.json
文件。
安装modules之后,在Gruntfile.js
中,使用grunt.loadNpmTasks('grunt-contrib-less');
来加载。
通过grunt.registerTask('default', ['less']);
来命名,这里defalut表示grunt
。其实就是指grunt
, grunt default
和grunt less
命令一直。你可以修改defalut,然后配置不同的任务。
这里我给出一个我自己写的Gruntfile.js文件。欢迎大家fork。
module.exports = function(grunt) {
grunt.initConfig({
pkg : grunt.file.readJSON('package.json'),
coffee: {
compile: {
// 选项
options: {},
// 指定文件编译
files: {
// 1:1 compile
'../src/scripts/result.js': '../src/scripts/source.coffee',
// compile and concat into single file
// '../src/scripts/another.js': ['../src/scripts/sources/*.coffee', '../src/scripts/more/*.coffee']
}
},
// 实时编译,1:1
glob_to_multiple: {
expand: true,
flatten: true,
cwd: '../src/scripts/',
src: ['*.coffee'],
dest: '../src/scripts/',
ext: '.js'
// 后面还可以继续写cwd~ext内容
}
},
less: {
compile: {
options: {},
files: {
'../src/styles/result.css': '../src/styles/source.less',
// '../src/styles/another.css': ['../src/styles/sources/*.less', '../src/styles/more/*.less']
}
},
glob_to_multiple: {
expand: true,
flatten: true,
cwd: '../src/styles/',
src: ['*.less'],
dest: '../src/styles/',
ext: '.css'
}
},
// 合并文件
concat : {
css : {
files: {
// des: src对应关系
'../src/dest/result.css': ['../src/styles/**/*.css']
}
},
js : {
files: {
'../src/dest/result.js': ['../src/scripts/**/*.js']
}
}
},
// 压缩JS
uglify : {
options : {
banner : '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
build : {
src : '../src/dest/*.js',
dest : '../src/dest/result.min.js'
}
},
watch: {
// 写任务名称,然后写监控文件,使用的任务,
// 多个文件夹监听,要追个写出到files数组中
coffee: {
files: ['../src/scripts/*.coffee'],
tasks: ['coffee:glob_to_multiple']
},
less: {
files: ['../src/styles/*.less'],
tasks: ['less:glob_to_multiple']
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['coffee:glob_to_multiple', 'less:glob_to_multiple']);
};