文章出處
文章列表
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);
寫在后面
沒什么好寫的其實,求勘誤~
文章列表
全站熱搜