michaelficarra / commonjs-everywhere

:rainbow: minimal CommonJS browser bundler with aliasing, extensibility, and source maps
BSD 3-Clause "New" or "Revised" License
158 stars 21 forks source link

specify additional dependencies #42

Closed xcoderzach closed 11 years ago

xcoderzach commented 11 years ago

it would be awesome if I could specify a list of additional dependencies to bundle, so I could use dynamic requires. i.e.

cjsify "lib/index.coffee",  { additionalDependencies: "lib/models/*.coffee" }

and then I could do

require "./models/" + name + ".coffee"

If you think this is something worth adding I'll make a PR.

vendethiel commented 11 years ago

What about npm link lib/models ?

xcoderzach commented 11 years ago

does the library actually do npm lookups?

xcoderzach commented 11 years ago

to answer my own question, I looked through the source and it doesn't do any npm module lookups, and it wouldn't really solve the problem even if it did, because the dependency traverser still wouldn't find those modules, because there is no static require pointing to them.

vendethiel commented 11 years ago

Whatever is in node_modules/ is correctly required.

michaelficarra commented 11 years ago

@xcoderzach: Yes, require looks through node_modules directories according to the resolution algorithm.

edit: See this test: https://github.com/michaelficarra/commonjs-everywhere/blob/9917fc6153b8c5f50f0354314305c3f84b94247b/test/module-resolution-sync.coffee#L5-L8

michaelficarra commented 11 years ago

@xcoderzach: To address your initial proposal, I'd like to point out that I've received a similar request before. This person had a script that would glob a directory and include all of those files for their side effects. I believe they were test files. While this seemed at first like a perfectly reasonable case, I really wanted this tool to continue working only on a single entry file. It's the only kind of input that makes sense with the bundling model. And I decided that it really was the interface that made the most sense. So you have a few options.

Sorry if some of that was incoherent, it's difficult to make these points with just words. If you need clarification, I can give code examples.

xcoderzach commented 11 years ago

A few clarifications:

1) I'm not actually requiring modules for side effects, that was a poor example, it should be more like

Model = require("./models/" + modelName)

2) my use case is as follows:

I have a directory with backbone models at app/models, here's an example

class User extends BaseModel
  @one "post"

I have a library that takes this and creates an associated model when the response from the server is loaded.

The associated model (the user's post) will be constructed with the result of require("./models/post") which I dynamically require behind the scenes with Model = require("./models/" + modelName).

3) As to your third point, I could bundle everything that could be required at runtime by specifying a list of files or file globs, additionalDependencies, to "wrap", even though there aren't static references to to the files.

Every file that matched the glob would have to be included, and have it's dependencies traversed. Any dynamic requires would be ignored by the dep traverser, and we could assume that any dependency that you expect to require dynamically would be passed in as { additionalDependencies: "lib/models/*.coffee" }. Trying to require anything else in the browser should throw an exception.

tl;dr Everything that could be required at runtime should either be a statically required or listed in additionalDependencies.

It's late, so hopefully this makes sense :-S.

xcoderzach commented 11 years ago

After thinking about this, I think that dynamic requires are probably a code smell, and I'll actually do something like:

Post = require("./models/post")
class User extends BaseModel
  @one Post

Please disregard my previous comments.