index.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. 'use strict';
  2. var js = require('default-require-extensions/js');
  3. module.exports = appendTransform;
  4. var count = 0;
  5. function appendTransform(transform, ext, extensions) {
  6. // Generate a unique key for this transform
  7. var key = __dirname + count; // eslint-disable-line
  8. count++;
  9. ext = ext || '.js';
  10. extensions = extensions || require.extensions;
  11. var forwardGet;
  12. var forwardSet;
  13. var descriptor = Object.getOwnPropertyDescriptor(extensions, ext) || {value: js, configurable: true};
  14. if (
  15. ((descriptor.get || descriptor.set) && !(descriptor.get && descriptor.set)) ||
  16. !descriptor.configurable
  17. ) {
  18. throw new Error('Somebody did bad things to require.extensions["' + ext + '"]');
  19. }
  20. if (descriptor.get) {
  21. // wrap a previous append-transform install and pass through to the getter/setter pair it created
  22. forwardGet = function () {
  23. return descriptor.get();
  24. };
  25. forwardSet = function (val) {
  26. descriptor.set(val);
  27. return forwardGet();
  28. };
  29. } else {
  30. forwardGet = function () {
  31. return descriptor.value;
  32. };
  33. forwardSet = function (val) {
  34. descriptor.value = val;
  35. return val;
  36. };
  37. }
  38. function wrapCustomHook(hook) {
  39. return function (module, filename) {
  40. // We wrap every added extension, but we only apply the transform to the one on top of the stack
  41. if (!module[key]) {
  42. module[key] = true;
  43. var originalCompile = module._compile;
  44. module._compile = function replacementCompile(code, filename) {
  45. module._compile = originalCompile;
  46. code = transform(code, filename);
  47. module._compile(code, filename);
  48. };
  49. }
  50. hook(module, filename);
  51. };
  52. }
  53. // wrap the original
  54. forwardSet(wrapCustomHook(forwardGet()));
  55. var hooks = [forwardGet()];
  56. function setCurrentHook(hook) {
  57. var restoreIndex = hooks.indexOf(hook);
  58. if (restoreIndex === -1) {
  59. hooks.push(forwardSet(wrapCustomHook(hook)));
  60. } else {
  61. // we have already scene this hook, and it is being reverted (proxyquire, etc) - don't wrap again.
  62. hooks.splice(restoreIndex + 1, hooks.length);
  63. forwardSet(hook);
  64. }
  65. }
  66. Object.defineProperty(extensions, ext, {
  67. configurable: true,
  68. enumerable: true,
  69. get: forwardGet,
  70. set: setCurrentHook
  71. });
  72. }