前言

Grunt是一款前端构建工具,帮助我们自动化搭建前端工程。它可以实现自动对js、css、html文件的合并、压缩等一些列操作。Grunt有很多插件,每一款插件实现某个功能,你可以通过npm命名去下载插件,然后使用它们。关于grunt的使用以及配置,卤煮不打算在此介绍。本篇博文重点要讲的是如何快速开发一款自定义的grunt插件。因为卤煮在打包合并代码的时候发现了无法将html和js混合的文件进行压缩处理,为此卤煮也翻了很多资料,没查找到理想的解决方案。在山穷水复之时,硬着头皮自己开发了一个简单的插件。在这里分享出来给诸位,望对正在使用grunt构建工具的诸君能有所帮助。

创建插件

1通过 npm install -g grunt-init 命令安装 grunt-init 。

2通过 git clone git://github.com/gruntjs/grunt-init-gruntplugin.git ~/.grunt-init/gruntplugin 命令安装grunt插件模版。

3在一个空的目录中执行 grunt-init gruntplugin 。

4执行 npm install 命令以准备开发环境。

在执行到第三步的时候会出现若干选择让你填写,这些选项都是初始化插件时的配置选项。把你的插件名称和github替换本地地址填上外其他的都可以选择默认。然后我们得到了一个默认的插件模块工程目录。如下所示:

其中Gruntfile.js是当前模块需要的依赖,你需要的是在tasks中的js文件中编写自己的插件。

编写插件

一个插件是可以配置的,在开发插件之前,你需要了解一些执行参数和配置。假设你的插件放入到了工程中去了,那么在该工程的gruntfile文件中必须写上要加载的插件并且给他参数,告诉这个插件怎么样处理哪些文件。此处仍然以压缩js和html混合代码的html文件为例子,展示我们编写插件时的基础配置:

  1. module.exports = function(grunt) {
  2.  
  3. // 构建任务配置
  4. grunt.initConfig({
  5.  
  6. //读取package.json的内容,形成个json数据
  7. pkg: grunt.file.readJSON('package.json'),
  8. //压缩模板文件
  9. htmlmin: {
  10. options: {
  11. a:1,
  12. b:2,
  13. c:3
  14. },
  15. html: {
  16. expand: true,
  17. cwd: 'js/tpl/',
  18. src: ['*.html'],
  19. dest: 'js/html_min/'
  20. }
  21. }
  22.  
  23. });
  24.  
  25. // 加载指定插件任务
  26. grunt.loadNpmTasks('grunt-htmlmin');
  27.  
  28. // 默认执行的任务
  29. grunt.registerTask('default', ['htmlmin']);
  30.  
  31. };

我们可以看到在配置文件中有了若干的配置项,那么我们在自己开发的htmlmin插件中怎么样读取呢。对于options我们可以在自己的插件中用this.options获取到,其他html对象中的配置是直接作为文件的默认属性而引用的。

  1. /*
  2. * template-uglify
  3. * https://github.com/烧炭党人-申包胥/grunt-plugin
  4. *
  5. * Copyright (c) 2016 chen.y
  6. * Licensed under the MIT license.
  7. */
  8.  
  9. 'use strict';
  10.  
  11. module.exports = function(grunt) {
  12.  
  13. // Please see the Grunt documentation for more information regarding task
  14. // creation: http://gruntjs.com/creating-tasks
  15. //开始注册任务
  16. grunt.registerMultiTask('htmlmin', 'uglify these html template', function() {
  17. // Merge task-specific and/or target-specific options with these defaults.此处即为options中的参数默认配置项,上面的a b c都会传入其中
  18. var options = this.options({
  19. punctuation: '',
  20. separator: ', '
  21. });
  22.  
  23. // Iterate over all specified file groups.
  24. this.files.forEach(function(f) {
  25. // Concat specified files.
  26. var src = f.src.filter(function(filepath) {
  27. // Warn on and remove invalid source files (if nonull was set).
  28. if (!grunt.file.exists(filepath)) {
  29. grunt.log.warn('Source file "' + filepath + '" not found.');
  30. return false;
  31. } else {
  32. return true;
  33. }
  34. }).map(function(filepath) {
  35. // Read file source.
  36. return grunt.file.read(filepath);
  37. }).join(grunt.util.normalizelf(options.separator));
  38.  
  39. // Handle options.src未文件内容的字符串
  40. src += options.punctuation;
  41. //此处为添加的业务,将读取到的文件内容压缩
  42. src = src.replace(/\r\n/g, '').replace(/\s+/g, ' ').replace(/>\s+(?=<)/g, '$1');
  43. // 将处理后的文件存入目标位置 dest是上文中配置的路径/js/html_min/
  44. grunt.file.write(f.dest, src);
  45.  
  46. // Print a success message.
  47. grunt.log.writeln('File "' + f.dest + '" created.');
  48. });
  49. });
  50.  
  51. };

发布插件

现在,你的基本的插件以及完成。通过本地测试后你可以执行 npm publish命令将你创建的 Grunt 插件提发布npm!为了检验插件,我们将一个html为后缀名的html文件进行压缩:

  1. <!--消费订单-->
  2. <script id="tplmenu" type="text/template">
  3. <footer class="bottom">
  4. <%for(var i=0; i<globalConfig.menu.length; i++){%>
  5. <div class="box <%if(globalConfig.menu[i].sub_button.length > 0){%>haschild<%}%>" data-url="<%=globalConfig.menu[i].url%>">
  6. <div><%=globalConfig.menu[i].name%></div>
  7. <%if(globalConfig.menu[i].sub_button.length > 0){%>
  8. <ul class="hidelist">
  9. <%for(var n=0; n<globalConfig.menu[i].sub_button.length; n++){%>
  10. <a href="<%=globalConfig.menu[i].sub_button[n].url%>"><%=globalConfig.menu[i].sub_button[n].name%></a>
  11. <%}%>
  12. </ul>
  13. <%}%>
  14. </div>
  15. <%}%>
  16. </footer>
  17. </script>

配置gruntfile文件cwd:'source',src:['*.html'], dest:'target',执行grunt命令,得到压缩后的html:

  1. <!--消费订单--><script id="tplmenu" type="text/template"><footer class="bottom"><%for(var i=0; i<globalConfig.menu.length; i++){%><div class="box <%if(globalConfig.menu[i].sub_button.length > 0){%>haschild<%}%>" data-url="<%=globalConfig.menu[i].url%>"><div><%=globalConfig.menu[i].name%></div><%if(globalConfig.menu[i].sub_button.length > 0){%><ul class="hidelist"><%for(var n=0; n<globalConfig.menu[i].sub_button.length; n++){%><a href="<%=globalConfig.menu[i].sub_button[n].url%>"><%=globalConfig.menu[i].sub_button[n].name%></a><%}%></ul><%}%></div><%}%></footer></script>

参考文档

http://www.gruntjs.net/creating-plugins

http://www.gruntjs.net/api/grunt

如何编写grunt 插件

Grunt 插件开发与调式

快速开发Grunt插件----压缩js模板的更多相关文章

  1. 快速开发 jQuery 插件的 10 大技巧(转)

    1. 把你的代码全部放在闭包里面 这是我用的最多的一条.但是有时候在闭包外面的方法会不能调用.不过你的插件的代码只为你自己的插件服务,所以不存在这个问题,你可以把所有的代码都放在闭包里面.而方法可能应 ...

  2. 快速开发 jQuery 插件的 10 大技巧(转)

    转自:http://www.oschina.net/news/41776/jquery-10-tips 在开发过很多 jQuery 插件以后,我慢慢的摸索出了一套开发jQuery插件比较标准的结构和模 ...

  3. 如何开发 Grunt 插件

    创建 grunt 插件 准备工作:(node/npm/git 安装,在此不做赘述) yeoman generator 可以自动生成一个插件模板. 安装 yo npm install -g yo 安装 ...

  4. 快速开发 jQuery 插件的 10 大技巧

    在开发过很多 jQuery 插件以后,我慢慢的摸索出了一套开发jQuery插件比较标准的结构和模式.这样我就可以 copy & paste 大部分的代码结构,只要专注最主要的逻辑代码就行了. ...

  5. 快速开发jQuery插件的10大技巧

    原文链接:http://wiki.itivy.com/?p=36 在开发过很多 jQuery 插件以后,我慢慢的摸索出了一套开发jQuery插件比较标准的结构和模式.这样我就可以 copy & ...

  6. 使用grunt合并压缩js、css文件

    需要了解的知识: 1.nodejs的安装与命令行使用 2.nodejs安装应用 3.grunt的初步了解 本文已假定读者已经熟悉以上知识. 好,我们继续: 任务1:将src目录下的所有zepto及插件 ...

  7. grunt 合并压缩js和css文件(二)

    具体node及文件配置请看: grunt 安装使用(一) 要压缩的文件 --src/ ajax.js assets.js touch.js zepto.js 目录结构: dist/ node_modu ...

  8. 【微信小程序开发】快速开发一个动态横向导航模板并使用

    目标:做个横向导航,可以横向滚动. 思路:使用scroll-view组件,可实现横向滚动功能.scroll-view内包含一个动态的view列表,代表导航的每一项,导航要接收动态数组,然后使用列表展示 ...

  9. 【新手】【十分钟上手系列-一】快速开发vue插件

    2018.6.28 在这浮躁的前端娱乐圈,不会三两个新框架都觉得自己不是前端.哦,不是我说的.说到底.原生才是重中之重.加油. vue用了大半年多,一直在用ui库,插件等,没有自己的东西. 想想连个v ...

随机推荐

  1. Angular2入门系列教程2-项目初体验-编写自己的第一个组件

    上一篇 使用Angular-cli搭建Angular2开发环境 Angular2采用组件的编写模式,或者说,Angular2必须使用组件编写,没有组件,你甚至不能将Angular2项目启动起来 紧接着 ...

  2. [PHP内核探索]PHP中的哈希表

    在PHP内核中,其中一个很重要的数据结构就是HashTable.我们常用的数组,在内核中就是用HashTable来实现.那么,PHP的HashTable是怎么实现的呢?最近在看HashTable的数据 ...

  3. myeclipse学习总结一(在MyEclipse中设置生成jsp页面时默认编码为utf-8编码)

    1.每次我们在MyEclispe中创建Jsp页面,生成的Jsp页面的默认编码是"ISO-8859-1".在这种情况下,当我们在页面中编写的内容存在中文的时候,就无法进行保存.如下图 ...

  4. ASP.NET Core应用针对静态文件请求的处理[1]: 以Web的形式发布静态文件

    虽然ASP.NET Core是一款"动态"的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件.CSS样式文件和图片文件 ...

  5. Nginx如何处理一个请求

    看了下nginx的官方文档,其中nginx如何处理一个请求讲解的很好,现在贴出来分享下.Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口*:80上监听 ...

  6. Android公共title的应用

    我们在开发Android应用中,写每一个页面的时候都会建一个title,不是写一个LinearLayout就是写一个RelativeLayout,久而久之就会觉得这样繁琐,尤其几个页面是只是标题不一样 ...

  7. Windows API 设置窗口下控件Enable属性

    参考页面: http://www.yuanjiaocheng.net/webapi/create-crud-api-1-put.html http://www.yuanjiaocheng.net/we ...

  8. 【JQ基础】数组

    each() 方法规定为每个匹配元素规定运行的函数.

  9. App解读

    一直不懂别人口中说的原生开发.混合式开发.今天突然看了一篇文章讲解的是什么叫做原生App?移动 Web App?混合APP?分享给大家. 原生App是专门针对某一类移动设备而生的,它们都是直接安装到设 ...

  10. Java实现FTP文件与文件夹的上传和下载

    Java实现FTP文件与文件夹的上传和下载 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制 ...