Advertisement
Guest User

Untitled

a guest
Jul 20th, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.25 KB | None | 0 0
  1. /**
  2. * Created by zuozhuo on 2017/7/20.
  3. */
  4. 'use strict'
  5.  
  6. const through = require('through2');
  7. const gutil = require('gulp-util');
  8. const path = require('path');
  9. const gulp = require('gulp');
  10. const gulpRename = require('gulp-rename');
  11. const url = require('url');
  12. const crypto = require('crypto');
  13. const fs = require('fs');
  14.  
  15. /*
  16. 测试用例:
  17. <link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png">
  18. <link rel="manifest" href="/favicons/manifest.json">
  19. <link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#A92119">
  20. <link rel="stylesheet" href="/index.css">
  21. <script src="/index.js"></script>
  22. <link rel="stylesheet" href="//at.alicdn.com/t/font_u3v0book0tsurf6r.css">
  23. <div style="background-image:url(/abc.jpg)"></div>
  24. */
  25.  
  26. const PLUGIN_NAME = 'gulp-html-cache-buster';
  27. const REGEX_STATIC_FILE_IN_HTML = /(src|href)\s*?\=\s*?[\"\'\(]\s*?(((\{\{[^\"\'\(\)]*?\}\})?[^\"\'\(\)]*?\.(jpg|jpeg|png|gif|cur|js|css|json|svg))(\?[^\"\'\(\)]+?)?)\s*?[\"\'\)]/gmi;
  28. const REGEX_STATIC_FILE_IN_CSS = /(url)\s*?\(\s*?[\"\']?([^\)]*?\.(jpg|jpeg|png|gif|cur|js|css|json|svg))[\"\']?\s*?\)/gmi;
  29.  
  30. function getFileMd5String(filePath) {
  31. const buffer = fs.readFileSync(filePath);
  32. return crypto.createHash('md5').update(buffer).digest("hex");
  33. }
  34.  
  35. function copyToHashNamedFile(file, hash) {
  36. const dir = path.dirname(file);
  37. const fileName = path.basename(file);
  38. if (fileName.indexOf(hash) === 0) {
  39. console.log(`文件${fileName}已经进过hash处理,跳过`);
  40. return fileName
  41. }
  42. const newFileName = hash + '.' + fileName;
  43. // 复制成带md5的文件
  44. gulp.src(file)
  45. .pipe(gulpRename(function (_path) {
  46. _path.basename = path.basename(newFileName, _path.extname);
  47. }))
  48. .pipe(gulp.dest(dir));
  49. //.pipe($.size({title: 'static_rename: ' + newFileName}))
  50. // .pipe(gulp.src(file, {read: false}))
  51. // .pipe($.clean())
  52. // 删除原文件容易报错
  53. //
  54. // .pipe($.clean())
  55.  
  56. return newFileName;
  57. }
  58.  
  59. function replaceContent(staticRoot, content, fullUrl, staticFile) {
  60. var fullPath, urlObj, newFullUrl, md5HashPrefix, newFileName;
  61.  
  62.  
  63. // 替换{{ STATIC_URL }}为/static/
  64. var STATIC_URL_REG = /\{\{\s*?STATIC_URL\s*?\}\}/gmi;
  65. staticFile = staticFile.replace(STATIC_URL_REG, '/static/');
  66.  
  67. fullPath = path.join(staticRoot, staticFile);
  68. if (fs.existsSync(fullPath)) {
  69. console.log('找到static文件:', fullPath);
  70.  
  71. md5HashPrefix = 'c' + getFileMd5String(fullPath).slice(0, 8);
  72. newFileName = copyToHashNamedFile(fullPath, md5HashPrefix);
  73.  
  74. urlObj = url.parse(fullUrl);
  75. urlObj.pathname = path.join(path.dirname(urlObj.pathname), newFileName);
  76. newFullUrl = url.format(urlObj);
  77.  
  78. // 纠正format函数中对{{ STATIC_URL }}的encode,以便还原{{ STATIC_URL }}
  79. // 0.10.33 是这种格式
  80. newFullUrl = newFullUrl.replace(/\{\{(%20)*?STATIC_URL(%20)*?\}\}/gim, '{{ STATIC_URL }}');
  81. // 0.12.4 是这种格式
  82. newFullUrl = newFullUrl.replace(/%7B%7B(%20)*?STATIC_URL(%20)*?%7D%7D/gim, '{{ STATIC_URL }}');
  83.  
  84. content = content.replace(fullUrl, newFullUrl);
  85.  
  86. console.log('替换md5:', newFullUrl)
  87. } else {
  88.  
  89. }
  90. return content;
  91. }
  92.  
  93.  
  94. // 给模板html的css和js增加版本hash
  95. function plugin(staticRoot) {
  96.  
  97. return through.obj(function (file, enc, callback) {
  98. let contents;
  99.  
  100. if (file.isNull()) {
  101. this.push(file);
  102. return callback();
  103. }
  104.  
  105. if (file.isStream()) {
  106. this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streams are not supported!'));
  107. return callback();
  108. }
  109.  
  110. console.log('搜索HTML:', file.path);
  111.  
  112. contents = file.contents.toString().replace(REGEX_STATIC_FILE_IN_HTML, function (content, prop, fullUrl, staticFile) {
  113. //content, prop, fullUrl, staticFile
  114. var fullPath, urlObj, newFullUrl, md5HashPrefix, newFileName;
  115.  
  116. console.log(`fullUrl: ${fullUrl}`)
  117. console.log(`staticFile: ${staticFile}`)
  118.  
  119. content = replaceContent(staticRoot, content, fullUrl, staticFile);
  120.  
  121. return content
  122.  
  123. });
  124. contents = contents.replace(REGEX_STATIC_FILE_IN_CSS, function (content, a1, fileUrl, a3, a4, a5) {
  125.  
  126. content = replaceContent(staticRoot, content, fileUrl, fileUrl);
  127.  
  128. return content;
  129. });
  130.  
  131.  
  132. file.contents = new Buffer(contents);
  133.  
  134. this.push(file);
  135. return callback();
  136. });
  137. }
  138.  
  139. module.exports = plugin;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement