• 巧用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);
    

    写在后面

    没什么好写的其实,求勘误~

  • 相关阅读:
    三伏天,华为路由器 AX3 PRO 发热严重,网络断流,改装散热清凉一夏
    MVC扩展(ControllerFactory VS DependencyResolver)
    MVC扩展(Templated Razor Delegates)
    RouteDebugger分析
    MVC扩展(ModelBinder)
    ORACLE 创建多个游标并嵌套循环
    java final初解
    oracle partition by 与 partition by ... order by 分组
    JS实现函数重载2
    使用XslCompiledTransform将XML 转HTML
  • 原文地址:https://www.cnblogs.com/chyingp/p/3844003.html
Copyright © 2020-2023  润新知