1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | const _ = require('lodash');
|
9 | const fs = require('fs');
|
10 | const Module = require('module');
|
11 |
|
12 | const originalWrapper = Module.wrapper.slice(0);
|
13 | const requizzleWrappers = {
|
14 | extras: require('./wrappers/extras'),
|
15 | requirePaths: require('./wrappers/requirepaths'),
|
16 | strict: require('./wrappers/strict')
|
17 | };
|
18 |
|
19 | function wrap(wrappers, script) {
|
20 | return wrappers[0] + script + wrappers[1];
|
21 | }
|
22 |
|
23 | function replaceWrapper(wrapperObj) {
|
24 | const joiner = '\n';
|
25 | const before = wrapperObj.before.join(joiner);
|
26 | const after = wrapperObj.after.join(joiner);
|
27 | const wrappers = [
|
28 | originalWrapper[0] + before,
|
29 | after + originalWrapper[1]
|
30 | ];
|
31 |
|
32 | Module.wrap = wrap.bind(null, wrappers);
|
33 | }
|
34 |
|
35 | function restoreWrapper() {
|
36 | Module.wrap = wrap.bind(null, originalWrapper);
|
37 | }
|
38 |
|
39 | function createModule(targetPath, parentModule, moduleCache) {
|
40 | moduleCache[targetPath] = moduleCache[targetPath] || new Module(targetPath, parentModule);
|
41 |
|
42 | return moduleCache[targetPath];
|
43 | }
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 | function requireProxy(targetModule, nodeRequire, filepath) {
|
54 | restoreWrapper();
|
55 | targetModule.require = nodeRequire;
|
56 |
|
57 | return nodeRequire.call(targetModule, filepath);
|
58 | }
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 | function infectProxy(targetModule, cache, opts, filepath) {
|
70 | let moduleExports;
|
71 |
|
72 | const Requizzle = require('./requizzle');
|
73 | let requizzle;
|
74 |
|
75 | opts = _.clone(opts);
|
76 | opts.parent = targetModule;
|
77 | requizzle = new Requizzle(opts, cache);
|
78 |
|
79 | moduleExports = requizzle.requizzle(filepath);
|
80 |
|
81 | return moduleExports;
|
82 | }
|
83 |
|
84 | exports.load = function load(targetPath, parentModule, wrapper, cache, options) {
|
85 | let nodeRequire;
|
86 | let targetModule;
|
87 |
|
88 |
|
89 | if (cache.module[targetPath]) {
|
90 | return cache.module[targetPath];
|
91 | }
|
92 |
|
93 | targetModule = createModule(targetPath, parentModule, cache.module);
|
94 | nodeRequire = targetModule.require;
|
95 |
|
96 | if (options.infect) {
|
97 | targetModule.require = filepath => infectProxy(targetModule, cache, options, filepath);
|
98 | } else {
|
99 | targetModule.require = filepath => requireProxy(targetModule, nodeRequire, filepath);
|
100 | }
|
101 |
|
102 |
|
103 | replaceWrapper(wrapper);
|
104 |
|
105 | targetModule.load(targetModule.id);
|
106 |
|
107 |
|
108 | restoreWrapper();
|
109 |
|
110 | return targetModule;
|
111 | };
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 | function detectStrictMode(src) {
|
120 | return (/^\s*(?:["']use strict["'])[ \t]*(?:[\r\n]|;)/g).test(src);
|
121 | }
|
122 |
|
123 | function loadSource(targetPath, sourceCache) {
|
124 | if (sourceCache[targetPath] === undefined) {
|
125 | sourceCache[targetPath] = fs.readFileSync(targetPath, 'utf8');
|
126 | }
|
127 |
|
128 | return sourceCache[targetPath];
|
129 | }
|
130 |
|
131 | exports.createWrapper = function createWrapper(targetPath, parentModule, cache, options) {
|
132 | let src;
|
133 | const wrapperObject = {
|
134 | before: [],
|
135 | after: []
|
136 | };
|
137 |
|
138 | function add(wrapperFunctions, opts) {
|
139 | const params = [targetPath, parentModule, opts];
|
140 |
|
141 | ['before', 'after'].forEach(item => {
|
142 | const result = wrapperFunctions[item].apply(null, params);
|
143 |
|
144 | if (result) {
|
145 | wrapperObject[item].push(result);
|
146 | }
|
147 | });
|
148 | }
|
149 |
|
150 |
|
151 | src = loadSource(targetPath, cache.source);
|
152 | if (detectStrictMode(src) === true) {
|
153 | add(requizzleWrappers.strict);
|
154 | }
|
155 |
|
156 | if (options.requirePaths) {
|
157 | add(requizzleWrappers.requirePaths, options.requirePaths);
|
158 | }
|
159 |
|
160 | if (options.extras) {
|
161 | add(requizzleWrappers.extras, options.extras);
|
162 | }
|
163 |
|
164 | return wrapperObject;
|
165 | };
|