nodejs合并压缩javascript和css的方法教程

对于压缩工具前端攻城师最常见的就是雅虎的Yui Compressor / Google的Closure Compiler了。

对比其他压缩工具相对在JS和CSS压缩领域比较成熟,压缩率也比较好.

一般会选择结合ANT实现压缩并合并,效果也不错,但是比较偏向个人,团队协作每个人都部署java/ant有些麻烦。

对于个人开发使用ANT的方案也是相对不错的选择。对于团队,最好的解决办法是在服务端压缩,大家只需要登录并执行一个统一的脚本。

下面分享下大致的测试结果,和改用nodejs压缩合并js/css的原因。

js部分采用UglifyJS

1. 压缩jquery 1.8,253 KB:使用UglifyJS(以下简称UJ): 90.5 KB;使用Closure Compiler(以下简称CC): 91.1 KB。

2. 如果在闭包(function($, window, undefined) {...})(jQuery, window); 内的 unused function/variables

CC会被删除没使用的;UJ 默认全部保留,加上 pro.ast_lift_variables(ast) 才会删除未使用的函数/变量 (对象/数组 不会被删除)。

如果直接暴漏在window下的,两个基本差不多。

3. function c(){2}, CC 会警告,UJ不会

4. function c(){e()2},都会抛出异常,显示行数,错误原因。CC提示列错误,UJ不会。

5. function c(){e();2},都保留了2,CC 警告,UglifyJS 无信息

6. CC 一次显示JS里的全部错误(有些是前面的错误引起的, 所以部分是误报),UJ每次只显示一个错误。

7. 0 = {}; CC会报错,而UJ不会。

8. if语句都可很好的优化。

9. CC喜欢把变量/函数(结构简单的)内的语句,直接插入到使用它们的地方,UJ维持原样。

如果函数内的内容较少, CC会把函数的内容直接插入到调用它的地方,比如:

function c(){xxxxxxx('12345678901234567');}

function c(){xxxxxx.yyyyy('12345678901234');}

function c(){xxxxxx.yyyyy.zzzz('12345678901');}

function c(){if (X){alert('1234')};alert('12');}

当其他函数里调用c()时,会把c()方法删除,然后把c()内的内容移动到这里

(当里面的字符串长度+1后,就会直接使用原函数c(),所以CC这里是根据字符长度)。

10. 如果是很长的字符串, var str ='很长......很长'; 在其他函数内用到str,CC会把str的值直接插入,而UJ不会。

11. 10000 都会转成 1e4。

12. alert(3*7) 都会转成 alert(21)。

13. function c() {}; function b(){return; c();}; CC/UJ(开启 --lift-vars) 都会删除 c() 的代码。

14. 这段代码:(function() {return;})(); CC会删除,UJ不会。

综上,CC是编译器,有高级优化选项,UJ目前只能算是压缩器。CC喜欢把函数外的字符串值/内容简单的函数内容,直接插入到使用它的地方,所以有时这样反而增加了压缩后的文件大小。

对于压缩后的大小,UJ压缩的一般比CC稍大,一般1KB左右。

压缩速度,CC想的事情比较多,而且需要java,所以压缩慢,UJ 速度飞快。

如果网站结构复杂,JS比较多的时候,UJ的速度优势就非常明显了。

所以团队成员无JS新手,使用UJ是个不错的选择。

另外, uglifyjs2 也在开发中,比UJ1的压缩效果好一些,https://github.com/mishoo/uglifyjs2,

对比uglifyjs1:

(function() {return;})(); 会变成:function(){}(), 删除了return;

0 = {}; 还是不会报错;

未使用的方法/变量移除时,会输出WARN信息;

function c(){e();2} 会把2删除,并有WARN信息;

提示信息的行号部分有偏差(少了1行);

因为还是beta版,UJ2的一些问题都算正常的,UJ2由UJ1改进而来,测试中也没发现重大bug,所以采用UJ2还算靠谱。

PS: 最近应用发现2个bug:

没用的内部变量, 没删除完整, 剩下了 "var;"

压缩文件末尾没加上";"号, 当2个文件合并后如果这样, 问题就大了:

var a={};a.x=function(){console.log(this)} //file1
(function(){...})() //file2 // 变成a.x()()了..

所以上面的2个bug, 需要自己写2个正则解决掉.

css部分采用clean-css

CSS压缩找到的有:

https://github.com/GoalSmashers/clean-css

https://github.com/ded/sqwish

https://github.com/fczuardi/node-css-compressor

对比后,选择了clean-css,压缩速度和效果都还不错,目前发现的问题:.a{}这样的无内容的规则,不会被清理。

改用nodejs压缩,1是源码是JS的,发现bug可以快速解决;2是nodejs的异步多线程IO特性,可以多线程压缩,压缩速度提升明显;3是统一了环境,不需要再依赖java。并且合并文件也非常简单。

压缩合并的大体思路:

build.js:

var argv = process.argv, arguments = argv.splice(2);

用来接收传递的参数,比如可以:sudo ./build.js css {project path}

var buildType = arguments[0], projectPath = arguments[1];

简单的项目,就可以去project path的assets目录遍历待压缩的文件,进行压缩。

高级点的,可以把文件列表写到配置,var maps = require('map').maps; 然后遍历maps进行压缩合并,只压缩map的结构一维就够了,如果想压缩并合并,可以改成二维的结构。

再高级点,遍历文件夹得到待压缩的文件(想办法去掉不需要压缩的文件),再根据规则产生待合并的文件名,然后自动生成map。

再高级点,自动生成map的同时,针对文件生成md5,下次压缩根据md5判断,如果文件内容变动,才压缩并重新生成map。

当然,也不是后面的方法最好,选择适合自己的就是最好的。

大体上,这样就可以制作“傻瓜版”压缩工具了,只需要输入参数,其他的不需要管。

我们的做法是读取header / footer 的部分, 匹配标记生成待压缩的文件列表和合并后的目标文件名,比如:

<!-- target="pkg1.min.js" {{{ -->
<script src="a1.js"></script>...<script src="b1.js"></script>
<!-- }}} -->
<!-- target="pkg2.min.js" {{{ --> ... <!-- }}} -->

然后生成带MD5的map,对比文件是否改动,选择性压缩,再合并到target指向的目标文件。

开发时使用未压缩的,上线前压缩合并,再自动把header/footer未压缩的注释掉,加上合并后的JS/CSS。

使用UglifyJS2、clean-css的压缩代码,已经放到github,https://github.com/kairyou/f2e-tools/tree/master/libs。

require build-css-cc.js或build-js-uj2.js,就可以使用里面的build方法压缩了。

另外,压缩时需要发送错误时终止并提示,所以压缩时的读取是sync方式,但是生成文件map、产生MD5、合并文件部分可以采用异步方式。

时间: 2024-11-01 23:02:58

nodejs合并压缩javascript和css的方法教程的相关文章

在服务端合并和压缩JavaScript和CSS文件

CSS Sprites和图像映射现在已经随处可见了,但由于IE6和IE7不支持Data URI以及性能问题,这项技术尚未大量使用.目前大部分网页中的JavaScript和CSS文件数量和开发时一致,少量的网页会根据实际情况采取本地合并,这些合并中相当多的是有选择地手动完成,每次新的合并都需要重新在本地完成并上传到服务器,比较的随意和繁琐,同样文件的压缩也有类似的情况.而利用服务端的合并和压缩,我们就可以按照开发的逻辑尽可能让文件的颗粒度变小,利用网页中URL的规则来自动实现文件的合并和压缩,这会

Ant+YUICompressor 合并压缩JS和CSS代码实例

在实际项目中,推荐的是一个html对应一个JS文件和一个CSS文件.这样做可以减少HTTP请求,众所周知,一个HTTP请求的延迟远比下载一个大点的文件大得多. 所以从程序员来看:我要分文件,分模块写.不然代码太混乱了.(多文件) 客户(网站的使用者)来看:我要良好的用户体验,越快越好.(少文件,文件一多HTTP请求会很多) 这就产生了冲突,不过有需求就有市场,我们聪明的前端攻城狮也有自己的方法解决.--链接文件与压缩大法,也就是标题"使用Ant和YUICompressor链接合并压缩你的JS和C

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

需要了解的知识: 1.nodejs的安装与命令行使用 2.nodejs安装应用 3.grunt的初步了解 本文已假定读者已经熟悉以上知识.   好,我们继续: 任务1:将src目录下的所有zepto及插件合并,并压缩. --src/ ajax.js assets.js callbacks.js data.js deferred.js detect.js event.js form.js fx.js fx_methods.js gesture.js ie.js ios3.js selector.j

学习使用grunt来打包JavaScript和CSS程序的教程_node.js

Java世界里的Maven提供了强大的包依赖管理和构建生命周期管理.在JavaScript的世界里,随着Node.js的流行,JavaScript原生的构建工具已经成为可能. Grunt.js是基于Node.js的自动化任务运行器.Grunt.js结合NPM的包依赖管理,完全可以媲美Maven.Grunt.js天然适合前端应用程序的构建--不仅限于JavaScript项目,同样可以用于其他语言的应用程序构建.越来越多的JavaScript项目已经在使用Grunt,其中最大的使用者包括著名的jQu

使用UglifyJS合并/压缩JavaScript的方法_基础知识

build.js中的代码会去调用UglifyJS的接口函数以执行压缩任务. 1,去github下载最新的UglifyJS.两种方式下载,如果安装了git,进入git控制台使用如下命令 git clone git://github.com/mishoo/UglifyJS.git 或者使用http方式下载,点击zip下载.解压后其目录结构如下   2,新建一个项目(文件夹)myApp,将uglify-js.js和lib目录拷贝到自己的项目中.如下 3,在myApp中新建一个compress.js,内

ASP.NET MVC中使用Bundle打包压缩js和css的方法_实用技巧

在ASP.NET MVC4中(在WebForm中应该也有),有一个叫做Bundle的东西,它用来将js和css进行压缩(多个文件可以打包成一个文件),并且可以区分调试和非调试,在调试时不进行压缩,以原始方式显示出来,以方便查找问题. 具体优势可自行百度或参看官方介绍:http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification 这里仅简单记录下如何使用. 首先,如果是使用的ASP.NET MVC4基本或者其他内容更丰富的模板,B

根据分辨率判断调用相对应的css文件方法教程

首先,我们将以下JS代码放入<head>和</head>标签内,用来判断浏览器分辨率  代码如下 复制代码 <SCRIPT LANGUAGE="javascript"> <!-- if (window.navigator.userAgent.indexOf("MSIE")>=1) { var IE1024=""; var IE800=""; var IE1152="&q

服务端合并和压缩JS和CSS文件

Web性能优化最佳实践中最重要的一条是减少HTTP请求,它也是YSlow中比重最大的一条规则.减少HTTP请求的方案主要有合并JavaScript和CSS文件.CSS Sprites.图像映射(Image Map)和使用Data URI来编码图片.CSS Sprites和图像映射现在已经随处可见了,但由于IE6和IE7不支持Data URI以及性能问题,这项技术尚未大量使用.目前大部分网页中的JavaScript和CSS文件数量和开发时一致,少量的网页会根据实际情况采取本地合并,这些合并中相当多

使用 YUI Compressor对JavaScript和CSS文件进行压缩优化(转)

本 文向您介绍如何通过在您的 CSS 和 JavaScript 文件中 - 两种易于优化的常见资源,使用社区中提供的工具即可完成优化 - 优化空间使用来实现更高的性能.然而,在继续之前,有一点是很重要的,压缩 CSS 和 JavaScript 文件只是为了让您的 web 应用程序 "轻巧" 的诸多操作其中的两个技术.    为了从本文中获得最大收益,您需要安装下列工具: 一个文本编辑器 Java Runtime Environment 1.4 或者更新版本    问题:空白内容 当 开