Fixes #3208. You now have to require 'coffee-script/extensions' in order to be able to auto-require CoffeeScript files.

This commit is contained in:
Jeremy Ashkenas 2013-10-20 11:08:13 -03:00
parent 581af4540a
commit b173a377a6
5 changed files with 138 additions and 119 deletions

View File

@ -161,6 +161,7 @@ task 'bench', 'quick benchmark of compilation time', ->
# Run the CoffeeScript test suite.
runTests = (CoffeeScript) ->
require './lib/coffee-script/extensions'
startTime = Date.now()
currentFile = null
passedTests = 0

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.3
(function() {
var Lexer, Module, SourceMap, binary, child_process, compile, compileFile, ext, fileExtensions, findExtension, fork, formatSourcePosition, fs, getSourceMap, helpers, lexer, loadFile, parser, path, sourceMaps, vm, withPrettyErrors, _i, _len,
var Lexer, SourceMap, compile, formatSourcePosition, fs, getSourceMap, helpers, lexer, parser, path, sourceMaps, vm, withPrettyErrors,
__hasProp = {}.hasOwnProperty,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
@ -10,8 +10,6 @@
path = require('path');
child_process = require('child_process');
Lexer = require('./lexer').Lexer;
parser = require('./parser').parser;
@ -22,7 +20,7 @@
exports.VERSION = '1.6.3';
fileExtensions = ['.coffee', '.litcoffee', '.coffee.md'];
exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md'];
exports.helpers = helpers;
@ -182,8 +180,11 @@
}
};
compileFile = function(filename, sourceMap) {
exports._compileFile = function(filename, sourceMap) {
var answer, err, raw, stripped;
if (sourceMap == null) {
sourceMap = false;
}
raw = fs.readFileSync(filename, 'utf8');
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
try {
@ -199,63 +200,6 @@
return answer;
};
loadFile = function(module, filename) {
var answer;
answer = compileFile(filename, false);
return module._compile(answer, filename);
};
if (require.extensions) {
for (_i = 0, _len = fileExtensions.length; _i < _len; _i++) {
ext = fileExtensions[_i];
require.extensions[ext] = loadFile;
}
Module = require('module');
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';
};
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;
};
}
if (child_process) {
fork = child_process.fork;
binary = require.resolve('../../bin/coffee');
child_process.fork = function(path, args, options) {
var execPath;
if (args == null) {
args = [];
}
if (options == null) {
options = {};
}
execPath = helpers.isCoffee(path) ? binary : null;
if (!Array.isArray(args)) {
args = [];
options = args || {};
}
options.execPath || (options.execPath = execPath);
return fork(path, args, options);
};
}
lexer = new Lexer;
parser.lexer = {
@ -343,10 +287,10 @@
if (sourceMaps[filename]) {
return sourceMaps[filename];
}
if (_ref = path != null ? path.extname(filename) : void 0, __indexOf.call(fileExtensions, _ref) < 0) {
if (_ref = path != null ? path.extname(filename) : void 0, __indexOf.call(exports.FILE_EXTENSIONS, _ref) < 0) {
return;
}
answer = compileFile(filename, true);
answer = exports._compileFile(filename, true);
return sourceMaps[filename] = answer.sourceMap;
};
@ -365,10 +309,10 @@
}
};
frames = (function() {
var _j, _len1, _results;
var _i, _len, _results;
_results = [];
for (_j = 0, _len1 = stack.length; _j < _len1; _j++) {
frame = stack[_j];
for (_i = 0, _len = stack.length; _i < _len; _i++) {
frame = stack[_i];
if (frame.getFunction() === exports.run) {
break;
}

View File

@ -0,0 +1,71 @@
// Generated by CoffeeScript 1.6.3
(function() {
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, helpers, loadFile, path, _i, _len, _ref;
CoffeeScript = require('./coffee-script');
child_process = require('child_process');
helpers = require('./helpers');
path = require('path');
loadFile = function(module, filename) {
var answer;
answer = CoffeeScript._compileFile(filename, false);
return module._compile(answer, filename);
};
if (require.extensions) {
_ref = CoffeeScript.FILE_EXTENSIONS;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
ext = _ref[_i];
require.extensions[ext] = loadFile;
}
Module = require('module');
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';
};
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;
};
}
if (child_process) {
fork = child_process.fork;
binary = require.resolve('../../bin/coffee');
child_process.fork = function(path, args, options) {
var execPath;
if (args == null) {
args = [];
}
if (options == null) {
options = {};
}
execPath = helpers.isCoffee(path) ? binary : null;
if (!Array.isArray(args)) {
args = [];
options = args || {};
}
options.execPath || (options.execPath = execPath);
return fork(path, args, options);
};
}
}).call(this);

View File

@ -6,7 +6,6 @@
fs = require 'fs'
vm = require 'vm'
path = require 'path'
child_process = require 'child_process'
{Lexer} = require './lexer'
{parser} = require './parser'
helpers = require './helpers'
@ -15,7 +14,7 @@ SourceMap = require './sourcemap'
# The current CoffeeScript version number.
exports.VERSION = '1.6.3'
fileExtensions = ['.coffee', '.litcoffee', '.coffee.md']
exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md']
# Expose helpers for testing.
exports.helpers = helpers
@ -152,7 +151,7 @@ exports.eval = (code, options = {}) ->
else
vm.runInContext js, sandbox
compileFile = (filename, sourceMap) ->
exports._compileFile = (filename, sourceMap = no) ->
raw = fs.readFileSync filename, 'utf8'
stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
@ -166,53 +165,6 @@ compileFile = (filename, sourceMap) ->
answer
# Load and run a CoffeeScript file for Node, stripping any `BOM`s.
loadFile = (module, filename) ->
answer = compileFile filename, false
module._compile answer, filename
# If the installed version of Node supports `require.extensions`, register
# CoffeeScript as an extension.
if require.extensions
for ext in fileExtensions
require.extensions[ext] = loadFile
# Patch Node's module loader to be able to handle mult-dot extensions.
# This is a horrible thing that should not be required. Perhaps, one day,
# when a truly benevolent dictator comes to rule over the Republik of Node,
# it won't be.
Module = require 'module'
findExtension = (filename) ->
extensions = path.basename(filename).split '.'
# Remove the initial dot from dotfiles.
extensions.shift() if extensions[0] is ''
# Start with the longest possible 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
{fork} = child_process
binary = require.resolve '../../bin/coffee'
child_process.fork = (path, args = [], options = {}) ->
execPath = if helpers.isCoffee(path) then binary else null
if not Array.isArray args
args = []
options = args or {}
options.execPath or= execPath
fork path, args, options
# Instantiate a Lexer for our use here.
lexer = new Lexer
@ -305,8 +257,8 @@ sourceMaps = {}
# Generates the source map for a coffee file and stores it in the local cache variable.
getSourceMap = (filename) ->
return sourceMaps[filename] if sourceMaps[filename]
return unless path?.extname(filename) in fileExtensions
answer = compileFile filename, true
return unless path?.extname(filename) in exports.FILE_EXTENSIONS
answer = exports._compileFile filename, true
sourceMaps[filename] = answer.sourceMap
# Based on [michaelficarra/CoffeeScriptRedux](http://goo.gl/ZTx1p)

51
src/extensions.coffee Normal file
View File

@ -0,0 +1,51 @@
CoffeeScript = require './coffee-script'
child_process = require 'child_process'
helpers = require './helpers'
path = require 'path'
# Load and run a CoffeeScript file for Node, stripping any `BOM`s.
loadFile = (module, filename) ->
answer = CoffeeScript._compileFile filename, false
module._compile answer, filename
# If the installed version of Node supports `require.extensions`, register
# CoffeeScript as an extension.
if require.extensions
for ext in CoffeeScript.FILE_EXTENSIONS
require.extensions[ext] = loadFile
# Patch Node's module loader to be able to handle mult-dot extensions.
# This is a horrible thing that should not be required. Perhaps, one day,
# when a truly benevolent dictator comes to rule over the Republik of Node,
# it won't be.
Module = require 'module'
findExtension = (filename) ->
extensions = path.basename(filename).split '.'
# Remove the initial dot from dotfiles.
extensions.shift() if extensions[0] is ''
# Start with the longest possible 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
{fork} = child_process
binary = require.resolve '../../bin/coffee'
child_process.fork = (path, args = [], options = {}) ->
execPath = if helpers.isCoffee(path) then binary else null
if not Array.isArray args
args = []
options = args or {}
options.execPath or= execPath
fork path, args, options