Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Created by zuozhuo on 2017/7/20.
- */
- 'use strict'
- const through = require('through2');
- const gutil = require('gulp-util');
- const path = require('path');
- const gulp = require('gulp');
- const gulpRename = require('gulp-rename');
- const url = require('url');
- const crypto = require('crypto');
- const fs = require('fs');
- /*
- 测试用例:
- <link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png">
- <link rel="manifest" href="/favicons/manifest.json">
- <link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#A92119">
- <link rel="stylesheet" href="/index.css">
- <script src="/index.js"></script>
- <link rel="stylesheet" href="//at.alicdn.com/t/font_u3v0book0tsurf6r.css">
- <div style="background-image:url(/abc.jpg)"></div>
- */
- const PLUGIN_NAME = 'gulp-html-cache-buster';
- const REGEX_STATIC_FILE_IN_HTML = /(src|href)\s*?\=\s*?[\"\'\(]\s*?(((\{\{[^\"\'\(\)]*?\}\})?[^\"\'\(\)]*?\.(jpg|jpeg|png|gif|cur|js|css|json|svg))(\?[^\"\'\(\)]+?)?)\s*?[\"\'\)]/gmi;
- const REGEX_STATIC_FILE_IN_CSS = /(url)\s*?\(\s*?[\"\']?([^\)]*?\.(jpg|jpeg|png|gif|cur|js|css|json|svg))[\"\']?\s*?\)/gmi;
- function getFileMd5String(filePath) {
- const buffer = fs.readFileSync(filePath);
- return crypto.createHash('md5').update(buffer).digest("hex");
- }
- function copyToHashNamedFile(file, hash) {
- const dir = path.dirname(file);
- const fileName = path.basename(file);
- if (fileName.indexOf(hash) === 0) {
- console.log(`文件${fileName}已经进过hash处理,跳过`);
- return fileName
- }
- const newFileName = hash + '.' + fileName;
- // 复制成带md5的文件
- gulp.src(file)
- .pipe(gulpRename(function (_path) {
- _path.basename = path.basename(newFileName, _path.extname);
- }))
- .pipe(gulp.dest(dir));
- //.pipe($.size({title: 'static_rename: ' + newFileName}))
- // .pipe(gulp.src(file, {read: false}))
- // .pipe($.clean())
- // 删除原文件容易报错
- //
- // .pipe($.clean())
- return newFileName;
- }
- function replaceContent(staticRoot, content, fullUrl, staticFile) {
- var fullPath, urlObj, newFullUrl, md5HashPrefix, newFileName;
- // 替换{{ STATIC_URL }}为/static/
- var STATIC_URL_REG = /\{\{\s*?STATIC_URL\s*?\}\}/gmi;
- staticFile = staticFile.replace(STATIC_URL_REG, '/static/');
- fullPath = path.join(staticRoot, staticFile);
- if (fs.existsSync(fullPath)) {
- console.log('找到static文件:', fullPath);
- md5HashPrefix = 'c' + getFileMd5String(fullPath).slice(0, 8);
- newFileName = copyToHashNamedFile(fullPath, md5HashPrefix);
- urlObj = url.parse(fullUrl);
- urlObj.pathname = path.join(path.dirname(urlObj.pathname), newFileName);
- newFullUrl = url.format(urlObj);
- // 纠正format函数中对{{ STATIC_URL }}的encode,以便还原{{ STATIC_URL }}
- // 0.10.33 是这种格式
- newFullUrl = newFullUrl.replace(/\{\{(%20)*?STATIC_URL(%20)*?\}\}/gim, '{{ STATIC_URL }}');
- // 0.12.4 是这种格式
- newFullUrl = newFullUrl.replace(/%7B%7B(%20)*?STATIC_URL(%20)*?%7D%7D/gim, '{{ STATIC_URL }}');
- content = content.replace(fullUrl, newFullUrl);
- console.log('替换md5:', newFullUrl)
- } else {
- }
- return content;
- }
- // 给模板html的css和js增加版本hash
- function plugin(staticRoot) {
- return through.obj(function (file, enc, callback) {
- let contents;
- if (file.isNull()) {
- this.push(file);
- return callback();
- }
- if (file.isStream()) {
- this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streams are not supported!'));
- return callback();
- }
- console.log('搜索HTML:', file.path);
- contents = file.contents.toString().replace(REGEX_STATIC_FILE_IN_HTML, function (content, prop, fullUrl, staticFile) {
- //content, prop, fullUrl, staticFile
- var fullPath, urlObj, newFullUrl, md5HashPrefix, newFileName;
- console.log(`fullUrl: ${fullUrl}`)
- console.log(`staticFile: ${staticFile}`)
- content = replaceContent(staticRoot, content, fullUrl, staticFile);
- return content
- });
- contents = contents.replace(REGEX_STATIC_FILE_IN_CSS, function (content, a1, fileUrl, a3, a4, a5) {
- content = replaceContent(staticRoot, content, fileUrl, fileUrl);
- return content;
- });
- file.contents = new Buffer(contents);
- this.push(file);
- return callback();
- });
- }
- module.exports = plugin;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement