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的更多相关文章

  1. eclipse重构详解(转)

    重构是对软件内部结构的一种调整,目的是在不改变软件行为的前提下,提高其可理解性,降低其修改成本.开发人员可以使用一系列重构准则,在不改变软件行为的前提下,调整软件的结构. 有很多种原因,开发人员应该重 ...

  2. Yeoman的好基友:Grunt

    grunt介绍 前端不能承受之痛 1.这是我们的生活 文件压缩:YUI Compressor.Google Closure 文件合并:fiddler + qzmin 文件校验:jshint 雪碧图:c ...

  3. 题解 P5065 【[Ynoi2014]不归之人与望眼欲穿的人们】

    出现了一篇跑得炒鸡慢的题解! noteskey 无 fuck 说,好像就是整个数列分块然后合并区间...什么的吧 对于每块内部就是算一下前缀信息.后缀信息(就是以 第一个点/最后一个点 为一个边界,不 ...

  4. grunt-inline:一个资源内嵌插件

    一.插件简介 将引用的外部资源,如js.css.img等,内嵌到引用它们的文件里去. 二.使用场景 在项目中,出于某些原因,有的时候我们需要将一些资源,比如js脚本内嵌到页面中去.比如我们的html页 ...

  5. kd-tree 小结

    核心思想 是一种分割 \(k\) 维数据空间的数据结构 一维情况下就是平衡树,以 \(key\) 为标准判断插入左儿子还是右儿子 \(kdtree\) 就是平衡树在多维空间的扩展 因为有多维,我们按不 ...

  6. 『重构--改善既有代码的设计』读书笔记----Inline Class

    如果某个类没有做太多的事情,你可以将这个类的所有特性搬移到另外一个类中,然后删除原类.可以看到,Inline Class正好和Extract Class相反,后者是将一个巨类分解成多个小类从而来分担责 ...

  7. 重构改善既有代码设计--重构手法13:Inline Class (将类内联化)

    某个类没有做太多事情.将这个类的所有特性搬移到另一个类中,然后移除原类. 动机:Inline Class (将类内联化)正好于Extract Class (提炼类)相反.如果一个类不再承担足够责任.不 ...

  8. 重构改善既有代码设计--重构手法02:Inline Method (内联函数)& 03: Inline Temp(内联临时变量)

    Inline Method (内联函数) 一个函数调用的本体与名称同样清楚易懂.在函数调用点插入函数体,然后移除该函数. int GetRating() { return MoreThanfiveLa ...

  9. VS插件CodeRush for Visual Studio发布v19.1.5|新的Inline Lambda重构

    CodeRush是一个强大的Visual Studio .NET 插件,它利用整合技术,通过促进开发者和团队效率来提升开发者体验.CodeRush能帮助你以极高的效率创建和维护源代码.Consume- ...

随机推荐

  1. CentOS配置rsyslog Serve

    CentOS6配置rsyslog Server: vi /etc/rsyslog.conf: #启用如下tcp支持: $ModLoad imtcp $InputTCPServerRun 514 #添加 ...

  2. 【待补充】[Spark Core] Spark 实现标签生成

    0. 说明 在 IDEA 中编写 Spark 代码实现将 JSON 数据转换成标签,分别用 Scala & Java 两种代码实现. 1. 准备 1.1 pom.xml  <depend ...

  3. facebook api & oauth protocal

    http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-10.5 http://stackoverflow.com/questions/14 ...

  4. 关于react的一点工作总结

    首先,react是Facebook开发的一套前端框架,仅仅是MVC中的V.核心思想是“封装组件”,组件封装后可以作为一个独立的实体被引入到新的组件中,这样新的组件就又是一个实体了,由于组件的实现了可复 ...

  5. Spring IOC 之 SmartInitializingSingleton

    使用 实现该接口后,当所有单例 bean 都初始化完成以后, 容器会回调该接口的方法 afterSingletonsInstantiated. 主要应用场合就是在所有单例 bean 创建完成之后,可以 ...

  6. unlimited 控制

  7. rest_framework源码分析

    CBV&APIView '''原生django as_view方法''' class View(object): http_method_names = ['get', 'post', 'pu ...

  8. Python2.7-time

    time模块,与datetime模块功能有所重合,time较为简单明了,若只需要当前时间或日期或是sleep,直接用time模块,需要更复杂的时间间隔等情况用datetime模块更好 1.获得time ...

  9. 多模匹配算法之Aho-Corasick

    除剔除那些含有敏感词的文本,由于有大量的敏感词,所以通过简单的正则表达式和字符串查找的方式效率太低,每次都有遍历一次字符串.而AC算法的核心思想就是避免不必要的回溯使搜索一直沿着向前的方向,最大可能的 ...

  10. Linux服务器安全之 fail2ban的安装与配置

    近日在查看Nginx的访问日志中,发现了大量404请求,仔细研究一番发现有人正在试图爆破网站. 我刚上线你就企图攻击我?????? 这怎么能忍.. 于是乎 --- 查资料后得知有一个神奇的工具 fai ...