Grunt 配置文件编写技巧及示范
受益于grunt这么久,继续分享关于grunt的一些技巧。grunt确实是前端项目中不可或缺的提升效率的工具。第一次接触grunt是在去年7月份,开始有接触LESS、Coffee Script的等需要编译的模板才能使用的,所以grunt就有了很大的用处。当然除了编译,还有一部分的工作就是压缩,grunt常用的任务就是压缩JS、CSS,检查语法错误,同时也可以保证质量压缩图片(删除图片多余信息)。
使用起来也很简单,基于node,所以我们就可以通过js来控制这些文件。唯一需要做的是编写配置文件,做一套适合我们项目的编译系统。除此之外,另一个很方便的功能就是grunt能够通过监听文件变化(创建、删除、保存)来执行相应的任务。在初次学习grunt的配置的时候,踩过许多坑,之前也写过两篇关于grunt的文章,所以这里就写下Grunt的配置写法,具体为何那么写以及需要注意的点已经在代码里面表明清楚。
示范
写法仅供参考,具体请结合自己的项目编写配置。
- module.exports = function (grunt) {
- // 构建配置任务
- grunt.initConfig({
- //读取package.json的内容,形成个json数据
- pkg: grunt.file.readJSON('package.json'),
- // 复制
- copy: {
- // 指定子任务,调用可以是grunt copy(执行copy里面的全部任务),grunt copy:build(执行copy里面的build任务)
- build: {
- cwd: 'js', //指向的目录是相对的,全称Change Working Directory更改工作目录
- src: ['**'], //指向源文件,**是一个通配符,用来匹配Grunt任何文件
- dest: 'images', //用来输出结果任务
- expand: true //expand参数为true来启用动态扩展,涉及到多个文件处理需要开启
- },
- // 注:如果src: [ '**', '!**/*.styl' ],表示除去.styl文件,!在文件路径的开始处可以防止Grunt的匹配模式
- },
- // 清除
- clean: {
- build: {
- src: ['css/**/*.*']
- },
- },
- less: {
- dynamic_mappings: {
- files: [{
- expand: true, // Enable dynamic expansion.
- cwd: 'build/less', // Src matches are relative to this path.
- src: ['**/*.less', '!**/header.less', '!**/sidebar.less', '!**/footer.less', '!**/reset.less', '!**/layout.less', '!**/nprogress.less', '!**/post.less', '!**/single.less'], // Actual pattern(s) to match.
- dest: 'css', // Destination path prefix.
- ext: '.css', // Dest filepaths will have this extension.
- }],
- },
- },
- // CSS压缩
- cssmin: {
- build: {
- expand: true,
- cwd: 'css/',
- src: ['*.css', '!*.min.css'],
- dest: 'css/',
- ext: '.css'
- }
- },
- // 压缩js
- uglify: {
- // 基本压缩(用于不常修改的文件)
- build: {
- files: [{
- expand: true,
- cwd: 'build/js',
- src: ['*.js', '!**/component.js', '!**/jquery.js', '!**/html5.js'],
- dest: 'js/'
- }],
- },
- // public(常修改维护的文件)
- publicJs: {
- files: {
- 'js/public.js': ['build/js/public.js']
- }
- },
- // 组件压缩(组件级别,一般仅压缩一次)
- component: {
- options: {
- mangle: false // false表示关闭短命名方式压缩。如果文件要共享到另一个项目中,会带来问题,因为名称已改变
- },
- files: {
- 'js/component.js': ['build/js/component/piano_storage.js']
- },
- },
- },
- // JS语法检查
- jshint: {
- all: ['js/*.js'],
- },
- // 监听(监测到文件改变时执行对应任务)
- watch: {
- stylesheets: {
- files: 'build/less/*.less',
- tasks: ['stylesheets']
- },
- publicJs: {
- files: 'build/js/public.js',
- tasks: ['uglify:publicJs'],
- },
- scripts: {
- files: ['build/js/*.js', '!build/js/**/public.js'],
- tasks: ['uglify:build'],
- },
- componentJS: {
- files: ['build/js/component/*.js'],
- tasks: ['uglify:component'],
- }
- },
- // initConfig结尾
- });
- // 加载任务-分开加载
- grunt.loadNpmTasks("grunt-contrib-copy");
- grunt.loadNpmTasks("grunt-contrib-less");
- grunt.loadNpmTasks("grunt-contrib-jshint");
- grunt.loadNpmTasks("grunt-contrib-uglify");
- grunt.loadNpmTasks("grunt-contrib-watch");
- grunt.loadNpmTasks("grunt-contrib-clean");
- grunt.loadNpmTasks("grunt-contrib-cssmin");
- // 把grunt-contrib插件全部一次性加载
- // grunt.loadNpmTasks('grunt-contrib');
- // grunt.event.on('watch', function(action, filepath) {
- // grunt.config(['uglify', 'build'], filepath);
- // });
- grunt.event.on('watch', function (action, filepath) {
- grunt.config(['jshint', 'all'], filepath);
- });
- // 自定义任务
- // 作用:将以上众多子任务和在一起,便于手工运行或定义watch的任务
- // 处理CSS
- grunt.registerTask(
- 'stylesheets',
- 'Compiles the stylesheets.',
- // [ 'less' ]
- ['less', 'cssmin']
- );
- // 处理JS
- grunt.registerTask(
- 'scripts',
- 'Compiles the JavaScript files.',
- ['uglify:publicJs']
- );
- // 处理public
- grunt.registerTask(
- 'publicJs',
- 'Compiles the JavaScript files.',
- ['uglify:publicJs']
- );
- // componentJS
- grunt.registerTask(
- 'componentJS',
- 'Compiles the JavaScript files.',
- ['uglify:componentJS']
- );
- // 创建工程
- grunt.registerTask(
- 'build', //任务名称
- 'Compiles all of the assets and copies the files to the build directory.', //任务描述
- ['clean', 'copy', 'stylesheets', 'scripts', 'jade'] //将要运行的任务数组,按顺序执行
- );
- // 默认工程
- grunt.registerTask(
- 'default',
- 'Watches the project for changes, automatically builds them and runs a server.',
- ['build', 'connect', 'watch']
- );
- // default任务运行build创建一个初始的build,然后它开始连接服务器,最后它会运行watch,监测文件变化和重新构建。
- // 因为watch一直在运行,所以服务器一直在运行。在你的控制台上运行grunt,然后到http://localhost:4000查看你的项目。
- //modules结尾
- };
方案
在编写Grunt配置文件中,出现过一些问题,下面列一下
1. 各个插件的写法
因为插件众多,而各插件的写法也不一致,而且插件也都是英文的,所以读起来略繁琐。但是我们能做的就是在readme.md中查看每个用到的插件的语法,多试几个例子就好了。
2. 插件加载问题
因为Grunt是基于node的,所以加载插件的时候,我们不需要指定具体的路径,只需要放在node_modules文件夹下,嵌套多深也不要紧,只要是在node_modules里面就行。因为github上有这么一个项目grunt-contrib是收集了基本上常用到的Grunt插件,刚开始接触Grunt的时候,不知道选择什么插件,可以这样clone引用。但是会带来一个效率的问题,引用的时候:grunt.loadNpmTasks(‘grunt-contrib’);,因为涉及到的文件(文件夹)过多,会带来效率上的问题。所以仅需要当加载我们需要的插件就好。Grunt常用插件介绍:http://www.xuanfengge.com/grunt-commonly-used-plug-in-introduced.html
3. watch任务问题
watch给我们带来了很多方便,但是有时候也是个累赘。虽然说Grunt基于node,执行效率比Ant高很多,但是随着项目的庞大,文件的增多,简单的watch任务会使得每改动一次文件,都会编译所有同类型的文件,这相当的不需要。不过我们也不能watch单个文件,没有这样的写法,也不能写死(单个文件都写配置)。所以我们就需要根据文件改动编译次数,分成不同类型的任务。很少改动的直接不watch,转为手动编译就好
4. 涉及多文件时出错
提示错误:Source file “xxx.less” not found,普通写法对单个文件的编译没问题,但是涉及到多文件多目录的时候,就需要加上配置:expand: true
5. Grunt是不是最好的自动化工具
答案移至上一篇文章,Grunt自动化的前端项目构建工具:http://www.xuanfengge.com/grunt-front-end-project-build-automation-tools.html
另外,百度也有个前端集成解决方案:http://fis.baidu.com/
PS:本文摘自http://www.xuanfengge.com/grunt-profile-writing-tips-and-demonstrations-2.html 得益于此篇文章,已经在公司项目中使用了grunt,感觉不错,在此mark一下,比之前使用webstorm集成yui compressor要灵活的多
posted on 2015-06-23 18:08 shirleyqin216 阅读(173) 评论(0) 收藏 举报
浙公网安备 33010602011771号