diff --git a/Cakefile b/Cakefile index 3bf7f0c1..a8446ed6 100644 --- a/Cakefile +++ b/Cakefile @@ -219,7 +219,7 @@ runTests = (CoffeeScript) -> # Run every test in the `test` folder, recording failures. files = fs.readdirSync 'test' - for file in files when file.match /\.(lit)?coffee$/i + for file in files when helpers.isCoffee file literate = helpers.isLiterate file currentFile = filename = path.join 'test', file code = fs.readFileSync filename diff --git a/lib/coffee-script/coffee-script.js b/lib/coffee-script/coffee-script.js index 637755b6..40807c11 100644 --- a/lib/coffee-script/coffee-script.js +++ b/lib/coffee-script/coffee-script.js @@ -185,6 +185,35 @@ ext = _ref[_i]; require.extensions[ext] = loadFile; } + (function(Module) { + var NATIVELOAD, findExtension; + NATIVELOAD = "function(filename){debug('load'+JSON.stringify(filename)+'formodule'+JSON.stringify(this.id));assert(!this.loaded);this.filename=filename;this.paths=Module._nodeModulePaths(path.dirname(filename));varextension=path.extname(filename)||'.js';if(!Module._extensions[extension])extension='.js';Module._extensions[extension](this,filename);this.loaded=true;}"; + if (Module.prototype.load.toString().replace(/\s+/g, '') !== NATIVELOAD) { + return; + } + findExtension = function(filename) { + var curExtension, extensions; + extensions = path.basename(filename).split('.'); + if (extensions[0] === '') { + extensions.shift(); + } + while (extensions.shift()) { + curExtension = '.' + extensions.join('.'); + if (Module._extensions[curExtension]) { + return curExtension; + } + } + return '.js'; + }; + return Module.prototype.load = function(filename) { + var extension; + this.filename = filename; + this.paths = Module._nodeModulePaths(path.dirname(filename)); + extension = findExtension(filename); + Module._extensions[extension](this, filename); + return this.loaded = true; + }; + })(require('module')); } if (child_process) { diff --git a/src/coffee-script.coffee b/src/coffee-script.coffee index 591a786e..be7e4ab5 100644 --- a/src/coffee-script.coffee +++ b/src/coffee-script.coffee @@ -154,6 +154,35 @@ if require.extensions for ext in ['.coffee', '.litcoffee', '.coffee.md'] require.extensions[ext] = loadFile + # Patch Node's module loader to be able to handle .coffee.md in require.extensions + do (Module = require 'module') -> + NATIVELOAD = "function(filename){debug('load'+JSON.stringify(filename)+'formodule'+JSON.stringify(this.id));assert(!this.loaded);this.filename=filename;this.paths=Module._nodeModulePaths(path.dirname(filename));varextension=path.extname(filename)||'.js';if(!Module._extensions[extension])extension='.js';Module._extensions[extension](this,filename);this.loaded=true;}" + + # Only keep going if we're sure module.prototype.load is what we expect + return unless Module::load.toString().replace(/\s+/g, '') is NATIVELOAD + + findExtension = (filename) -> + extensions = path.basename(filename).split '.' + + # Remove initial dot from dotfiles + extensions.shift() if extensions[0] is '' + + # Start with the longest extension and work our way shortwards + while extensions.shift() + curExtension = '.' + extensions.join '.' + return curExtension if Module._extensions[curExtension] + + '.js' + + Module::load = (filename) -> + @filename = filename + @paths = Module._nodeModulePaths path.dirname filename + + extension = findExtension filename + Module._extensions[extension](this, filename) + @loaded = true + + # If we're on Node, patch `child_process.fork` so that Coffee scripts are able # to fork both CoffeeScript files, and JavaScript files, directly. if child_process diff --git a/test/importing.coffee b/test/importing.coffee index 4bd8f40b..91d56d41 100644 --- a/test/importing.coffee +++ b/test/importing.coffee @@ -16,3 +16,19 @@ unless window? or testingBrowser? if require?.extensions? ok require(__filename).method() is magicValue delete global[magicKey] + + test "javascript modules can be imported", -> + magicVal = 1 + for module in 'test.js test2 .test2 test.extension.js test.unknownextension .coffee .coffee.md'.split ' ' + ok require("./importing/#{module}").value?() is magicVal, module + + test "coffeescript modules can be imported", -> + magicVal = 2 + for module in '.test.coffee test.coffee test.extension.coffee'.split ' ' + ok require("./importing/#{module}").value?() is magicVal, module + + test "literate coffeescript modules can be imported", -> + magicVal = 3 + # Leading space intentional to check for index.coffee.md + for module in ' .test.coffee.md test.coffee.md test.litcoffee test.extension.coffee.md'.split ' ' + ok require("./importing/#{module}").value?() is magicVal, module diff --git a/test/importing/.coffee b/test/importing/.coffee new file mode 100644 index 00000000..34f70d69 --- /dev/null +++ b/test/importing/.coffee @@ -0,0 +1,2 @@ +// Required by ../importing.coffee +module.exports = {value: function(){return 1;}}; diff --git a/test/importing/.coffee.md b/test/importing/.coffee.md new file mode 100644 index 00000000..34f70d69 --- /dev/null +++ b/test/importing/.coffee.md @@ -0,0 +1,2 @@ +// Required by ../importing.coffee +module.exports = {value: function(){return 1;}}; diff --git a/test/importing/.test.coffee b/test/importing/.test.coffee new file mode 100644 index 00000000..ff8ad831 --- /dev/null +++ b/test/importing/.test.coffee @@ -0,0 +1,2 @@ +# Required by ../importing.coffee +module.exports = {value: -> 2} diff --git a/test/importing/.test.coffee.md b/test/importing/.test.coffee.md new file mode 100644 index 00000000..99459eb3 --- /dev/null +++ b/test/importing/.test.coffee.md @@ -0,0 +1,3 @@ +Required by ../importing.coffee + + module.exports = {value: -> 3} diff --git a/test/importing/.test2 b/test/importing/.test2 new file mode 100644 index 00000000..34f70d69 --- /dev/null +++ b/test/importing/.test2 @@ -0,0 +1,2 @@ +// Required by ../importing.coffee +module.exports = {value: function(){return 1;}}; diff --git a/test/importing/index.coffee.md b/test/importing/index.coffee.md new file mode 100644 index 00000000..99459eb3 --- /dev/null +++ b/test/importing/index.coffee.md @@ -0,0 +1,3 @@ +Required by ../importing.coffee + + module.exports = {value: -> 3} diff --git a/test/importing/test.coffee.md b/test/importing/test.coffee.md new file mode 100644 index 00000000..99459eb3 --- /dev/null +++ b/test/importing/test.coffee.md @@ -0,0 +1,3 @@ +Required by ../importing.coffee + + module.exports = {value: -> 3} diff --git a/test/importing/test.extension.coffee b/test/importing/test.extension.coffee new file mode 100644 index 00000000..ff8ad831 --- /dev/null +++ b/test/importing/test.extension.coffee @@ -0,0 +1,2 @@ +# Required by ../importing.coffee +module.exports = {value: -> 2} diff --git a/test/importing/test.extension.coffee.md b/test/importing/test.extension.coffee.md new file mode 100644 index 00000000..99459eb3 --- /dev/null +++ b/test/importing/test.extension.coffee.md @@ -0,0 +1,3 @@ +Required by ../importing.coffee + + module.exports = {value: -> 3} diff --git a/test/importing/test.extension.js b/test/importing/test.extension.js new file mode 100644 index 00000000..34f70d69 --- /dev/null +++ b/test/importing/test.extension.js @@ -0,0 +1,2 @@ +// Required by ../importing.coffee +module.exports = {value: function(){return 1;}}; diff --git a/test/importing/test.js b/test/importing/test.js new file mode 100644 index 00000000..34f70d69 --- /dev/null +++ b/test/importing/test.js @@ -0,0 +1,2 @@ +// Required by ../importing.coffee +module.exports = {value: function(){return 1;}}; diff --git a/test/importing/test.unknownextension b/test/importing/test.unknownextension new file mode 100644 index 00000000..34f70d69 --- /dev/null +++ b/test/importing/test.unknownextension @@ -0,0 +1,2 @@ +// Required by ../importing.coffee +module.exports = {value: function(){return 1;}}; diff --git a/test/importing/test2 b/test/importing/test2 new file mode 100644 index 00000000..34f70d69 --- /dev/null +++ b/test/importing/test2 @@ -0,0 +1,2 @@ +// Required by ../importing.coffee +module.exports = {value: function(){return 1;}};