nodejs给文件链接添加md5

nodejs给文件链接添加md5

月光魔力鸭

2018-09-12 10:11 阅读 435 喜欢 0 md5 link nodejs

在开发的时候,经常会有css js 文件的变更,然后部署后发现没有起到作用,最终发现是缓存的问题,如何来方便的解决。

因为没有用到webpack 啥的,是java项目,所以准备做一个小工具,检索jsp或html中引用css js的地方,并根据对应的路径找到文件,对文件进行md5计算,最后给链接更新一个md5值,这样没有变化的就会缓存,有变化的就会从服务器更新。 (大神请轻喷..)

大体思路
  1. 检索目标目录下的jsp 或 html
  2. 读取内容,根据正则找到 link 或 script
  3. 根据规则,找到对应的目录的文件
  4. 读取文件,计算MD5
  5. 更新回原来的地址
  6. 结束
代码实现

准备使用nodejs 来实现。

//给jsp 或 html 中的css js 添加fileMd5值
var fs = require('fs'),
    readline = require('readline'),
    path = require('path'),
    join = path.join,
    extname = path.extname,
    async = require('async'),
    colors = require('colors'),
    url = require('url'),
    crypto = require('crypto'),
    qs = require('querystring');

function AddMd5(directory,opts){
    this.directory = directory;
    this.fileList = [];
    this.count = 0;
    this.extList = opts.extList;//['.jsp','.html','.htm'];
    this.exclude = opts.exclude;//['plugins'];
    this.compress = opts.compress;
    this.replace = opts.replace;//['${basepath}','${staticresdomain}','<%=basepath%>'];//替换字符串
    return this;
}
//获得符合条件的文件
AddMd5.prototype.getFiles = function(dirPath){
    var thiz = this;
    if(fs.existsSync(dirPath)){
        var files = fs.readdirSync(dirPath);
        if(files && files.length > 0){
            for(var i=0,max=files.length;i<max;i++){
                var temp = files[i];
                var filePath = join(dirPath,temp);
                var stats = fs.statSync(filePath);
                if(stats.isDirectory() && thiz.exclude.indexOf(temp) < 0){
                    //继续
                    thiz.getFiles(filePath);
                }else{
                    var fileExt = extname(filePath).toLowerCase();
                    if(thiz.extList.indexOf(fileExt) > -1){
                        //符合
                        thiz.fileList.push(filePath);
                    }
                }
            }
        }
    }
}
AddMd5.prototype.start = function(){
    var thiz = this,
        directory = thiz.directory;
    thiz.getFiles(directory);
    console.log('共计扫描到 '.green+(''+thiz.fileList.length).red+' 个符合条件的文件'.green);
    async.mapLimit(thiz.fileList,5,function(item,cb){
        thiz.scan(item,cb);
    },function(err,value){
        console.log('共计替换 '.green+(''+thiz.count).red +' 个链接'.green)
    });
};

AddMd5.prototype.scan = function(filePath,callback){
    var thiz = this,compress = thiz.compress;
    var is = fs.createReadStream(filePath);
    var inter = readline.createInterface({input :is});
    var strArr = '';
    inter.on('line',function(line){
        var rst = thiz.checkLine(line);
        if(rst){//检查到有内容
            //处理并替换
            var type = rst.type;
            var md5 = rst.md5;
            //检索并替换
            var arr = /src[\s]*=[\s]*[\"\']?([^\'\"]*)[\'\"]?/i.exec(line);
            if(arr && arr.length > 0){
                var src = arr[1];
                var query = url.parse(src).query;
                var src2 = src.indexOf('?') > -1 ? src.substring(0,src.indexOf('?')) : src;
                var qsObj = qs.parse(query);
                qsObj.v = md5.substring(0,5);
                var qsStr = qs.stringify(qsObj);
                var newSrc= src2 + '?'+qsStr;
                line = line.replace(src,newSrc);
                console.log('替换 [ '.green+line.red+' ]'.green);
                thiz.count ++ ;
            }
        }
        strArr+=line+(compress ? '' : '\n');
    });
    inter.on('close',function(){
        //重新写入
        fs.writeFileSync(filePath,strArr);
        callback(null,null);
    })
};
//根据文件路径获得FILEMD5
AddMd5.prototype.getMd5 = function(filePath){
    var buffer = fs.readFileSync(filePath);
    var md5 = crypto.createHash('md5');
    md5.update(buffer);
    return md5.digest('hex').toLowerCase();
};
AddMd5.prototype.checkLine = function(str){
    //检查字符串是否符合 link script 
    var thiz = this,replace = thiz.replace,directory = thiz.directory;
    str = str.toLowerCase().replace(/\s/g,'');
    var rst = /\<script[\s\S]*src="([\$\{\}\w\.\/\<\%\=\>\?\&]*)"[\s\S]*\>[\s\S]*\<\/script\>/g.exec(str);
    var src = '';
    var type = '';
    if(rst && rst.length > 0){
        src = rst[1];
        type = 'src';
    }
    rst = /^\<link[\s\S]*href="([\$\{\}\w\.\/\<\%\=\>\?\&]*)"[\s\S]*[\>|\/\>|\<\/link\>]$/g.exec(str);
    if(rst && rst.length > 0 && rst[1].indexOf('favicon') < 0){
        src = rst[1];
        type = 'href';
    }
    if(src){
        if(replace && replace.length > 0){
            for(var i=0,max=replace.length;i<max;i++){
                src = src.replace(replace[i],'');
            }
        }
        var srcObj = url.parse(src);
        var query = srcObj.query;
        var filePath = join(directory,srcObj.pathname);
        if(fs.existsSync(filePath)){
            var fileMd5 = thiz.getMd5(filePath);
            return {
                md5 : fileMd5,
                query : query,
                filePath : srcObj.pathname,
                type : type
            };
        }
    }
    return null;
};

module.exports = AddMd5;

然后封装了一个命令行工具,这样以后就可以随意对某个目录进行压缩啦,发布后自己安装下就可以啦。

npm install addmd5 -g

具体可以查看 https://github.com/chrunlee/addmd5

写的比较仓促,目前是最初的版本,很多地方还不严谨..尤其是我的正则比较烂。

如果对你有帮助,麻烦点个赞呗

转载请注明出处: https://chrunlee.cn/article/nodejs-add-link-md5.html


感谢支持!

赞赏支持
提交评论
评论信息(请文明评论)
暂无评论,快来快来写想法...
推荐
关于js的编译和压缩,之前做过一个小工具了,主要就是自己项目成员大都没有这部分的技能,导致发布的时候总需要去编译压缩下.. 最终做了个命令行小工具.. 问题不在这里,前一阵子做压缩的时候发现压缩后竟然是undefined.最终才发现是es6的语法问题。
发布自己的nodejs应用后,需要进行管理,目前一般都pm2来进行管理,这里记录下常用的命令。
当我们做爬虫或其他的一些应用的时候,如果需要一些短信验证,但是又没有那么多手机号,又不能放人在那里一直输入的时候?怎么办?
在通过axios读取页面的时候,经常会碰到gbk的编码,如果不进行转化的话,在获取信息或读取上都会很麻烦。
分享一个自动抓取静态站资源的小工具,可以在抓取某个静态站点的时候方便很多,尤其是如果页面比较多的话,会很难受,而且会自动将资源进行归类,如果一个页面一个页面的保存的话,那就比较费劲了。
在我们做运维或者小工具的时候,总会有些需要提醒的事情,比如服务器宕机或者天气提醒,但是发email又会不够及时或者可能会忽略,那么短信就是一个不错的选择了
从豆瓣转到网易云后,发现了不少好听的歌曲,然鹅..当我想把这些歌拿下来扔车上听的时候发现竟然不允许下载..能听不能下?这不科学,作为一名程序猿,必然要迎难而上啊.
最近有接触到针对二维码进行识别的功能,然后对图片进行位置纠正、二维码扫描,并将数据进行整理。以下是通过nodejs做的,相对简单一些,没有太过严格,识别率也不是很高大约80%左右