Commit 185c1ba6 185c1ba652d95547f6350977e2783842ce50db2e by Nicolas Perriault

Fixed CommonJS module pattern implementation

partially reverted d0dcd0cf to ensure BC with existing
CasperJS scripts.
1 parent d0dcd0cf
...@@ -4,10 +4,10 @@ CasperJS Changelog ...@@ -4,10 +4,10 @@ CasperJS Changelog
4 XXXX-XX-XX, v1.0.0 (currently latest master) 4 XXXX-XX-XX, v1.0.0 (currently latest master)
5 -------------------------------------------- 5 --------------------------------------------
6 6
7 ### Important Changes 7 ### Important Changes & Caveats
8 8
9 - **PhantomJS 1.6 is now the minimal requirement** 9 - **PhantomJS 1.6 is now the minimal requirement**
10 - The `modules` directory has been renamed to `node_modules` for compatibility purpose with PhantomJS 1.7. 10 - CasperJS continues to ship with its own implementation of CommonJS' module pattern, due to the way it has to work to offer its own executable. While the implementations are nearly the same, **100% compatibility is not guaranteed**.
11 11
12 ### Bugfixes & enhancements 12 ### Bugfixes & enhancements
13 13
......
...@@ -54,26 +54,20 @@ if (typeof Function.prototype.bind !== "function") { ...@@ -54,26 +54,20 @@ if (typeof Function.prototype.bind !== "function") {
54 } 54 }
55 55
56 /** 56 /**
57 * Only for PhantomJS < 1.7: Patching require() to allow loading of other 57 * CasperJS ships with its own implementation of CommonJS' require() because
58 * modules than PhantomJS' builtin ones. 58 * PhantomJS' native one doesn't allow to specify supplementary, alternative
59 * lookup directories to fetch modules from.
59 * 60 *
60 */ 61 */
61 function patchRequire(require, requireDir) { 62 function patchRequire(require, requireDirs) {
62 "use strict"; 63 "use strict";
64 require('webserver'); // force generation of phantomjs' require.cache for the webserver module
63 var fs = require('fs'); 65 var fs = require('fs');
64 var phantomBuiltins = ['fs', 'webpage', 'webserver', 'system']; 66 var phantomBuiltins = ['fs', 'webpage', 'system', 'webserver'];
65 var phantomRequire = phantom.__orig__require = require; 67 var phantomRequire = phantom.__orig__require = require;
66 var requireCache = {}; 68 var requireCache = {};
67 return function _require(path) { 69 function possiblePaths(path, requireDir) {
68 var i, dir, paths = [], 70 var dir, paths = [];
69 fileGuesses = [],
70 file,
71 module = {
72 exports: {}
73 };
74 if (phantomBuiltins.indexOf(path) !== -1) {
75 return phantomRequire(path);
76 }
77 if (path[0] === '.') { 71 if (path[0] === '.') {
78 paths.push.apply(paths, [ 72 paths.push.apply(paths, [
79 fs.absolute(path), 73 fs.absolute(path),
...@@ -84,6 +78,7 @@ function patchRequire(require, requireDir) { ...@@ -84,6 +78,7 @@ function patchRequire(require, requireDir) {
84 } else { 78 } else {
85 dir = fs.absolute(requireDir); 79 dir = fs.absolute(requireDir);
86 while (dir !== '' && dir.lastIndexOf(':') !== dir.length - 1) { 80 while (dir !== '' && dir.lastIndexOf(':') !== dir.length - 1) {
81 paths.push(fs.pathJoin(dir, 'modules', path));
87 // nodejs compatibility 82 // nodejs compatibility
88 paths.push(fs.pathJoin(dir, 'node_modules', path)); 83 paths.push(fs.pathJoin(dir, 'node_modules', path));
89 dir = fs.dirname(dir); 84 dir = fs.dirname(dir);
...@@ -91,6 +86,21 @@ function patchRequire(require, requireDir) { ...@@ -91,6 +86,21 @@ function patchRequire(require, requireDir) {
91 paths.push(fs.pathJoin(requireDir, 'lib', path)); 86 paths.push(fs.pathJoin(requireDir, 'lib', path));
92 paths.push(fs.pathJoin(requireDir, 'modules', path)); 87 paths.push(fs.pathJoin(requireDir, 'modules', path));
93 } 88 }
89 return paths;
90 }
91 var patchedRequire = function _require(path) {
92 var i, paths = [],
93 fileGuesses = [],
94 file,
95 module = {
96 exports: {}
97 };
98 if (phantomBuiltins.indexOf(path) !== -1) {
99 return phantomRequire(path);
100 }
101 requireDirs.forEach(function(requireDir) {
102 paths = paths.concat(possiblePaths(path, requireDir));
103 });
94 paths.forEach(function _forEach(testPath) { 104 paths.forEach(function _forEach(testPath) {
95 fileGuesses.push.apply(fileGuesses, [ 105 fileGuesses.push.apply(fileGuesses, [
96 testPath, 106 testPath,
...@@ -133,6 +143,8 @@ function patchRequire(require, requireDir) { ...@@ -133,6 +143,8 @@ function patchRequire(require, requireDir) {
133 requireCache[file] = module; 143 requireCache[file] = module;
134 return module.exports; 144 return module.exports;
135 }; 145 };
146 patchedRequire.patched = true;
147 return patchedRequire;
136 } 148 }
137 149
138 function bootstrap(global) { 150 function bootstrap(global) {
...@@ -243,9 +255,7 @@ function bootstrap(global) { ...@@ -243,9 +255,7 @@ function bootstrap(global) {
243 })(phantom.casperPath); 255 })(phantom.casperPath);
244 256
245 // patch require 257 // patch require
246 if (phantom.version.major === 1 && phantom.version.minor < 7) { 258 global.require = patchRequire(global.require, [phantom.casperPath, fs.workingDirectory]);
247 global.require = patchRequire(global.require, phantom.casperPath);
248 }
249 259
250 // casper cli args 260 // casper cli args
251 phantom.casperArgs = global.require('cli').parse(phantom.args); 261 phantom.casperArgs = global.require('cli').parse(phantom.args);
......
...@@ -836,7 +836,7 @@ Casper.prototype.injectClientUtils = function injectClientUtils() { ...@@ -836,7 +836,7 @@ Casper.prototype.injectClientUtils = function injectClientUtils() {
836 if (true === clientUtilsInjected) { 836 if (true === clientUtilsInjected) {
837 return; 837 return;
838 } 838 }
839 var clientUtilsPath = require('fs').pathJoin(phantom.casperPath, 'node_modules', 'clientutils.js'); 839 var clientUtilsPath = require('fs').pathJoin(phantom.casperPath, 'modules', 'clientutils.js');
840 if (true === this.page.injectJs(clientUtilsPath)) { 840 if (true === this.page.injectJs(clientUtilsPath)) {
841 this.log("Successfully injected Casper client-side utilities", "debug"); 841 this.log("Successfully injected Casper client-side utilities", "debug");
842 } else { 842 } else {
......