templateCache.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. const path = require('path');
  2. const gutil = require('gulp-util');
  3. const through = require('through2');
  4. const minify = require('html-minifier').minify;
  5. function replacePlugin(contents, objName) {
  6. const re = new RegExp(`${objName}\\.get\\('(.*?)'\\)`, 'g');
  7. return through.obj(function (file, enc, cb) {
  8. const dirname = path.dirname(file.path);
  9. file.contents = new Buffer(String(file.contents).replace(re, (m, name) => {
  10. const filepath = path.resolve(dirname, name);
  11. const item = contents[filepath];
  12. if (!item) console.warn(`Cache not found: ${name}`);
  13. return `${objName}.get(${item.id})`;
  14. }));
  15. cb(null, file);
  16. });
  17. }
  18. module.exports = function templateCache(objName) {
  19. const contentTpl = `${objName}.put(<%= name %>, <%= content %>);\n`;
  20. const header = `\n\n/* Templates cached with love :) */\n`;
  21. const contents = {};
  22. function bufferContents(file, enc, cb) {
  23. if (file.isNull()) return cb();
  24. if (file.isStream()) return this.emit('error', new gutil.PluginError('VM-cache', 'Stream is not supported.'));
  25. contents[file.path] = {
  26. content: minify(String(file.contents), {
  27. removeComments: true,
  28. collapseWhitespace: true,
  29. conservativeCollapse: true,
  30. removeAttributeQuotes: true,
  31. }),
  32. };
  33. cb();
  34. }
  35. function endStream(cb) {
  36. var keys = Object.keys(contents).sort();
  37. keys.forEach((key, i) => contents[key].id = i + 1);
  38. this.replace = () => replacePlugin(contents, objName);
  39. const templates = keys.map(key => {
  40. const item = contents[key];
  41. return `${objName}.put(${item.id}, ${JSON.stringify(item.content)});`;
  42. }).join('\n');
  43. this.push(new gutil.File({
  44. base: '',
  45. path: 'template.js',
  46. contents: new Buffer(header + templates),
  47. }));
  48. cb();
  49. }
  50. return through.obj(bufferContents, endStream);
  51. };