Grunt 配置文件编写技巧及示范

 

受益于grunt这么久,继续分享关于grunt的一些技巧。grunt确实是前端项目中不可或缺的提升效率的工具。第一次接触grunt是在去年7月份,开始有接触LESS、Coffee Script的等需要编译的模板才能使用的,所以grunt就有了很大的用处。当然除了编译,还有一部分的工作就是压缩,grunt常用的任务就是压缩JS、CSS,检查语法错误,同时也可以保证质量压缩图片(删除图片多余信息)。

使用起来也很简单,基于node,所以我们就可以通过js来控制这些文件。唯一需要做的是编写配置文件,做一套适合我们项目的编译系统。除此之外,另一个很方便的功能就是grunt能够通过监听文件变化(创建、删除、保存)来执行相应的任务。在初次学习grunt的配置的时候,踩过许多坑,之前也写过两篇关于grunt的文章,所以这里就写下Grunt的配置写法,具体为何那么写以及需要注意的点已经在代码里面表明清楚。

示范

写法仅供参考,具体请结合自己的项目编写配置。

  1. module.exports = function (grunt) {
  2. // 构建配置任务
  3. grunt.initConfig({
  4. //读取package.json的内容,形成个json数据
  5. pkg: grunt.file.readJSON('package.json'),
  6.  
  7. // 复制
  8. copy: {
  9. // 指定子任务,调用可以是grunt copy(执行copy里面的全部任务),grunt copy:build(执行copy里面的build任务)
  10. build: {
  11. cwd: 'js', //指向的目录是相对的,全称Change Working Directory更改工作目录
  12. src: ['**'], //指向源文件,**是一个通配符,用来匹配Grunt任何文件
  13. dest: 'images', //用来输出结果任务
  14. expand: true //expand参数为true来启用动态扩展,涉及到多个文件处理需要开启
  15. },
  16. // 注:如果src: [ '**', '!**/*.styl' ],表示除去.styl文件,!在文件路径的开始处可以防止Grunt的匹配模式
  17. },
  18.  
  19. // 清除
  20. clean: {
  21. build: {
  22. src: ['css/**/*.*']
  23. },
  24. },
  25.  
  26. less: {
  27. dynamic_mappings: {
  28. files: [{
  29. expand: true, // Enable dynamic expansion.
  30. cwd: 'build/less', // Src matches are relative to this path.
  31. src: ['**/*.less', '!**/header.less', '!**/sidebar.less', '!**/footer.less', '!**/reset.less', '!**/layout.less', '!**/nprogress.less', '!**/post.less', '!**/single.less'], // Actual pattern(s) to match.
  32. dest: 'css', // Destination path prefix.
  33. ext: '.css', // Dest filepaths will have this extension.
  34. }],
  35. },
  36. },
  37.  
  38. // CSS压缩
  39. cssmin: {
  40. build: {
  41. expand: true,
  42. cwd: 'css/',
  43. src: ['*.css', '!*.min.css'],
  44. dest: 'css/',
  45. ext: '.css'
  46. }
  47. },
  48.  
  49. // 压缩js
  50. uglify: {
  51. // 基本压缩(用于不常修改的文件)
  52. build: {
  53. files: [{
  54. expand: true,
  55. cwd: 'build/js',
  56. src: ['*.js', '!**/component.js', '!**/jquery.js', '!**/html5.js'],
  57. dest: 'js/'
  58. }],
  59. },
  60. // public(常修改维护的文件)
  61. publicJs: {
  62. files: {
  63. 'js/public.js': ['build/js/public.js']
  64. }
  65. },
  66. // 组件压缩(组件级别,一般仅压缩一次)
  67. component: {
  68. options: {
  69. mangle: false // false表示关闭短命名方式压缩。如果文件要共享到另一个项目中,会带来问题,因为名称已改变
  70. },
  71. files: {
  72. 'js/component.js': ['build/js/component/piano_storage.js']
  73. },
  74. },
  75. },
  76.  
  77. // JS语法检查
  78. jshint: {
  79. all: ['js/*.js'],
  80. },
  81.  
  82. // 监听(监测到文件改变时执行对应任务)
  83. watch: {
  84. stylesheets: {
  85. files: 'build/less/*.less',
  86. tasks: ['stylesheets']
  87. },
  88. publicJs: {
  89. files: 'build/js/public.js',
  90. tasks: ['uglify:publicJs'],
  91. },
  92. scripts: {
  93. files: ['build/js/*.js', '!build/js/**/public.js'],
  94. tasks: ['uglify:build'],
  95. },
  96. componentJS: {
  97. files: ['build/js/component/*.js'],
  98. tasks: ['uglify:component'],
  99. }
  100. },
  101.  
  102. // initConfig结尾
  103. });
  104.  
  105. // 加载任务-分开加载
  106. grunt.loadNpmTasks("grunt-contrib-copy");
  107. grunt.loadNpmTasks("grunt-contrib-less");
  108. grunt.loadNpmTasks("grunt-contrib-jshint");
  109. grunt.loadNpmTasks("grunt-contrib-uglify");
  110. grunt.loadNpmTasks("grunt-contrib-watch");
  111. grunt.loadNpmTasks("grunt-contrib-clean");
  112. grunt.loadNpmTasks("grunt-contrib-cssmin");
  113.  
  114. // 把grunt-contrib插件全部一次性加载
  115. // grunt.loadNpmTasks('grunt-contrib');
  116.  
  117. // grunt.event.on('watch', function(action, filepath) {
  118. // grunt.config(['uglify', 'build'], filepath);
  119. // });
  120. grunt.event.on('watch', function (action, filepath) {
  121. grunt.config(['jshint', 'all'], filepath);
  122. });
  123.  
  124. // 自定义任务
  125. // 作用:将以上众多子任务和在一起,便于手工运行或定义watch的任务
  126.  
  127. // 处理CSS
  128. grunt.registerTask(
  129. 'stylesheets',
  130. 'Compiles the stylesheets.',
  131. // [ 'less' ]
  132. ['less', 'cssmin']
  133. );
  134. // 处理JS
  135. grunt.registerTask(
  136. 'scripts',
  137. 'Compiles the JavaScript files.',
  138. ['uglify:publicJs']
  139. );
  140. // 处理public
  141. grunt.registerTask(
  142. 'publicJs',
  143. 'Compiles the JavaScript files.',
  144. ['uglify:publicJs']
  145. );
  146. // componentJS
  147. grunt.registerTask(
  148. 'componentJS',
  149. 'Compiles the JavaScript files.',
  150. ['uglify:componentJS']
  151. );
  152.  
  153. // 创建工程
  154. grunt.registerTask(
  155. 'build', //任务名称
  156. 'Compiles all of the assets and copies the files to the build directory.', //任务描述
  157. ['clean', 'copy', 'stylesheets', 'scripts', 'jade'] //将要运行的任务数组,按顺序执行
  158. );
  159.  
  160. // 默认工程
  161. grunt.registerTask(
  162. 'default',
  163. 'Watches the project for changes, automatically builds them and runs a server.',
  164. ['build', 'connect', 'watch']
  165. );
  166. // default任务运行build创建一个初始的build,然后它开始连接服务器,最后它会运行watch,监测文件变化和重新构建。
  167. // 因为watch一直在运行,所以服务器一直在运行。在你的控制台上运行grunt,然后到http://localhost:4000查看你的项目。
  168.  
  169. //modules结尾
  170. };

 

 方案

在编写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要灵活的多

原文链接:http://www.gbtags.com/gb/share/5552.htm

posted on 2015-06-23 18:08  shirleyqin216  阅读(173)  评论(0)    收藏  举报