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