Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

`coffee dir` executes every coffee file, vs `node dir` which executes `index.js` only. #2496

Closed
leeola opened this Issue · 14 comments

7 participants

@leeola

Well as the title says, if you run coffee directory CoffeeScript will "execute" every coffee file found within that directory, as if they were all called directly (coffee dir/foo.coffee, coffee dir/bar.coffee, etc). This is very different behavior from node directory which will look for, and only execute, an index.js file if found.

Is this a bug? Or working as intended?

Note that the work-around is not hard, simply execute the index file explicitly, such as: coffee directory/index.coffee, it just seems more logical that coffee dir and node dir should do the same things, as they do the same thing when used like coffee file and node file.

@leeola

For example, with the following files..

# example/index.coffee
if require.main is module
  console.log 'Index is the main file run! I was run directly by the user!'

exports.file1 = require './file1'
exports.file2 = require './file2'
exports.file3 = require './file3' 

# example/file1.coffee
if require.main is module
  console.log 'File1 is the main file run! I was run directly by the user!'

# example/file2.coffee
if require.main is module
  console.log 'File2 is the main file run! I was run directly by the user!'

# example/file3.coffee
if require.main is module
  console.log 'File3 is the main file run! I was run directly by the user!'

And the actual output for this is...

File1 is the main file run! I was run directly by the user!
Index is the main file run! I was run directly by the user!
File3 is the main file run! I was run directly by the user!
File2 is the main file run! I was run directly by the user!

Now, i would expect the output to simply be:

Index is the main file run! I was run directly by the user!

The reason for this is simply that interpreters such as Node and Python have the expected behavior to execute a directory by executing the index file only. Coffee, on the other hand, executes every file in the directory.

I would think this would be counterintuitive to many of the new Coffee users coming from Nodejs.

Not a huge issue either way.

@aseemk

I've wondered about this for a long time, too, and agree that unless there's a good reason for this (which there may be; just not aware of any), it'd be great for coffee foo to work just like node foo, even if foo is a directory.

The good news is that Node has the algorithm for this both documented and exposed:

http://nodejs.org/api/modules.html#modules_all_together
https://github.com/joyent/node/blob/v0.8.8/lib/module.js#L323 (Module._resolveFilename('foo'))

@mjadobson

Yeah, I was thrown by this a little while back when I started playing with coffee-script. Definitely would be nice if it worked the same as node.

@ghost

I would imagine it's in there for tests - you can have all your tests in separate files in a "test" directory, and run them all by doing

coffee test

Rather than having to write an index file that loads in and runs each test individually.

@vendethiel
Collaborator

You need helpers etc for test suites anyway, so I hardly see how that could be the case

@ghost

What do you mean? vows, for one, can run a file with tests in it straight through node or coffee.

@vendethiel
Collaborator

oh that's definitely nice

@jashkenas
Owner

Hrm... If we changed this, then the behavior of coffee dir would vastly differ from the behavior of coffee --compile dir. Is that acceptable? @michaelficarra, how have you solved this?

@michaelficarra
Collaborator

My CLI simply behaves as node's. The relevant issue is already linked above: michaelficarra/CoffeeScriptRedux#102

@ppvg

Calling coffee on a directory also seriously messes up the require chain:

  • sometimes (but not always!) a module will be its own parent
  • parent/child relationships between files in the directory are not reflected in the module objects (neither module.parent nor module.children)

Is there a reliable way to tell whether the process was started by calling coffee ./dir, as opposed to coffee ./dir/file.coffee?

@leeola

@PPvG require.main should be how it's done, imo. If coffee is set to execute, it is essentially node and should behave in the same manner.

Either way, this may be a none issue anymore, since Redux handles the issue properly.

@ppvg

@leeolayvar that's what I thought, but I don't think that's true. The result is identical when coffee is called on a directory, expect it seems to pick one of the directory's .coffee files at random to be require.main.

Since I'm writing a library, I can't depend on the users using either regular CS or CS Redux.

Edit:
I've ended up throwing an Error if there's any module with a cyclic dependency (where module.parent.filename equals module.filename). This happens most of the time (but not always), so at least I can warn the user that something's wrong.

@leeola

@PPvG No, i mean that in my opinion, require.main should be how it works in coffee, but currently does not. Redux supposedly fixes this though, so it may be a nonissue.

@aseemk

I noted this in #3292, but noting here too: it'd still be worth getting to full node parity by respecting the directory's package.json main field, if there is one. I believe require('module')._resolveFilename(path) gets you this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.