Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/rewire.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohannes <johannes.ewald@roomieplanet.de>2012-08-18 18:34:13 +0400
committerJohannes <johannes.ewald@roomieplanet.de>2012-08-18 18:34:13 +0400
commitc5d8fab07f0edc568e45e0747f863afd5876abc2 (patch)
treeab57b94703d16087fbb6c81e4bdb5d1ae6217d19 /lib
parent657b9e84018014d15916c86274b8ee35b9386627 (diff)
- Introduced webpack bundler for rewire (work in progress, some tests are not running)
Diffstat (limited to 'lib')
-rw-r--r--lib/browser/shims.js48
-rw-r--r--lib/browserify/browserifyMiddleware.js100
-rw-r--r--lib/bundlers/browserify/browserifyMiddleware.js67
-rw-r--r--lib/bundlers/browserify/browserifyRewire.js (renamed from lib/browserify/browserifyRewire.js)374
-rw-r--r--lib/bundlers/getRewireRegExp.js15
-rw-r--r--lib/bundlers/getRewireRequires.js (renamed from lib/browserify/getRewireRequires.js)44
-rw-r--r--lib/bundlers/injectRewire.js54
-rw-r--r--lib/bundlers/webpack/configureWebpack.js16
-rw-r--r--lib/bundlers/webpack/webpackPostLoader.js43
-rw-r--r--lib/bundlers/webpack/webpackPostProcessor.js18
-rw-r--r--lib/bundlers/webpack/webpackRewire.js91
-rw-r--r--lib/index.js57
12 files changed, 537 insertions, 390 deletions
diff --git a/lib/browser/shims.js b/lib/browser/shims.js
deleted file mode 100644
index df7bd63..0000000
--- a/lib/browser/shims.js
+++ /dev/null
@@ -1,48 +0,0 @@
-// Taken from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility
-if (!Array.prototype.indexOf) {
- Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
- "use strict";
- if (this == null) {
- throw new TypeError();
- }
- var t = Object(this);
- var len = t.length >>> 0;
- if (len === 0) {
- return -1;
- }
- var n = 0;
- if (arguments.length > 0) {
- n = Number(arguments[1]);
- if (n != n) { // shortcut for verifying if it's NaN
- n = 0;
- } else if (n != 0 && n != Infinity && n != -Infinity) {
- n = (n > 0 || -1) * Math.floor(Math.abs(n));
- }
- }
- if (n >= len) {
- return -1;
- }
- var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
- for (; k < len; k++) {
- if (k in t && t[k] === searchElement) {
- return k;
- }
- }
- return -1;
- }
-}
-
-
-// Taken from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/trim#Compatibility
-if(!String.prototype.trim) {
- String.prototype.trim = function () {
- return this.replace(/^\s+|\s+$/g,'');
- };
-}
-
-// Taken from https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray#Compatibility
-if(!Array.isArray) {
- Array.isArray = function (vArg) {
- return Object.prototype.toString.call(vArg) === "[object Array]";
- };
-} \ No newline at end of file
diff --git a/lib/browserify/browserifyMiddleware.js b/lib/browserify/browserifyMiddleware.js
deleted file mode 100644
index fb1887f..0000000
--- a/lib/browserify/browserifyMiddleware.js
+++ /dev/null
@@ -1,100 +0,0 @@
-var setterSrc = require("../__set__.js").toString(),
- getterSrc = require("../__get__.js").toString(),
- fs = require("fs"),
- path = require("path"),
- getImportGlobalsSrc = require("../getImportGlobalsSrc.js"),
- getRewireRequires = require("./getRewireRequires.js"),
- detectStrictMode = require("../detectStrictMode.js"),
-
- injectionSrc = getInjectionSrc().replace(/\s+/g, " "); // strip out unnecessary spaces to be unobtrusive in the debug view
-
-/**
- * Returns a string that gets injected at the beginning of every module. Its purpose is to
- *
- * - register the setters and getters according to the module's filename
- * - override the internal require with a require proxy.
- *
- * @return {String}
- */
-function getInjectionSrc() {
- return '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(__filename, module, ' + setterSrc + ', ' + getterSrc + ');' +
- // Overrides the module internal require with a require proxy. This proxy is necessary to call rewire with the
- // module's filename at the first parameter to resolve the path. This way rewire() works exactly like require().
- 'require = rewire.getProxy(require, __dirname);' +
- // Cleaning up
- 'rewire = undefined;';
-}
-
-function browserifyMiddleware(b) {
-
- /**
- * Gets called for every module. Injects special code so rewire is able to access private variables.
- *
- * @param {String} src
- * @param {String} filename
- * @return {String}
- */
- function injectRewire(src, filename) {
- var rewireRequires;
-
- // Search for all rewire() statements an return the required path.
- rewireRequires = getRewireRequires(src);
-
- // Add all modules that are loaded by rewire() manually to browserify because browserify's
- // require-sniffing doesn't work here.
- rewireRequires.forEach(function forEachRewireRequire(requirePath) {
- // Resolve absolute paths
- if (requirePath.charAt(0) === ".") {
- requirePath = path.resolve(path.dirname(filename), requirePath);
- }
- b.require(requirePath);
- });
-
- // Convert back slashes to normal slashes on windows.
- if (process.platform.indexOf("win") === 0) {
- filename = filename.replace(/\\/g, "/");
- }
-
- // We don't want to inject this code at the beginning of a rewire/lib-module. Otherwise
- // it would cause a black hole that devours our universe.
- if (filename.indexOf("/rewire/lib") === -1) {
- src =
- // Trying to hide the injected line in the debug view with extra whitespaces.
- ' ' +
- '/* this line was injected by rewire() */ ' + // Comment for the curious developer
-
- // Now all global variables are declared with a var statement so they can be changed via __set__()
- // without influencing global objects.
- 'var global = window; ' + // window is our new global object
- 'eval(require("rewire").getImportGlobalsSrc()); ' +
-
- // The module src is wrapped inside a self-executing function.
- // This is necessary to separate the module src from the preceding eval(importGlobalsSrc),
- // because the module src can be in strict mode.
- // In strict mode eval() can only declare vars in the current scope. In this case our setters
- // and getters won't work.
- // @see https://developer.mozilla.org/en/JavaScript/Strict_mode#Making_eval_and_arguments_simpler
- "(function () {" +
-
- // If the module uses strict mode we must ensure that "use strict" stays at the beginning of the function.
- (detectStrictMode(src)? ' "use strict"; ': ' ') +
-
- injectionSrc + "\n" +
- src +
-
- "})();";
- }
-
- return src;
- }
-
- // Register file handler
- b.register(".js", injectRewire);
-
- return b;
-}
-
-module.exports = browserifyMiddleware; \ No newline at end of file
diff --git a/lib/bundlers/browserify/browserifyMiddleware.js b/lib/bundlers/browserify/browserifyMiddleware.js
new file mode 100644
index 0000000..39d76b1
--- /dev/null
+++ b/lib/bundlers/browserify/browserifyMiddleware.js
@@ -0,0 +1,67 @@
+var setterSrc = require("../../__set__.js").toString(),
+ getterSrc = require("../../__get__.js").toString(),
+ path = require("path"),
+ injectRewire = require("../injectRewire.js"),
+ getRewireRequires = require("../getRewireRequires.js"),
+
+ rewireIndex = path.resolve(__dirname, "../../index.js"),
+ settersAndGettersSrc;
+
+function browserifyMiddleware(b) {
+ function doInjectRewire(src, filename) {
+ var rewireRequires;
+
+ // Search for all rewire() statements an return the required path.
+ rewireRequires = getRewireRequires(src);
+
+ // Add all modules that are loaded by rewire() manually to browserify because browserify's
+ // require-sniffing doesn't work here.
+ rewireRequires.forEach(function forEachRewireRequire(requirePath) {
+ // Resolve absolute paths
+ if (requirePath.charAt(0) === ".") {
+ requirePath = path.resolve(path.dirname(filename), requirePath);
+ }
+ b.require(requirePath);
+ });
+
+ src = injectRewire(src, filename, settersAndGettersSrc);
+
+ return src;
+ }
+
+ function forwardBrowserifyRewire(filename) {
+ if (filename === rewireIndex) {
+ filename = __dirname + "/browserifyRewire.js";
+ }
+
+ return filename;
+ }
+
+ // Register file handler
+ b.register(".js", doInjectRewire);
+ b.register("path", forwardBrowserifyRewire);
+
+ return b;
+}
+
+/**
+ * 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
+ * - override the internal require with a require proxy.
+ *
+ * @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(__filename, module, ' + setterSrc + ', ' + getterSrc + ');' +
+ // Overrides the module internal require with a require proxy. This proxy is necessary to call rewire with the
+ // module's filename at the first parameter to resolve the path. This way rewire() works exactly like require().
+ 'require = rewire.getProxy(require, __dirname);' +
+ // Cleaning up
+ 'rewire = undefined;'
+).replace(/\s+/g, " "); // strip out unnecessary spaces to be unobtrusive in the debug view
+
+module.exports = browserifyMiddleware; \ No newline at end of file
diff --git a/lib/browserify/browserifyRewire.js b/lib/bundlers/browserify/browserifyRewire.js
index e21c0db..2798b69 100644
--- a/lib/browserify/browserifyRewire.js
+++ b/lib/bundlers/browserify/browserifyRewire.js
@@ -1,189 +1,187 @@
-require("../browser/shims.js"); // some shims for older browsers that are necessary for rewire()
-
-var pathUtil = require("path"),
- getImportGlobalsSrc = require("../getImportGlobalsSrc.js");
-
-/**
- * Clones an object deeply. Used to clone the module-object that is
- * stored in the cache. Because browserify doesn't create the module-
- * object newly if the module is executed again we can't modify the
- * exports object directly. Instead of we have to make an independent copy.
- *
- * @param {!Object} obj
- * @return {Object}
- */
-function clone(obj) {
- var target = {},
- value,
- key;
-
- for (key in obj) {
- if (obj.hasOwnProperty(key)) {
- value = obj[key];
- if (Array.isArray(value)) {
- target[key] = value.slice(0);
- } else if (typeof value === "object" && value !== null) {
- target[key] = clone(value);
- } else {
- target[key] = value;
- }
-
- }
- }
-
- return target;
-}
-
-// Saves all setters and getters for every module according to its filename
-var registry = {},
-// Cache for all rewired modules so it can be reset anytime
- rewiredModules = [];
-
-/**
- * Executes the given module and adds a special setter and getter that allow you to set and get private variables.
- * The parentModulePath is usually set by the requireProxy.
- *
- * @param {!String} parentModulePath __filename of the module, that wants to rewire() another module.
- * @param {!String} path path to the module that shall be rewired
- * @param {Boolean=true} cache indicates whether the rewired module should be cached or not
- * @return {Object}
- */
-function browserifyRewire(parentModulePath, path, cache) {
- var originalModule,
- absPath,
- rewiredExports,
- rewiredModule,
- registryEntry;
-
- // Default cache to true
- if (cache === undefined) {
- cache = true;
- }
-
- // Normalize path with file extensions
- absPath = pathUtil.resolve(parentModulePath, path);
-
- // Retrieve original module from cache
- originalModule = require.cache[absPath];
-
- if (originalModule && cache) {
- // Delete the original module from the cache so the next call to browserifyRequre()
- // executes the module
- delete require.cache[absPath];
- }
-
- // Require module to trigger rewire.register().
- // Putting (require) in brackets hides it for browserify.
- (require)(absPath);
-
- // Get registry entry of the target module
- registryEntry = registry[absPath];
- originalModule = registryEntry.module;
-
- // Make an independent copy of the original module so we can modify the copy
- // without influencing the original module.
- rewiredModule = clone(originalModule);
- rewiredExports = rewiredModule.exports;
-
- // Apply setter and getters
- rewiredExports.__set__ = registryEntry.setter;
- rewiredExports.__get__ = registryEntry.getter;
-
- if (cache) {
- require.cache[absPath] = rewiredModule;
- }
-
- // Store rewired modules for rewire.reset()
- rewiredModules.push(absPath);
-
- return rewiredExports;
-}
-
-/**
- * Registers the setter and getter of every module according to its filename
- *
- * @param {!String} filename the absolute path to the module (module id)
- * @param {!Function} setter
- * @param {!Function} getter
- */
-browserifyRewire.register = function (filename, module, setter, getter) {
- registry[filename] = {
- module: module,
- setter: setter,
- getter: getter
- };
-};
-
-/**
- * Deletes all rewired modules from the cache
- */
-browserifyRewire.reset = function () {
- var cache = require.cache,
- i,
- absPath;
-
- for (i = 0; i < rewiredModules.length; i++) {
- absPath = rewiredModules[i];
- delete cache[absPath];
- }
-
- rewiredModules = [];
-};
-
-/**
- * Provides a special require-proxy. Every module calls require("rewire").getProxy(require, __filename) at the
- * beginning and overrides its own require with this proxy.
- *
- * This is necessary to call rewire() with the original __filename. Thus you can use rewire() like require().
- *
- * @param {!Function} internalRequire the module's own require
- * @param {String} dirname the __dirname of the module
- * @return {Function} requireProxy
- */
-browserifyRewire.getProxy = function (internalRequire, dirname) {
- var rewire = internalRequire("rewire"),
- rewireProxyInit = false;
-
- function copyProperties(from, to) {
- var key;
-
- for (key in from) {
- if (from.hasOwnProperty(key)) {
- to[key] = from[key];
- }
- }
- }
-
- function rewireProxy(path, cache) {
- return rewire(dirname, path, cache);
- }
-
- function requireProxy(path) {
- if (path === "rewire") {
- if (rewireProxyInit === false) {
- copyProperties(rewire, rewireProxy); // lazy copy
- rewireProxyInit = true;
- }
- return rewireProxy;
- } else {
- return internalRequire(path);
- }
- }
-
- copyProperties(internalRequire, requireProxy);
-
- return requireProxy;
-};
-
-/**
- * Scans for global vars and returns an evalable string that declares all globals as a var.
- * This way a global variable can be overridden by __set__ without changing the global instance.
- * It is executed each time again to include global variables that have been added later.
- *
- * @return {String}
- */
-browserifyRewire.getImportGlobalsSrc = function () {
- return getImportGlobalsSrc(['require','module','exports','__dirname','__filename','process']);
-};
-
+var pathUtil = require("path"),
+ getImportGlobalsSrc = require("./getImportGlobalsSrc.js"); /* must be relative to lib/index.js */
+
+/**
+ * Clones an object deeply. Used to clone the module-object that is
+ * stored in the cache. Because browserify doesn't create the module-
+ * object newly if the module is executed again we can't modify the
+ * exports object directly. Instead of we have to make an independent copy.
+ *
+ * @param {!Object} obj
+ * @return {Object}
+ */
+function clone(obj) {
+ var target = {},
+ value,
+ key;
+
+ for (key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ value = obj[key];
+ if (Array.isArray(value)) {
+ target[key] = value.slice(0);
+ } else if (typeof value === "object" && value !== null) {
+ target[key] = clone(value);
+ } else {
+ target[key] = value;
+ }
+
+ }
+ }
+
+ return target;
+}
+
+// Saves all setters and getters for every module according to its filename
+var registry = {},
+// Cache for all rewired modules so it can be reset anytime
+ rewiredModules = [];
+
+/**
+ * Executes the given module and adds a special setter and getter that allow you to set and get private variables.
+ * The parentModulePath is usually set by the requireProxy.
+ *
+ * @param {!String} parentModulePath __filename of the module, that wants to rewire() another module.
+ * @param {!String} path path to the module that shall be rewired
+ * @param {Boolean=true} cache indicates whether the rewired module should be cached or not
+ * @return {Object}
+ */
+function browserifyRewire(parentModulePath, path, cache) {
+ var originalModule,
+ absPath,
+ rewiredExports,
+ rewiredModule,
+ registryEntry,
+ _require = require; // hide it from browserify
+
+ // Default cache to true
+ if (cache === undefined) {
+ cache = true;
+ }
+
+ // Normalize path with file extensions
+ absPath = pathUtil.resolve(parentModulePath, path);
+
+ // Retrieve original module from cache
+ originalModule = require.cache[absPath];
+
+ if (originalModule && cache) {
+ // Delete the original module from the cache so the next call to browserifyRequre()
+ // executes the module
+ delete require.cache[absPath];
+ }
+
+ // Require module to trigger rewire.register().
+ _require(absPath);
+
+ // Get registry entry of the target module
+ registryEntry = registry[absPath];
+ originalModule = registryEntry.module;
+
+ // Make an independent copy of the original module so we can modify the copy
+ // without influencing the original module.
+ rewiredModule = clone(originalModule);
+ rewiredExports = rewiredModule.exports;
+
+ // Apply setter and getters
+ rewiredExports.__set__ = registryEntry.setter;
+ rewiredExports.__get__ = registryEntry.getter;
+
+ if (cache) {
+ require.cache[absPath] = rewiredModule;
+ }
+
+ // Store rewired modules for rewire.reset()
+ rewiredModules.push(absPath);
+
+ return rewiredExports;
+}
+
+/**
+ * Registers the setter and getter of every module according to its filename
+ *
+ * @param {!String} filename the absolute path to the module (module id)
+ * @param {!Function} setter
+ * @param {!Function} getter
+ */
+browserifyRewire.register = function (filename, module, setter, getter) {
+ registry[filename] = {
+ module: module,
+ setter: setter,
+ getter: getter
+ };
+};
+
+/**
+ * Deletes all rewired modules from the cache
+ */
+browserifyRewire.reset = function () {
+ var cache = require.cache,
+ i,
+ absPath;
+
+ for (i = 0; i < rewiredModules.length; i++) {
+ absPath = rewiredModules[i];
+ delete cache[absPath];
+ }
+
+ rewiredModules = [];
+};
+
+/**
+ * Provides a special require-proxy. Every module calls require("rewire").getProxy(require, __filename) at the
+ * beginning and overrides its own require with this proxy.
+ *
+ * This is necessary to call rewire() with the original __filename. Thus you can use rewire() like require().
+ *
+ * @param {!Function} internalRequire the module's own require
+ * @param {String} dirname the __dirname of the module
+ * @return {Function} requireProxy
+ */
+browserifyRewire.getProxy = function (internalRequire, dirname) {
+ var rewire = internalRequire("rewire"),
+ rewireProxyInit = false;
+
+ function copyProperties(from, to) {
+ var key;
+
+ for (key in from) {
+ if (from.hasOwnProperty(key)) {
+ to[key] = from[key];
+ }
+ }
+ }
+
+ function rewireProxy(path, cache) {
+ return rewire(dirname, path, cache);
+ }
+
+ function requireProxy(path) {
+ if (path === "rewire") {
+ if (rewireProxyInit === false) {
+ copyProperties(rewire, rewireProxy); // lazy copy
+ rewireProxyInit = true;
+ }
+ return rewireProxy;
+ } else {
+ return internalRequire(path);
+ }
+ }
+
+ copyProperties(internalRequire, requireProxy);
+
+ return requireProxy;
+};
+
+/**
+ * Scans for global vars and returns an evalable string that declares all globals as a var.
+ * This way a global variable can be overridden by __set__ without changing the global instance.
+ * It is executed each time again to include global variables that have been added later.
+ *
+ * @return {String}
+ */
+browserifyRewire.getImportGlobalsSrc = function () {
+ return getImportGlobalsSrc(['require','module','exports','__dirname','__filename','process']);
+};
+
module.exports = browserifyRewire; \ No newline at end of file
diff --git a/lib/bundlers/getRewireRegExp.js b/lib/bundlers/getRewireRegExp.js
new file mode 100644
index 0000000..69e4ef5
--- /dev/null
+++ b/lib/bundlers/getRewireRegExp.js
@@ -0,0 +1,15 @@
+/**
+ * Returns a regular expression that matches all rewire() statements.
+ *
+ * Captures:
+ *
+ * 1. the character before rewire
+ * 2. the path between the parenthesis without quotation marks
+ *
+ * @return {RegExp}
+ */
+function getRewireRegExp() {
+ return /([^a-zA-Z0-9_])rewire\(["'](.+?)["']\)/g;
+}
+
+module.exports = getRewireRegExp; \ No newline at end of file
diff --git a/lib/browserify/getRewireRequires.js b/lib/bundlers/getRewireRequires.js
index 896729e..2c80091 100644
--- a/lib/browserify/getRewireRequires.js
+++ b/lib/bundlers/getRewireRequires.js
@@ -1,22 +1,24 @@
-/***
- * Searches for rewire(); statements and returns all strings that are between the brackets.
- *
- * @param {!String} src
- * @return {Array}
- */
-function getRewireRequires(src) {
- var result = [],
- regExp = /[^a-zA-Z0-9_]rewire\(["'](.+?)["']\)/g,
- match;
-
- src = " " + src; // ensure that rewire() is not at index 0 otherwise the regexp won't work in this case
- match = regExp.exec(src);
- while (match !== null) {
- result.push(match[1]);
- match = regExp.exec(src);
- }
-
- return result;
-}
-
+var getRewireRegExp = require("./getRewireRegExp.js");
+
+/**
+ * Searches for rewire(); statements and returns all strings that are between the brackets.
+ *
+ * @param {!String} src
+ * @return {Array}
+ */
+function getRewireRequires(src) {
+ var result = [],
+ regExp = getRewireRegExp(),
+ match;
+
+ src = " " + src; // ensure that rewire() is not at index 0 otherwise the regexp won't work in this case
+ match = regExp.exec(src);
+ while (match !== null) {
+ result.push(match[2]);
+ match = regExp.exec(src);
+ }
+
+ return result;
+}
+
module.exports = getRewireRequires; \ No newline at end of file
diff --git a/lib/bundlers/injectRewire.js b/lib/bundlers/injectRewire.js
new file mode 100644
index 0000000..dfd56a4
--- /dev/null
+++ b/lib/bundlers/injectRewire.js
@@ -0,0 +1,54 @@
+"use strict"; // run code in ES5 strict mode
+
+var path = require("path"),
+ getRewireRequires = require("./getRewireRequires.js"),
+ detectStrictMode = require("../detectStrictMode.js");
+
+/**
+ * Gets called by the bundler for every module. Injects special code so rewire is able to access private variables.
+ *
+ * @param {String} src the module's src
+ * @param {String} filename the module's filename
+ * @param {String} settersAndGettersSrc source that injects the setters and getters into the module scope
+ * @return {String}
+ */
+function injectRewire(src, filename, settersAndGettersSrc) {
+ // Convert back slashes to normal slashes on windows.
+ if (path.sep !== "/") {
+ filename = filename.split(path.sep).join("/");
+ }
+
+ // We don't want to inject this code at the beginning of a rewire/lib-module. Otherwise
+ // it would cause a black hole that devours our universe.
+ if (filename.indexOf("/rewire/lib/") === -1) {
+ src =
+ // Trying to hide the injected line in the debug view with extra whitespaces.
+ ' ' +
+ '/* this line was injected by rewire() */ ' + // Comment for the curious developer
+
+ // Now all global variables are declared with a var statement so they can be changed via __set__()
+ // without influencing global objects.
+ 'var global = window; ' + // window is our new global object
+ 'eval(require("rewire").getImportGlobalsSrc()); ' +
+
+ // The module src is wrapped inside a self-executing function.
+ // This is necessary to separate the module src from the preceding eval(importGlobalsSrc),
+ // because the module src can be in strict mode.
+ // In strict mode eval() can only declare vars in the current scope. In this case our setters
+ // and getters won't work.
+ // @see https://developer.mozilla.org/en/JavaScript/Strict_mode#Making_eval_and_arguments_simpler
+ "(function () { " +
+
+ // If the module uses strict mode we must ensure that "use strict" stays at the beginning of the function.
+ (detectStrictMode(src)? ' "use strict"; ': ' ') +
+
+ settersAndGettersSrc + "\n" +
+ src +
+
+ " })();";
+ }
+
+ return src;
+}
+
+module.exports = injectRewire; \ No newline at end of file
diff --git a/lib/bundlers/webpack/configureWebpack.js b/lib/bundlers/webpack/configureWebpack.js
new file mode 100644
index 0000000..a302d1c
--- /dev/null
+++ b/lib/bundlers/webpack/configureWebpack.js
@@ -0,0 +1,16 @@
+"use strict"; // run code in ES5 strict mode
+
+function configureWebpack(options) {
+ options.resolve = options.resolve || {};
+ options.postLoaders = options.postLoaders || [];
+ options.resolve.postprocess = options.resolve.postprocess || {};
+ options.resolve.postprocess.normal = options.resolve.postprocess.normal || [];
+
+ // @see https://github.com/webpack/webpack/issues/21
+ options.context = options.context || process.cwd();
+
+ options.postLoaders.push(require("./webpackPostLoader.js"));
+ options.resolve.postprocess.normal.push(require("./webpackPostProcessor.js"));
+}
+
+module.exports = configureWebpack; \ No newline at end of file
diff --git a/lib/bundlers/webpack/webpackPostLoader.js b/lib/bundlers/webpack/webpackPostLoader.js
new file mode 100644
index 0000000..620f091
--- /dev/null
+++ b/lib/bundlers/webpack/webpackPostLoader.js
@@ -0,0 +1,43 @@
+"use strict"; // run code in ES5 strict mode
+
+var setterSrc = require("../../__set__.js").toString(),
+ getterSrc = require("../../__get__.js").toString(),
+ injectRewire = require("../injectRewire.js"),
+ getRewireRegExp = require("../getRewireRegExp.js"),
+
+ settersAndGettersSrc;
+
+function webpackLoader(src) {
+ var filename = this.request.split("!").pop(),
+ rewireRegExp = getRewireRegExp();
+
+ if (filename.indexOf("/webpack/buildin/__webpack") === -1) {
+ src = src.replace(rewireRegExp, '$1rewire("$2", require("$2"))'); // replaces rewire("some/path") into rewire("some/path", require("some/path"))
+ src = injectRewire(src, filename, settersAndGettersSrc);
+ }
+
+
+ return src;
+}
+
+webpackLoader.loader = __filename;
+webpackLoader.test = /\.js$/;
+
+/**
+ * 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
+ * - override the internal require with a require proxy.
+ *
+ * @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 = webpackLoader; \ No newline at end of file
diff --git a/lib/bundlers/webpack/webpackPostProcessor.js b/lib/bundlers/webpack/webpackPostProcessor.js
new file mode 100644
index 0000000..e90a4ad
--- /dev/null
+++ b/lib/bundlers/webpack/webpackPostProcessor.js
@@ -0,0 +1,18 @@
+"use strict"; // run code in ES5 strict mode
+
+var path = require("path");
+
+function webpackPostProcessor(filename, callback) {
+ // Convert back slashes to normal slashes on windows.
+ if (path.sep !== "/") {
+ filename = filename.split(path.sep).join("/");
+ }
+
+ if (filename.indexOf("/rewire/lib/index.js") !== -1) {
+ filename = __dirname + "/webpackRewire.js";
+ }
+
+ callback(null, filename);
+}
+
+module.exports = webpackPostProcessor; \ No newline at end of file
diff --git a/lib/bundlers/webpack/webpackRewire.js b/lib/bundlers/webpack/webpackRewire.js
new file mode 100644
index 0000000..bd86f98
--- /dev/null
+++ b/lib/bundlers/webpack/webpackRewire.js
@@ -0,0 +1,91 @@
+"use strict"; // run code in ES5 strict mode
+
+var registry = {},
+ getImportGlobalsSrc = require("../../getImportGlobalsSrc.js");
+
+var requireInDisguise;
+
+eval("requireInDisguise = require");
+
+function getId(module) {
+ var index = registry.modules.indexOf(module);
+
+ return registry.id[index] || null;
+}
+
+function getIdFromCache(module) {
+ var cache = require.cache,
+ id;
+
+ for (id in cache) {
+ if (cache.hasOwnProperty(id)) {
+ if (cache[id] === module) {
+ return Number(id);
+ }
+ }
+ }
+
+ return null;
+}
+
+function getIdByExportsObj(moduleExports) {
+ var id;
+
+ for (id in registry) {
+ if (registry.hasOwnProperty(id)) {
+ if (registry[id].module.exports === moduleExports) {
+ return Number(id);
+ }
+ }
+ }
+
+ return null;
+}
+
+function webpackRewire(path, moduleExports) {
+ var id = getIdByExportsObj(moduleExports),
+ cachedModule,
+ rewiredModule,
+ setter,
+ getter;
+
+ if (typeof id !== "number") {
+ throw new Error("(rewire) Sorry, rewiring '" + path + "' is currently not supported.");
+ }
+
+ cachedModule = require.cache[id];
+ delete require.cache[id];
+ rewiredModule = requireInDisguise(id);
+ //require.cache[id] = cachedModule;
+
+ setter = registry[id].setter;
+ getter = registry[id].getter;
+
+ rewiredModule.__set__ = setter;
+ rewiredModule.__get__ = getter;
+
+ return rewiredModule;
+}
+
+webpackRewire.register = function (module, setter, getter) {
+ var id = getIdFromCache(module);
+
+ registry[id] = {
+ module: module,
+ setter: setter,
+ getter: getter
+ };
+};
+
+/**
+ * Scans for global vars and returns an evalable string that declares all globals as a var.
+ * This way a global variable can be overridden by __set__ without changing the global instance.
+ * It is executed each time again to include global variables that have been added later.
+ *
+ * @return {String}
+ */
+webpackRewire.getImportGlobalsSrc = function () {
+ return getImportGlobalsSrc(['require','module','exports','__dirname','__filename','process']);
+};
+
+module.exports = webpackRewire; \ No newline at end of file
diff --git a/lib/index.js b/lib/index.js
index 491599a..4105917 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,33 +1,24 @@
-var rewireModule;
-
-/**
- * Adds a special setter and getter to the module located at filename. After the module has been rewired, you can
- * call myModule.__set__(name, value) and myModule.__get__(name) to manipulate private variables.
- *
- * @param {!String} filename Path to the module that shall be rewired. Use it exactly like require().
- * @param {Boolean} cache Indicates whether the rewired module should be cached by node so subsequent calls of require() will return the rewired module. Subsequent calls of rewire() will always overwrite the cache.
- * @return {*} the rewired module
- */
-function rewire(filename, cache) {
- if (cache === undefined) {
- cache = true;
- }
-
- return rewireModule(module.parent, filename, cache);
-}
-
-// Conditional require for different environments
-if (process.title === "browser") {
- module.exports = require("./browserify/browserifyRewire.js");
-} else {
- delete require.cache[__filename]; // deleting self from module cache so the parent module is always up to date
-
- // Putting (require) within brackets is a hack to disable browserify's require sniffing
- // @see https://github.com/substack/node-browserify/issues/132#issuecomment-5281470
- rewireModule = (require)("./internalRewire.js");
-
- rewire.reset = rewireModule.reset;
- rewire.browserify = (require)("./browserify/browserifyMiddleware.js");
-
- module.exports = rewire;
-}
+var rewireModule = require("./internalRewire.js");
+
+/**
+ * Adds a special setter and getter to the module located at filename. After the module has been rewired, you can
+ * call myModule.__set__(name, value) and myModule.__get__(name) to manipulate private variables.
+ *
+ * @param {!String} filename Path to the module that shall be rewired. Use it exactly like require().
+ * @param {Boolean} cache Indicates whether the rewired module should be cached by node so subsequent calls of require() will return the rewired module. Subsequent calls of rewire() will always overwrite the cache.
+ * @return {*} the rewired module
+ */
+function rewire(filename, cache) {
+ if (cache === undefined) {
+ cache = true;
+ }
+
+ return rewireModule(module.parent, filename, cache);
+}
+
+rewire.reset = rewireModule.reset;
+rewire.browserify = require("./bundlers/browserify/browserifyMiddleware.js");
+
+module.exports = rewire;
+
+delete require.cache[__filename]; // deleting self from module cache so the parent module is always up to date \ No newline at end of file