转载

fis压缩html内联js和css

通常我们处理文件压缩一般都是直接针对js和css文件,但是我们的html文件(或者其他诸如php、jsp等类html文件)通常也会包含一些内联样式或者js代码,那这些代码同样有压缩的必要。由于团队在用fis做前端自动化构建和部署,那我们就fis插件的方式实现我们的html内联css和js代码的压缩。

fis插件开发前奏

如果对fis插件开发还不是很了解的同学,可以参考一下我们白大神前面写的一篇文章,FIS插件开发记。 当然,你也可以直接到 fis官网 看一下 fis插件开发教程 ,如果你熟悉fis,相信狂拽酷炫吊炸天的你肯定一看便懂。

我们的fis插件

好了,聊完了fis插件开发,现在开始聊聊我们的插件。

开发目录

fis 的插件是以 NPM 包的形式提供的,这将意味着 fis 的插件都是一个 NPM 包,并且最终也需要发布到 NPM 平台上。为了方便管理,FIS 只能加载 NPM 全局安装的插件,这将意味着你开发的时候需要把你的插件放到 NPM 全局插件目录下。我们如何知道这个全局插件目录在什么地方呢,一般需要通过在 CMD (Windows) 或者 终端 (类 Unix)执行命令 npm prefix -g 得到一个目录,比如:

fis压缩html内联js和css

那么npm包的目录就在全局的node_modules目下,我的npm全局目录就是C:/Users/Administrator/AppData/Roaming/npm/node_modules,我们的插件就在该目录下运行。

插件命名

在开发一个fis插件之前,我们首先要做的是定位插件的类型和命名。

现在我们都很明确,我们的插件主要是用于html内联js和css代码的压缩,那就是属于optimizer类型的插件,像fis自带的js压缩插件fis-optimizer-uglify-js和css压缩插件fis-optimizer-clean-css都是属于这一类;那我们就取名叫fis-optimizer-minify-html。记住,如果你的插件要发布到 npm资源网 ,记得先到上面查一下是否同名的插件,否则我们的插件会发布不上去。

插件目录

在C:/Users/Administrator/AppData/Roaming/npm/node_modules目下创建一个fis-optimizer-minify-html目录,新建一个index.js、package.json文件还有一个node_modules目录: fis压缩html内联js和css

index.js就是我们的程序入口,package.json配置我们的插件信息,node_modules存放我们需要依赖的包;

插件配置

//package.json {   "name": "fis-optimizer-minify-html",   "description": "A optimizer for fis to compress html inline js and css by using minify-html.",   "version": "1.0.0",   "author": {     "name": "GaryGao",     "email": "garygchai@gmail.com"   },   "homepage": "https://github.com/garygchai/",   "keywords": [     "fis", "minify-html"   ],   "main": "index.js",   "engines": {     "node": ">= 0.8.0"   },   "dependencies": {     "uglify-js": "2.4.15",     "clean-css": "1.1.7"   },   "maintainers": [     {       "name": "garygao",       "email": "garygchai@gmail.com"     }   ] } 

插件开发

由于要压缩js和css,我们需要依赖两个工具库,uglify-js和clean-css。下面插件的代码:

//index.js /*  * fis-optimizer-minify-html  * v0.0.1  * garygao  * https://github.com/garygchai/  */ 'use strict'; var UglifyJS = require('uglify-js');   var CleanCss = require('clean-css');   //匹配 <style></style> var styleReg = /(<style(?:(?=/s)[/s/S]*?["'/s/w///-]>|>))([/s/S]*?)(<//style/s*>|$)/ig;   //匹配 <script></script> var scriptReg = /(<script(?:(?=/s)[/s/S]*?["'/s/w///-]>|>))([/s/S]*?)(<//script/s*>|$)/ig;   module.exports = function(content, file, conf){console.log(conf)    conf.fromString = true;  conf.processImport = false;  //压缩内联css  content = content.replace(styleReg, function(m, start_tag, cont, end_tag){   var parseCont = "";   try {    parseCont = CleanCss.process(cont, conf);   } catch(e) {    parseCont = cont;   }   return start_tag + parseCont + end_tag;  });   //压缩内联js  content = content.replace(scriptReg, function(m, start_tag, cont, end_tag){   var parseCont = "";   try {    parseCont = UglifyJS.minify(cont, conf).code;   } catch(e) {    parseCont = cont;   }   return start_tag + parseCont + end_tag;  });  file.setContent(content);  return content; };  

插件测试

插件开发完成,我再来看看怎么进行配置使用,打开我们项目的fis-conf.js

//fis-conf.js //项目编译配置 fis.config.set('roadmap.path',[    {   reg: /static//(.*)/,   release: 'staticPub/$1'  } ]); //插件配置 fis.config.set('modules.optimizer', {     html: 'minify-html',   php: 'minify-html' });  

我们配置了html和php文件都要经过我们的插件进行处理,下面是我们的index.html文件:

//static/index.html <!DOCTYPE HTML>   <html>    <head>   <meta http-equiv='Content-Type' content='text/html;charset=utf-8'></meta>   <meta http-equiv="X-UA-Compatible" content="IE=edge" />   <style type="text/css">    *{     padding:0;     margin:0    }    html {     min-height:101%    }    body {     font-family:verdana,arial,tahoma;     font-size:12px;     color:#333    }    div {     margin:0 auto    }    ul,ol,li {     list-style:none    }    a {     text-decoration:none;     word-wrap:break-word    }    a:hover {     text-decoration:underline    }    img {     border:0    }    .right {     float:right    }    </style>    <script type="text/javascript">     var Cookie = {      read: function(name, key) {       var cookieValue = "";       var arrStr = document.cookie.split("; ");       for(var i = 0;i < arrStr.length;i ++){        var temp = arrStr[i].split("=");        if(temp[0] == name){         cookieValue = temp[1];         break;        }       }       if(key){        return new Kg.Param().parse(cookieValue)[key];       }       return cookieValue;      },      getValue: function(name, item){       var cookieArr = document.cookie.match(new RegExp("(^|//s)"+name+"=([^;]*)","i"));       var cookieValue = cookieArr?unescape(cookieArr[2]):"";       if(item && cookieValue){        var value = cookieValue.match(new RegExp("(^|//&)"+item+"=([^//&]*)","i"));        cookieValue = value?value[2]:"";       }       return cookieValue;      }     };    </script> </head>   <body>   <script type="text/html">    <div>   <ul>    <li></li>    <li></li>    <li></li>    <li></li>   </ul>  </div> <script>   var isIndex = true;   var isIndexPage = true;   (function(){  //判断手机访问 android和ios跳转到m.fanxing.com  var tUrl = location.href,   ua = navigator.userAgent.toLowerCase(),   android = /android|Adr/gi.test(ua),   iphone = /iphone/gi.test(ua),   frwrap = /fr=wrap/gi.test(tUrl);  if(!frwrap){   if (android || iphone) {    document.location = "http://m.fanxing.com";   }  } })(); </script>   </body>   </html>    

执行编译命令:

fis-release -od ./   

我们打开staticPub/index.html看看效果:

<!DOCTYPE HTML>   <html>    <head>   <meta http-equiv='Content-Type' content='text/html;charset=utf-8'></meta>   <meta http-equiv="X-UA-Compatible" content="IE=edge" />   <style type="text/css">*{padding:0;margin:0}html{min-height:101%}body{font-family:verdana,arial,tahoma;font-size:12px;color:#333}div{margin:0 auto}ul,ol,li{list-style:none}a{text-decoration:none;word-wrap:break-word}a:hover{text-decoration:underline}img{border:0}.right{float:right}</style>    <script type="text/javascript">var Cookie={read:function(e,a){for(var r="",n=document.cookie.split("; "),t=0;t<n.length;t++){var i=n[t].split("=");if(i[0]==e){r=i[1];break}}return a?(new Kg.Param).parse(r)[a]:r},getValue:function(e,a){var r=document.cookie.match(new RegExp("(^|//s)"+e+"=([^;]*)","i")),n=r?unescape(r[2]):"";if(a&&n){var t=n.match(new RegExp("(^|//&)"+a+"=([^//&]*)","i"));n=t?t[2]:""}return n}};</script> </head>   <body>   <script type="text/html">    <div>   <ul>    <li></li>    <li></li>    <li></li>    <li></li>   </ul>  </div> </script>   <script type="text/html">var isIndex=!0,isIndexPage=!0;!function(){var e=location.href,t=navigator.userAgent.toLowerCase(),a=/android|Adr/gi.test(t),i=/iphone/gi.test(t),n=/fr=wrap/gi.test(e);n||(a||i)&&(document.location="http://m.fanxing.com")}();</script>   </body>   </html>    

效果棒棒哒~经过一系列的测试之后,下来就是把插件发布到npm以供小伙伴们使用啦~

插件发布

发布之前我们需要登录npm账号:

$ npm adduser Username: garygchai   Password: *********   Email: <this IS public> garygchai@gmail.com   

输入完成登录成功之后,我们直接在fis-optimizer-minify-html目录执行发布:

$ npm pubish + fis-optimizer-minify-html@1.0.0 

看到上面的界面就是发布成功啦!全局安装就能使用我们的插件啦~

$ npm install -g fis-optimizer-minify-html 

后记

这样我们就完成了插件的1.0版本,但是插件还有一些需要优化地方:

1、script标签的正则查找效率不是很好,如果script标签有type属性,我们只需要查找type="text/javascript"的script标签,而且还应过滤掉含有src属性的script标签;

2、不支持自定义的script标签,比如<:script><:/script>;

如果你有兴趣,这些我们后续一起优化吧...

github地址: https://github.com/garygchai/fis-optimizer-minify-html

npm地址: https://www.npmjs.com/package/fis-optimizer-minify-html

正文到此结束
Loading...