index.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. 'use strict';
  2. var fs = require('fs');
  3. var path = require('path');
  4. var xtend = require('xtend');
  5. var crypto = require('crypto');
  6. var loadeds = {};
  7. var extensions = xtend(require.extensions);
  8. function getHash(data) {
  9. return crypto
  10. .createHash('md5')
  11. .update(data)
  12. .digest('hex');
  13. }
  14. /**
  15. * Activates deduping for files with the given extension.
  16. *
  17. * @name activate
  18. * @function
  19. * @param ext {String} (optional) extension for which to activate deduping (default: '.js')
  20. * @param subdirs {Number} (optional) how many subdirs right above the module
  21. * have to be the same in order for it to be considered identical (default: 2)
  22. *
  23. * Example: sudirs: 2 -- x/foo/bar/main.js === y/foo/bar/main.js
  24. * x/boo/bar/main.js !== y/foo/bar/main.js
  25. */
  26. exports.activate = function (ext, subdirs) {
  27. ext = ext || '.js';
  28. subdirs = typeof subdirs === 'undefined' ? 2 : subdirs;
  29. var ext_super = require.extensions[ext];
  30. require.extensions[ext] = function dedupingExtension(module, file) {
  31. var src = fs.readFileSync(file, 'utf8');
  32. // hash includes filename and subdir name(s) to make override more strict
  33. var fulldir = path.dirname(file);
  34. var dirs = fulldir.split(path.sep);
  35. var dir = '';
  36. for (var i = subdirs; i > 0 && dirs.length; i--) dir = dirs.pop() + dir;
  37. var filename = path.basename(file);
  38. var hash = getHash(src + dir + filename);
  39. var loaded = loadeds[hash];
  40. if (loaded) {
  41. module.exports = loaded.module.exports;
  42. } else {
  43. ext_super(module, file);
  44. loadeds[hash] = { file: file, module: module };
  45. }
  46. };
  47. };
  48. /**
  49. * Deactivates deduping files with the given extension.
  50. *
  51. * @name deactivate
  52. * @function
  53. * @param ext {String} (optional) extension for which to activate deduping (default: '.js')
  54. */
  55. exports.deactivate = function (ext) {
  56. ext = ext || '.js';
  57. require.extensions[ext] = extensions[ext];
  58. };
  59. /**
  60. * Clears the registry that contains previously loaded modules.
  61. *
  62. * @name reset
  63. * @function
  64. */
  65. exports.reset = function () {
  66. loadeds = {};
  67. };