巧用cheerio重构grunt-inline
grunt-inline是楼主之前写的一个插件,主要作用是把页面带了__inline标记的资源内嵌到html页面去。比如下面的这个script标签。
<script src="main.js?__inline"></script>
技术难度不高,主要就是通过正则将符合条件的script标签等匹配出来。当时就在想:
如果有那么一个插件,能够帮我们完成html解析就好了!
没错,真有——cheerio。感谢当劳君的推荐 =。=
cheerio简介
直接引用某前端同学的翻译。
为服务器特别定制的,快速、灵活、实施精益(lean implementation)的jQuery核心
举个最简单的栗子,更多API说明请参考官方文档
var cheerio = require('cheerio'),
$ = cheerio.load('<h2 class="title">Hello world</h2>');
$('h2.title').text('Hello there!');
$('h2').addClass('welcome');
$.html();
//=> <h2 class="title welcome">Hello there!</h2>
重构实战
首先看下我们的目录结构。其中,src里的是源文件,dest目录里是编译生成的文件。可以猛击这里下载demo。
├── demo.js
├── package.json
├── dest
│ └── index.html
└── src
├── index.html
└── main.js
我们看下src/index.html,里面的main.js就是我们最终要内嵌的目标。let's go
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>cheerio demo</title>
</head>
<body>
<h1>cheerio demo</h1>
<script src="main.js?__inline"></script>
</body>
</html>
先看成果
在控制台敲如下命令,就会生成dest/index.html。下一节我们会讲下demo.js的实现
npm install
node demo.js
dest/index.html如下。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>cheerio demo</title>
</head>
<body>
<h1>cheerio demo</h1>
<script>/**
* Created by a on 14-7-15.
*/
var Main = {
say: function(msg){
console.log(msg);
}
};</script>
</body>
</html>
demo.js代码解析
直接上demo.js的代码,一切尽在不言中。如果想更近一步,完成css资源、img资源的内嵌,非常简单,参照script内嵌的那部分代码就可以了。需要压缩代码?赶紧用uglifyjs啦,so easy,这里就不占用篇幅讲这个了。
/**
* Created by a on 14-7-15.
*/
var cheerio = require('cheerio'), // 主角 cheerio
fs = require('fs'),
url = require('url'),
path = require('path');
var from = 'src/index.html', // 源文件
to = 'dest/index.html', // 最终生成的文件
content = fs.readFileSync(from),
$ = cheerio.load(content), // 加载源文件
fd = 0;
// 选取 src/index.html 里所有的script标签,并将带有 __inline 标记的内嵌
$('script').each(function(index, script){
var script = $(this),
src = script.attr('src'),
urlObj = url.parse(src),
dir = path.dirname(from),
pathname = path.resolve(dir, urlObj.pathname),
scriptContent = '';
// 关键步骤:__inline 检测!(ps:非严谨写法)
if(urlObj.search.indexOf('__inline')!=-1){
scriptContent = fs.readFileSync(pathname);
script.replaceWith('<script>'+ scriptContent +'</script>');
}
});
// 创建dest目录
if(!fs.exists(path.dirname(to))){
fs.mkdirSync(path.dirname(to));
}
// 将处理完的文件写回去
fd = fs.openSync(to, 'w');
fs.writeFileSync(to, $.html());
fs.closeSync(fd);
写在后面
没什么好写的其实,求勘误~
巧用cheerio重构grunt-inline的更多相关文章
- eclipse重构详解(转)
重构是对软件内部结构的一种调整,目的是在不改变软件行为的前提下,提高其可理解性,降低其修改成本.开发人员可以使用一系列重构准则,在不改变软件行为的前提下,调整软件的结构. 有很多种原因,开发人员应该重 ...
- Yeoman的好基友:Grunt
grunt介绍 前端不能承受之痛 1.这是我们的生活 文件压缩:YUI Compressor.Google Closure 文件合并:fiddler + qzmin 文件校验:jshint 雪碧图:c ...
- 题解 P5065 【[Ynoi2014]不归之人与望眼欲穿的人们】
出现了一篇跑得炒鸡慢的题解! noteskey 无 fuck 说,好像就是整个数列分块然后合并区间...什么的吧 对于每块内部就是算一下前缀信息.后缀信息(就是以 第一个点/最后一个点 为一个边界,不 ...
- grunt-inline:一个资源内嵌插件
一.插件简介 将引用的外部资源,如js.css.img等,内嵌到引用它们的文件里去. 二.使用场景 在项目中,出于某些原因,有的时候我们需要将一些资源,比如js脚本内嵌到页面中去.比如我们的html页 ...
- kd-tree 小结
核心思想 是一种分割 \(k\) 维数据空间的数据结构 一维情况下就是平衡树,以 \(key\) 为标准判断插入左儿子还是右儿子 \(kdtree\) 就是平衡树在多维空间的扩展 因为有多维,我们按不 ...
- 『重构--改善既有代码的设计』读书笔记----Inline Class
如果某个类没有做太多的事情,你可以将这个类的所有特性搬移到另外一个类中,然后删除原类.可以看到,Inline Class正好和Extract Class相反,后者是将一个巨类分解成多个小类从而来分担责 ...
- 重构改善既有代码设计--重构手法13:Inline Class (将类内联化)
某个类没有做太多事情.将这个类的所有特性搬移到另一个类中,然后移除原类. 动机:Inline Class (将类内联化)正好于Extract Class (提炼类)相反.如果一个类不再承担足够责任.不 ...
- 重构改善既有代码设计--重构手法02:Inline Method (内联函数)& 03: Inline Temp(内联临时变量)
Inline Method (内联函数) 一个函数调用的本体与名称同样清楚易懂.在函数调用点插入函数体,然后移除该函数. int GetRating() { return MoreThanfiveLa ...
- VS插件CodeRush for Visual Studio发布v19.1.5|新的Inline Lambda重构
CodeRush是一个强大的Visual Studio .NET 插件,它利用整合技术,通过促进开发者和团队效率来提升开发者体验.CodeRush能帮助你以极高的效率创建和维护源代码.Consume- ...
随机推荐
- CentOS配置rsyslog Serve
CentOS6配置rsyslog Server: vi /etc/rsyslog.conf: #启用如下tcp支持: $ModLoad imtcp $InputTCPServerRun 514 #添加 ...
- 【待补充】[Spark Core] Spark 实现标签生成
0. 说明 在 IDEA 中编写 Spark 代码实现将 JSON 数据转换成标签,分别用 Scala & Java 两种代码实现. 1. 准备 1.1 pom.xml <depend ...
- facebook api & oauth protocal
http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-10.5 http://stackoverflow.com/questions/14 ...
- 关于react的一点工作总结
首先,react是Facebook开发的一套前端框架,仅仅是MVC中的V.核心思想是“封装组件”,组件封装后可以作为一个独立的实体被引入到新的组件中,这样新的组件就又是一个实体了,由于组件的实现了可复 ...
- Spring IOC 之 SmartInitializingSingleton
使用 实现该接口后,当所有单例 bean 都初始化完成以后, 容器会回调该接口的方法 afterSingletonsInstantiated. 主要应用场合就是在所有单例 bean 创建完成之后,可以 ...
- unlimited 控制
- rest_framework源码分析
CBV&APIView '''原生django as_view方法''' class View(object): http_method_names = ['get', 'post', 'pu ...
- Python2.7-time
time模块,与datetime模块功能有所重合,time较为简单明了,若只需要当前时间或日期或是sleep,直接用time模块,需要更复杂的时间间隔等情况用datetime模块更好 1.获得time ...
- 多模匹配算法之Aho-Corasick
除剔除那些含有敏感词的文本,由于有大量的敏感词,所以通过简单的正则表达式和字符串查找的方式效率太低,每次都有遍历一次字符串.而AC算法的核心思想就是避免不必要的回溯使搜索一直沿着向前的方向,最大可能的 ...
- Linux服务器安全之 fail2ban的安装与配置
近日在查看Nginx的访问日志中,发现了大量404请求,仔细研究一番发现有人正在试图爆破网站. 我刚上线你就企图攻击我?????? 这怎么能忍.. 于是乎 --- 查资料后得知有一个神奇的工具 fai ...