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
|
"use strict"; // run code in ES5 strict mode
var setterSrc = require("../../__set__.js").toString(),
getterSrc = require("../../__get__.js").toString(),
path = require("path"),
injectRewire = require("../injectRewire.js"),
getRewireRegExp = require("../getRewireRegExp.js"),
rewireLib = path.resolve(__dirname, "../../"),
projectBasePath = path.resolve(__dirname, "../../../../../"),
nodeModulesPath = path.join(projectBasePath, "node_modules"),
webpackPath = path.join("node_modules", "webpack"),
settersAndGettersSrc;
/**
* Injects special code so rewire gains access to the module's private scope.
*
* Furthermore it changes all calls of rewire("some/path") to rewire("some/path", require("some/path")) so webpack
* recognizes the additional dependency. This also enables rewire to resolve the module because webpack replaces all
* paths to numeric ids.
*
* @param {!String} src
* @return {String} src
*/
function webpackPostLoader(src) {
var filename = this.request.split("!").pop(),
rewireRegExp = getRewireRegExp();
if (isRewireableModule(filename)) {
// replaces rewire("some/path") into rewire("some/path", require("some/path"))
src = src.replace(rewireRegExp, '$1rewire("$2", require("$2"))');
// Inject special code
src = injectRewire(src, settersAndGettersSrc);
}
return src;
}
webpackPostLoader.loader = __filename;
webpackPostLoader.test = /\.js$/;
/**
* Returns true if the module is rewireable. Rewireable are all modules of the project.
*
* Example:
* Imagine rewire lies under "~/myProject/node_modules/rewire". All files in "~/myProject" are rewireable except
* the "~/myProject/node_modules"-path.
*
* @param {!String} path
* @return {Boolean}
*/
function isRewireableModule(path) {
return path.indexOf(projectBasePath) !== -1 &&
path.indexOf(nodeModulesPath) === -1 &&
// "rewire/lib" and "node_modules/webpack" are explicitly excluded to make the tests work
path.indexOf(rewireLib) === -1 &&
path.indexOf(webpackPath) === -1;
}
/**
* This string gets injected at the beginning of every module. Its purpose is to
* - register the setters and getters according to the module's filename
*
* @private
* @type {String}
*/
settersAndGettersSrc = (
'var rewire = require("rewire"); ' +
// Registers the setters and getters of every module according to their filename. The setters and getters must be
// injected as string here to gain access to the private scope of the module.
'rewire.register(module, ' + setterSrc + ', ' + getterSrc + '); ' +
// Cleaning up
'rewire = undefined;'
).replace(/\s+/g, " "); // strip out unnecessary spaces to be unobtrusive in the debug view
module.exports = webpackPostLoader;
|