diff options
-rw-r--r-- | lib/bundlers/browserify/browserifyMiddleware.js | 113 | ||||
-rw-r--r-- | lib/bundlers/browserify/browserifyRewire.js | 189 | ||||
-rw-r--r-- | lib/bundlers/getRewireRegExp.js | 15 | ||||
-rw-r--r-- | lib/bundlers/getRewireRequires.js | 24 | ||||
-rw-r--r-- | lib/bundlers/injectRewire.js | 46 | ||||
-rw-r--r-- | lib/bundlers/webpack/configureWebpack.js | 26 | ||||
-rw-r--r-- | lib/bundlers/webpack/getLoaderTestRegExp.js | 16 | ||||
-rw-r--r-- | lib/bundlers/webpack/webpackPostLoader.js | 80 | ||||
-rw-r--r-- | lib/bundlers/webpack/webpackPostProcessor.js | 24 | ||||
-rw-r--r-- | lib/bundlers/webpack/webpackRewire.js | 76 | ||||
-rw-r--r-- | lib/index.js | 5 | ||||
-rw-r--r-- | test/debug.test.js | 11 | ||||
-rw-r--r-- | test/testModules/sharedTestCases.js | 5 |
13 files changed, 2 insertions, 628 deletions
diff --git a/lib/bundlers/browserify/browserifyMiddleware.js b/lib/bundlers/browserify/browserifyMiddleware.js deleted file mode 100644 index a161369..0000000 --- a/lib/bundlers/browserify/browserifyMiddleware.js +++ /dev/null @@ -1,113 +0,0 @@ -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"), - rewireLib = path.join("rewire", "lib"), - settersAndGettersSrc; - -/** - * This function can be added to browserify via b.use(). - * @see https://github.com/substack/node-browserify/blob/master/doc/methods.markdown#methods - * - * It injects special code before every module in order to gain access to the private scope - * of the module. Additionally it forwards all calls of require("rewire") to the module - * browserifyRewire.js. Thus we don't need any cumbersome client/server-switches in the index.js. - * - * @param {browserify} b the bundle returned by browserify() - * @return {browserify} b - */ -function browserifyMiddleware(b) { - - console.log("(DEPRECATED) rewire won't support browserify anymore. Please let me know if you're relying on this feature (https://github.com/jhnns/rewire/issues/13)"); - - /** - * Does actually the injecting of the special code. It is called by browserify for every - * js-module. - * - * @param {String} src - * @param {String} filename - * @return {String} src - */ - function doInjectRewire(src, filename) { - var rewireRequires; - - // 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(rewireLib) === -1) { - // 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 to absolute paths - if (requirePath.charAt(0) === ".") { - requirePath = path.resolve(path.dirname(filename), requirePath); - } - b.require(requirePath); - - }); - - // Injects the special code - src = injectRewire(src, settersAndGettersSrc); - - // Because browserify doesn't create a new, independent module instance each time the module is - // executed we have to make it fake-independent. Thus the rewired module doesn't influence the original module. - // This is a crazy hack, but: hey don't blame me! Make a pull-request to browserify :) - src += ' module = require("rewire").getIndependentModule(module);'; - } - - return src; - } - - /** - * Gets called before each module is loaded. - * This function ensures that lib/bundlers/browserify/browserifyRewire.js is returned instead of lib/index.js - * - * @param {String} filename - * @return {String} filename - */ - 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. These setter and getter - // allow us 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/bundlers/browserify/browserifyRewire.js b/lib/bundlers/browserify/browserifyRewire.js deleted file mode 100644 index b09b51a..0000000 --- a/lib/bundlers/browserify/browserifyRewire.js +++ /dev/null @@ -1,189 +0,0 @@ -var pathUtil = require("path"), - getImportGlobalsSrc = require("./getImportGlobalsSrc.js"); // must be relative to lib/index.js because of forwardBrowserifyRewire() - -/** - * 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 = {}; - -/** - * 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 - * @return {Object} the rewired module - */ -function browserifyRewire(parentModulePath, path) { - var cached, - originalModule, - originalExports, - absPath, - rewiredExports = {}, - registryEntry, - _require = require; // hide it from browserify to avoid annoying console warnings - - // Normalize path with file extensions - absPath = pathUtil.resolve(parentModulePath, path); - - // Retrieve original module from cache - cached = originalModule = require.cache[absPath]; - - if (cached) { - // If there is already a module instance in the cache we have to store the original exports-object - // manually so it won't be overwritten by the next execution. This is all necessary due to browserify's - // odd way of module creation. - originalExports = originalModule.exports; - originalModule.exports = rewiredExports; - - // Delete the original module from the cache so the next call to _require() - // executes the module - delete require.cache[absPath]; - } - - // Require module to trigger rewire.register(). - _require(absPath); - - originalModule = require.cache[absPath]; - - // Now we're cloning the exports-obj so later modifications of the rewired module won't influence the - // cached, original version of this module. - rewiredExports = clone(originalModule.exports); - - if (cached) { - // Restore original exports - originalModule.exports = originalExports; - } - - // Get registry entry of the target module - registryEntry = registry[absPath]; - - // Apply setter and getters - rewiredExports.__set__ = registryEntry.setter; - rewiredExports.__get__ = registryEntry.getter; - - 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 - }; -}; - -/** - * 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']); -}; - -/** - * Returns a new object that inherits from the original module via prototype inheritance. - * - * Any changes to the module, e.g. assigning another exports-object will now modify the object - * instead of original module. - * - * @param {Object} originalModule - * @return {Object} the independent module - */ -browserifyRewire.getIndependentModule = function (originalModule) { - var independentModule; - - function IndependentModule() {} - IndependentModule.prototype = originalModule; - - independentModule = new IndependentModule(); - independentModule.exports = originalModule.exports; - - return independentModule; -}; - -module.exports = browserifyRewire;
\ No newline at end of file diff --git a/lib/bundlers/getRewireRegExp.js b/lib/bundlers/getRewireRegExp.js deleted file mode 100644 index 69e4ef5..0000000 --- a/lib/bundlers/getRewireRegExp.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * 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/bundlers/getRewireRequires.js b/lib/bundlers/getRewireRequires.js deleted file mode 100644 index 2c80091..0000000 --- a/lib/bundlers/getRewireRequires.js +++ /dev/null @@ -1,24 +0,0 @@ -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 deleted file mode 100644 index 52e3742..0000000 --- a/lib/bundlers/injectRewire.js +++ /dev/null @@ -1,46 +0,0 @@ -"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. - * This module doesn't contain bundler specific code. All bundler specific stuff should be done in the settersAndGettersSrc. - * - * @param {!String} src the module's src - * @param {!String} settersAndGettersSrc source that injects the setters and getters into the module scope - * @return {String} - */ -function injectRewire(src, settersAndGettersSrc) { - - 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 + "\n" + - - " })();"; - - 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 deleted file mode 100644 index 0738e16..0000000 --- a/lib/bundlers/webpack/configureWebpack.js +++ /dev/null @@ -1,26 +0,0 @@ -"use strict"; // run code in ES5 strict mode - -/** - * Configures webpack so it can be used with rewire. Make sure that the options aren't modified - * after calling this function. It's important that the rewire()-postLoader is the last loader called on a module. - * - * @see https://github.com/webpack/webpack - * - * @param {Object} options a webpack option object - */ -function configureWebpack(options) { - console.log("(DEPRECATED) rewire itself doesn't support webpack anymore. Please use rewire-webpack (https://github.com/jhnns/rewire-webpack)"); - - options.resolve = options.resolve || {}; - options.postLoaders = options.postLoaders || []; - options.resolve.postprocess = options.resolve.postprocess || {}; - options.resolve.postprocess.normal = options.resolve.postprocess.normal || []; - - // Registering the postLoader for injecting the special rewire code - options.postLoaders.push(require("./webpackPostLoader.js")); - - // Registering the postProcessor for resolving paths - options.resolve.postprocess.normal.push(require("./webpackPostProcessor.js")); -} - -module.exports = configureWebpack;
\ No newline at end of file diff --git a/lib/bundlers/webpack/getLoaderTestRegExp.js b/lib/bundlers/webpack/getLoaderTestRegExp.js deleted file mode 100644 index 40119c2..0000000 --- a/lib/bundlers/webpack/getLoaderTestRegExp.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; // run code in ES5 strict mode - -var pathUtil = require("path"), - match, - basePath; - - - -match = __dirname.match(/(.*)[\\\/].+[\\\/]rewire[\\\/]lib[\\\/]/); -if (match === null) { - return (/\.js$/); -} else { - basePath = match[1]; - basePath.replace(/([\\\/])/g, "\\$1"); - return new RegExp() -}
\ No newline at end of file diff --git a/lib/bundlers/webpack/webpackPostLoader.js b/lib/bundlers/webpack/webpackPostLoader.js deleted file mode 100644 index a381f8d..0000000 --- a/lib/bundlers/webpack/webpackPostLoader.js +++ /dev/null @@ -1,80 +0,0 @@ -"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;
\ No newline at end of file diff --git a/lib/bundlers/webpack/webpackPostProcessor.js b/lib/bundlers/webpack/webpackPostProcessor.js deleted file mode 100644 index ee10c40..0000000 --- a/lib/bundlers/webpack/webpackPostProcessor.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; // run code in ES5 strict mode - -var path = require("path"), - - rewireLibIndex = path.join("rewire", "lib", "index.js"); - -/** - * Gets called before each module is loaded. - * This function ensures that lib/bundlers/webpack/webpackRewire.js is returned instead of lib/index.js. - * - * The callback gets called with (null, filename) - * - * @param {!String} filename - * @param {!Function} callback - */ -function webpackPostProcessor(filename, callback) { - if (filename.indexOf(rewireLibIndex) !== -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 deleted file mode 100644 index db78302..0000000 --- a/lib/bundlers/webpack/webpackRewire.js +++ /dev/null @@ -1,76 +0,0 @@ -"use strict"; // run code in ES5 strict mode - -var registry = {}, - getImportGlobalsSrc = require("../../getImportGlobalsSrc.js"); - -var requireInDisguise; - -eval("requireInDisguise = require"); - -function getModuleId(exports) { - var cache = require.cache, - id; - - for (id in cache) { - if (cache.hasOwnProperty(id)) { - if (cache[id].exports === exports) { - return Number(id); - } - } - } - - return null; -} - -function webpackRewire(path, moduleExports) { - var id = getModuleId(moduleExports), - previousRegistryEntry, - cachedModule, - rewiredModule, - setter, - getter; - - if (typeof id !== "number") { - throw new Error("(rewire) Sorry, rewiring '" + path + "' is currently not supported."); - } - - previousRegistryEntry = registry[id]; - - cachedModule = require.cache[id]; - delete require.cache[id]; - rewiredModule = requireInDisguise(id); - require.cache[id] = cachedModule; - - setter = registry[id].setter; - getter = registry[id].getter; - - registry[id] = previousRegistryEntry; - - rewiredModule.__set__ = setter; - rewiredModule.__get__ = getter; - - return rewiredModule; -} - -webpackRewire.register = function (module, setter, getter) { - var id = module.id; - - 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 6858598..11229ff 100644 --- a/lib/index.js +++ b/lib/index.js @@ -11,11 +11,6 @@ function rewire(filename) { return rewireModule(module.parent, filename); } -rewire.bundlers = { - browserify: require("./bundlers/browserify/browserifyMiddleware.js"), - webpack: require("./bundlers/webpack/configureWebpack.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 diff --git a/test/debug.test.js b/test/debug.test.js deleted file mode 100644 index 0ffbacf..0000000 --- a/test/debug.test.js +++ /dev/null @@ -1,11 +0,0 @@ -var rewire = require("../lib/index.js");
-
-// add breakpoints in testModules/debuggerModule.js and debug this file with your IDE to
-// check if debugging works with rewire.
-var debuggerModule = rewire("./testModules/debuggerModule.js");
-
-debugger;
-
-debuggerModule.__set__("myNumber", 1);
-
-debuggerModule();
\ No newline at end of file diff --git a/test/testModules/sharedTestCases.js b/test/testModules/sharedTestCases.js index 050c753..65537e6 100644 --- a/test/testModules/sharedTestCases.js +++ b/test/testModules/sharedTestCases.js @@ -2,8 +2,7 @@ // In case this module was in strict mode, all other modules called by this would also be strict. // But when testing if the strict mode is preserved, we must ensure that this module is NOT strict. -var path = require("path"), - expect = require("expect.js"), +var expect = require("expect.js"), rewire = require("rewire"); function checkForTypeError(err) { @@ -46,7 +45,7 @@ describe("rewire " + (typeof testEnv === "undefined"? "(node)": "(" + testEnv + expect(rewire("./moduleB.js").__get__).to.be.a(Function); }); it("should not influence other modules", function () { - var rewiredModuleA = rewire("./moduleA.js"); + rewire("./moduleA.js"); expect(require("./someOtherModule.js").__set__).to.be(undefined); expect(require("./someOtherModule.js").__get__).to.be(undefined); |