Skip to content
This repository

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

Closed
leeolayvar opened this Issue August 14, 2012 · 14 comments

8 participants

Lee Olayvar Aseem Kishore Sugarstack Michael Smith Nami-Doc Jeremy Ashkenas Michael Ficarra Peter-Paul van Gemerden
Lee Olayvar

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.

Lee Olayvar

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.

Aseem Kishore

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'))

Sugarstack

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.

Michael Ficarra michaelficarra referenced this issue in michaelficarra/CoffeeScriptRedux November 27, 2012
Closed

--input doesn’t accept a directory #102

Michael Smith

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.

Nami-Doc
Collaborator

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

Michael Smith

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

Nami-Doc
Collaborator

oh that's definitely nice

Jeremy Ashkenas
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?

Michael Ficarra
Collaborator

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

Peter-Paul van Gemerden
ppvg commented March 26, 2013

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?

Lee Olayvar

@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.

Peter-Paul van Gemerden
ppvg commented March 27, 2013

@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.

Lee Olayvar

@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.

Michael Ficarra michaelficarra closed this in #3292 December 29, 2013
Aseem Kishore

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.