码迷,mamicode.com
首页 > 其他好文 > 详细

grunt配置太复杂?发布一个前端构建工具,简单高效,自动跳过未更新的文件

时间:2015-07-07 19:00:59      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:

做前端项目,如果没有一个自动化构建工具,手动处理那简直就是坑爹O(∩_∩)O。于是上网了解了下,grunt用的人不少,功能也挺强大。看了一下grunt的配置(包括gulp),感觉稍显复杂。当时项目结构非常简单,就是单文件夹下的html文件,再加上js、css、图片。需要的功能也就js的合并和压缩,html和css的简单格式化,功能简单,So easy……开搞,搞定第一版,一直用到今年。最近整理项目,感觉只支持单一文件夹,功能全内置,实在不够灵活,于是重写了第二版。功能实现没什么难的,麻烦的是打造一个可扩展性良好的架构,要配置简单,任务流程完全自主配置,插件、执行顺序完全可控,文本还要能单独处理,最好能和任务一样配置、控制方便。终于搞定了!一个良好的架构真是很花时间和精力,大家推荐支持一下呗O(∩_∩)O

关于Qbuild.js(姑且这么叫之吧)

  • 轻量高效,易于配置。支持js压缩、文件合并、格式化、复制和重命名等。
  • 基于js的配置文件,支持自定义任务模块和文本处理,支持模块重用。
  • 灵活的文件扫描规则,支持通配符(*和**),支持正则表达式,支持排除规则。
  • 自动跳过未更新的文件,大大提升处理效率。
  • 重命名文件时,自动更新文件引用(可配置)。
  • 自定义输出目录,并保持文件引用(可配置)。
  • 支持将通过 document.write 输出内容的js文件,直接将js引用替换为输出内容。

最后一点可能有人不了解,比如一个html网站,头部和尾部内容在很多html文件里是一样的,便于开发(避免变动一处要修改n个文件),可以将内容整合到js文件中,通过 document.write(html) 输出,而发布时却想将内容直接集成到html文件里(考虑到SEO优化、加载性能等),可以使用本工具实现。我承认这个功能比较蛋疼,可能很多人并不会用到,不过既然实现了,就放上来了,而且对后面实现文件重命名(比如js、css)后自动更新文件(比如html文件)引用有不少帮助。最重要的是全插件模式,任君配置。

先看下运行效果:

技术分享技术分享技术分享

以下是 demo/index.html 文件的变化,输出文件夹为 release/www/index.html

技术分享技术分享

第二次运行,仅修改 demo/index.html 文件,截取部分运行结果

技术分享

如何使用

1. 安装Node.js和压缩工具(uglify或 Google Closure Compiler(需java支持))

2. 下载示例代码,将build文件夹放到你的项目中,配置好build.data.js,执行 node build/build.js (Windows 可直接运行 build.bat )

3. 示例配置见 build/build.data.js 和 demo/build/build.data.js ,2种不同的情况,可供参考

更多见 https://github.com/devin87/build.js

配置代码(build.data.js)

由于注释较多,默认折叠

技术分享
  1 //build 配置文件
  2 module.exports = {
  3     //根目录,默认为配置文件所在路径,所有目录均基于此目录
  4     //绝对路径优先;若以./开头则基于配置文件路径(下同)
  5     root: "../",
  6     //输入目录,以下所有dir目录均基于此目录(若以/开头则直接基于根目录)
  7     dir: "",
  8     //输出目录,同上
  9     output: "release",
 10 
 11     //是否自动跳过未更新的文件
 12     //若任务对象有同名属性,则以任务对象的值为主 eg: dir、output、skipOutput、autoSkip、enable、preload、rename、registerText、runText
 13     autoSkip: true,
 14 
 15     //重命名规则
 16     rename: "%f.name%.%date(‘yyyyMMddHHmm‘)%%f.ext%",
 17     cleanRename: true,
 18 
 19     //注册任务处理模块,基于根目录
 20     register: {
 21         concat: "./module/concat.js",
 22         format: "./module/format.js",
 23         cmd: "./module/cmd.js",
 24 
 25         //若处理程序相同,可重用已注册的模块 eg: copy:"format"
 26         copy: "./module/copy.js"
 27     },
 28 
 29     //注册文本处理模块,基于根目录
 30     //registerText: {},
 31     registerText: "./module/text/*.js",
 32 
 33     //默认执行的文本处理模块(按顺序执行),*表示其它模块
 34     runText: ["replace", "before", "after", "*"],
 35 
 36     //任务:文件合并
 37     concat: {
 38         title: "文件合并",
 39 
 40         dir: "js/src",
 41         output: "/js",
 42 
 43         //可以简写为 {"src/a.js":["a/t1.js", "a/t2.js", "a/t3.js"]}
 44         list: [
 45             {
 46                 dir: "a",
 47                 src: ["t1.js", "t2.js", "t3.js"],
 48                 dest: "src/a.js"
 49             },
 50             {
 51                 dir: "b",
 52                 src: ["t1.js", "t2.js", "D:/t.js"],
 53                 dest: "src/b.js"
 54             },
 55             {
 56                 src: ["a.js", "b.js"],
 57                 dest: "ab.js"
 58             }
 59         ],
 60 
 61         //在文件内容之前添加文本,见 ./module/text/append.js
 62         before: [
 63             "//build:%NOW% by Qbuild.js devin87@qq.com\n",
 64 
 65             //给不同文件追加不同文本,不适用有同名文件的情况
 66             {
 67                 //其它文件追加的文本
 68                 "def": "//%f.fullname%",
 69                 //ab.js追加的文本
 70                 "ab.js": "//a.js+b.js\n"
 71             }
 72         ],
 73 
 74         //在文件内容之后添加文本,同上,见 ./module/text/append.js
 75         after: [
 76             {
 77                 "ab.js": "\n//append after test!"
 78             }
 79         ],
 80 
 81         replace: [
 82             //移除\r字符,第一个参数可以是正则表达式或字符串,若是字符串,则需要指定第3个参数(正则表达式标记 eg:g、i、m或其组合)
 83             [/\r/g, ""],
 84             //移除VS引用
 85             [/\/\/\/\s*<reference path="[^"]*" \/>\n/gi, ""]
 86         ],
 87 
 88         //禁用文件重命名
 89         rename: false
 90     },
 91 
 92     //任务:文件格式化
 93     format: {
 94         title: "格式化html文件",
 95         //autoSkip: false,
 96         rename: false,
 97 
 98         //注册单独的文本处理模块,|开头表示程序所在目录
 99         registerText: {
100             include: "|./module/text/custom/document.write.js",
101             rename_link: "|./module/text/custom/rename_link.js"
102         },
103 
104         include: "/**(head|bottom).js",
105 
106         //可配置引用匹配规则
107         //rename_link: {
108         //    match: /<(script|link|img)[^>]+?(src|href)=([‘"])([^>]+?)\3[^>]*>/ig,
109         //    index: 4
110         //},
111 
112         runText: ["replace", "before", "after", "include", "rename_link"],
113 
114         //要扫描的目录,可为数组,默认只扫描当前目录下的文件,若要扫描子孙目录,请使用*或**
115         //扫描根目录下所有子目录 eg:/*
116         //扫描根目录下所有子孙目录(包括子目录的子目录等) eg:/**
117         //dir: ["ab*/*", "m"],
118 
119         //一般output可省略,将自动保持原始文件夹结构
120         output: "www",
121 
122         //要匹配的文件,支持正则表达式 eg: (*|/demo/**).html
123         //*可匹配斜杆之外的字符,2个*可匹配所有字符
124         match: "**.html",
125         //要排除的文件
126         exclude: "**.old.html",
127 
128         replace: [
129             //移除html注释
130             [/(<!--(?!\[if\s)([^~]|~)*?-->)/gi, ""],
131             //移除空script标签
132             [/\s*<script(\s+type="[^"]+")?>\s*?<\/script>/gi,""],
133             //移除无效的空格或换行
134             [/(<div[^>]*>)[\s\r\n]+(<\/div>)/gi, "$1$2"],
135             //移除多余的换行
136             [/(\r?\n)(\r?\n)+/g, "$1"],
137             //移除首尾空格
138             [/^\s+|\s+$/, ""]
139         ]
140     },
141     format0: {
142         title: "格式化css文件",
143         //enable: false,
144 
145         dir: "css",
146         match: "*.css",
147 
148         replace: [
149             //移除css注释
150             [/\/\*([^~]|~)*?\*\//g, ""],
151             //移除多余的换行
152             [/(\r?\n)(\r?\n)+/g, "$1"],
153             //移除首尾空格
154             [/^\s+|\s+$/, ""]
155         ]
156     },
157 
158     //任务:调用命令行压缩js
159     cmd: [
160         {
161             title: "压缩js",
162 
163             dir: ["js", "m/js"],
164             //cmd: "java -jar D:\\tools\\compiler.jar --js=%f.fullname% --js_output_file=%f.dest%",
165             cmd: "uglifyjs %f.fullname% -o %f.dest% -c -m",
166 
167             match: "**.js",
168             exclude: "data/**.js",
169 
170             replace: [
171                 //去掉文件头部压缩工具可能保留的注释
172                 [/^\/\*([^~]|~)*?\*\//, ""]
173             ],
174 
175             //可针对单一的文件配置 before、after,def 表示默认
176             before: [
177                 {
178                     "def": "//devin87@qq.com\n",
179                     "Q.js": "//Q.js devin87@qq.com\n"
180                 },
181                 "//build:%NOW%\n"
182             ]
183         }
184     ],
185 
186     //任务:文件同步(复制)
187     copy: [
188         {
189             title: "同步js数据",
190             dir: "js/data",
191             match: "**.js"
192         },
193         {
194             title: "同步图片",
195             dir: "images",
196             match: "**"
197         }
198     ],
199 
200     //要启动的任务,按顺序执行,不支持*
201     //由于js、css进行了重命名,更新html引用需依赖这两项,所以先执行js压缩和css格式化
202     run: ["concat", "cmd", "format0", "format", "copy"]
203 };
View Code

代码下载

Qbuild.js 源码+示例代码

写在最后

由于图片较多,暂时先介绍到这。下次再介绍运行机制及插件的编写。

如果本文或本项目对您有帮助,请不吝点个赞。如果有什么意见或建议,欢迎交流!

grunt配置太复杂?发布一个前端构建工具,简单高效,自动跳过未更新的文件

标签:

原文地址:http://www.cnblogs.com/devin87/p/Qbuild.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!