通常我们处理文件压缩一般都是直接针对js和css文件,但是我们的html文件(或者其他诸如php、jsp等类html文件)通常也会包含一些内联样式或者js代码,那这些代码同样有压缩的必要。由于团队在用fis做前端自动化构建和部署,那我们就fis插件的方式实现我们的html内联css和js代码的压缩。
如果对fis插件开发还不是很了解的同学,可以参考一下我们白大神前面写的一篇文章,FIS插件开发记。 当然,你也可以直接到 fis官网 看一下 fis插件开发教程 ,如果你熟悉fis,相信狂拽酷炫吊炸天的你肯定一看便懂。
好了,聊完了fis插件开发,现在开始聊聊我们的插件。
开发目录
fis 的插件是以 NPM 包的形式提供的,这将意味着 fis 的插件都是一个 NPM 包,并且最终也需要发布到 NPM 平台上。为了方便管理,FIS 只能加载 NPM 全局安装的插件,这将意味着你开发的时候需要把你的插件放到 NPM 全局插件目录下。我们如何知道这个全局插件目录在什么地方呢,一般需要通过在 CMD (Windows) 或者 终端 (类 Unix)执行命令 npm prefix -g 得到一个目录,比如:
那么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目录: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